diff --git a/src/app/(app)/(auth)/sign-in/page.tsx b/src/app/(app)/(auth)/sign-in/page.tsx index 3d9de2f..ab699c2 100644 --- a/src/app/(app)/(auth)/sign-in/page.tsx +++ b/src/app/(app)/(auth)/sign-in/page.tsx @@ -1,7 +1,16 @@ -import { SignInView } from "@/modules/auth/ui/views/sign-in-view"; +import { redirect } from 'next/navigation'; -const Page = () => { - return -} +import { caller } from '@/trpc/server'; +import { SignInView } from '@/modules/auth/ui/views/sign-in-view'; + +const Page = async () => { + const session = await caller.auth.session(); + + if (session.user) { + redirect('/'); + } + + return ; +}; export default Page; diff --git a/src/app/(app)/(auth)/sign-up/page.tsx b/src/app/(app)/(auth)/sign-up/page.tsx index 08a2016..72b7029 100644 --- a/src/app/(app)/(auth)/sign-up/page.tsx +++ b/src/app/(app)/(auth)/sign-up/page.tsx @@ -1,7 +1,16 @@ -import { SignUpView } from "@/modules/auth/ui/views/sign-up-view"; +import { redirect } from 'next/navigation'; -const Page = () => { - return -} +import { caller } from '@/trpc/server'; +import { SignUpView } from '@/modules/auth/ui/views/sign-up-view'; + +const Page = async () => { + const session = await caller.auth.session(); + + if (session.user) { + redirect('/'); + } + + return ; +}; export default Page; diff --git a/src/app/(app)/(home)/navbar.tsx b/src/app/(app)/(home)/navbar.tsx index 77e34e5..0ac73eb 100644 --- a/src/app/(app)/(home)/navbar.tsx +++ b/src/app/(app)/(home)/navbar.tsx @@ -5,9 +5,11 @@ import Link from 'next/link'; import { Poppins } from 'next/font/google'; import { MenuIcon } from 'lucide-react'; import { usePathname } from 'next/navigation'; +import { useQuery } from '@tanstack/react-query'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; +import { useTRPC } from '@/trpc/client'; import NavbarSidebar from './navbar-sidebar'; @@ -64,9 +66,12 @@ const Navbar = () => { const pathname = usePathname(); const [isSidebarOpen, setIsSidebarOpen] = useState(false); - return ( - + ); }; export default Navbar; diff --git a/src/app/(app)/(home)/search-filters/search-input.tsx b/src/app/(app)/(home)/search-filters/search-input.tsx index 1e36188..11f6c33 100644 --- a/src/app/(app)/(home)/search-filters/search-input.tsx +++ b/src/app/(app)/(home)/search-filters/search-input.tsx @@ -1,10 +1,13 @@ 'use client'; import { useState } from 'react'; -import { ListFilterIcon, SearchIcon } from 'lucide-react'; +import Link from 'next/link'; +import { useQuery } from '@tanstack/react-query'; +import { BookmarkCheckIcon, ListFilterIcon, SearchIcon } from 'lucide-react'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; +import { useTRPC } from '@/trpc/client'; import CategoriesSidebar from './categories-sidebar'; @@ -15,6 +18,9 @@ interface SearchInputProps { const SearchInput = ({ disabled }: SearchInputProps) => { const [isSidebarOpen, setIsSidebarOpen] = useState(false); + const trpc = useTRPC(); + const session = useQuery(trpc.auth.session.queryOptions()); + return (
@@ -40,6 +46,15 @@ const SearchInput = ({ disabled }: SearchInputProps) => { > + + {session.data?.user && ( + + )}
); diff --git a/src/modules/auth/constants.ts b/src/modules/auth/constants.ts deleted file mode 100644 index 32e1c5f..0000000 --- a/src/modules/auth/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const AUTH_COOKIE = 'payload-token'; \ No newline at end of file diff --git a/src/modules/auth/server/procedures.ts b/src/modules/auth/server/procedures.ts index 284d8c8..6be13cf 100644 --- a/src/modules/auth/server/procedures.ts +++ b/src/modules/auth/server/procedures.ts @@ -1,21 +1,17 @@ -import { headers as getHeaders, cookies as getCookies } from "next/headers"; +import { headers as getHeaders } from "next/headers"; import { TRPCError } from "@trpc/server"; -import { AUTH_COOKIE } from "@/modules/auth/constants"; import { loginSchema, registerSchema } from "@/modules/auth/schemas"; import { baseProcedure, createTRPCRouter } from "@/trpc/init"; +import { generateAuthCookie } from "../utils"; + export const authRouter = createTRPCRouter({ session: baseProcedure.query(async ({ ctx }) => { const headers = await getHeaders(); return await ctx.db.auth({ headers }); }), - logout: baseProcedure.mutation((async () => { - const cookies = await getCookies(); - - cookies.delete(AUTH_COOKIE); - })), register: baseProcedure .input( registerSchema @@ -62,13 +58,10 @@ export const authRouter = createTRPCRouter({ }) } - const cookies = await getCookies(); - cookies.set({ - name: AUTH_COOKIE, + await generateAuthCookie({ + prefix: ctx.db.config.cookiePrefix, value: data.token, - httpOnly: true, - path: '/', - }); + }) }), login: baseProcedure .input(loginSchema) @@ -88,13 +81,10 @@ export const authRouter = createTRPCRouter({ }) } - const cookies = await getCookies(); - cookies.set({ - name: AUTH_COOKIE, + await generateAuthCookie({ + prefix: ctx.db.config.cookiePrefix, value: data.token, - httpOnly: true, - path: '/', - }); + }) return data; }) diff --git a/src/modules/auth/ui/views/sign-in-view.tsx b/src/modules/auth/ui/views/sign-in-view.tsx index 2a411e7..eed7df4 100644 --- a/src/modules/auth/ui/views/sign-in-view.tsx +++ b/src/modules/auth/ui/views/sign-in-view.tsx @@ -1,18 +1,19 @@ 'use client'; +import { toast } from "sonner"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { useForm } from "react-hook-form"; +import { Poppins } from "next/font/google"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { zodResolver } from "@hookform/resolvers/zod"; + +import { useTRPC } from "@/trpc/client"; import { Button } from "@/components/ui/button"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { cn } from "@/lib/utils"; import { LoginSchema, loginSchema } from "@/modules/auth/schemas"; -import { useTRPC } from "@/trpc/client"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useMutation } from "@tanstack/react-query"; -import { Poppins } from "next/font/google"; -import Link from "next/link"; -import { useRouter } from "next/navigation"; -import { useForm } from "react-hook-form"; -import { toast } from "sonner"; const poppins = Poppins({ subsets: ['latin'], @@ -22,11 +23,13 @@ const poppins = Poppins({ export const SignInView = () => { const router = useRouter(); const trpc = useTRPC(); + const queryClient = useQueryClient(); const login = useMutation(trpc.auth.login.mutationOptions({ onError: (error) => { toast.error(error.message) }, - onSuccess: () => { + onSuccess: async () => { + await queryClient.invalidateQueries(trpc.auth.session.queryFilter()) router.push('/'); } })); diff --git a/src/modules/auth/utils.ts b/src/modules/auth/utils.ts new file mode 100644 index 0000000..90e43a6 --- /dev/null +++ b/src/modules/auth/utils.ts @@ -0,0 +1,17 @@ +import { cookies as getCookies } from "next/headers"; + +interface Props { + prefix: string; + value: string; +} + +export const generateAuthCookie = async ({prefix, value}: Props) => { + const cookies = await getCookies(); + + cookies.set({ + name: `${prefix}-token`, + value, + httpOnly: true, + path: '/', + }) +} \ No newline at end of file diff --git a/src/payload.config.ts b/src/payload.config.ts index 1487641..ccf3adf 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -21,6 +21,7 @@ export default buildConfig({ baseDir: path.resolve(dirname), }, }, + cookiePrefix: 'funroad', collections: [Users, Media, Categories], editor: lexicalEditor(), secret: process.env.PAYLOAD_SECRET || '', diff --git a/src/trpc/server.tsx b/src/trpc/server.tsx index 33d124e..ea68544 100644 --- a/src/trpc/server.tsx +++ b/src/trpc/server.tsx @@ -11,4 +11,5 @@ export const trpc = createTRPCOptionsProxy({ ctx: createTRPCContext, router: appRouter, queryClient: getQueryClient, -}); \ No newline at end of file +}); +export const caller = appRouter.createCaller(createTRPCContext); \ No newline at end of file