From 4d4b92b35758f68c24dc4323e71fd965ea748c74 Mon Sep 17 00:00:00 2001 From: xirf <55616872+xirf@users.noreply.github.com> Date: Sun, 7 Sep 2025 12:12:12 +0700 Subject: [PATCH] feat(landing): login register --- .claude/settings.local.json | 9 ++ .../(auth)/signin/_http/fetch-post-signin.ts | 1 + .../src/app/(public)/(home)/home/page.tsx | 14 +++ apps/landing/src/app/(public)/(home)/page.tsx | 14 --- .../src/app/(public)/_components/header.tsx | 100 ++++++++++++------ apps/landing/src/hooks/use-auth.ts | 28 +++++ 6 files changed, 120 insertions(+), 46 deletions(-) create mode 100644 .claude/settings.local.json create mode 100644 apps/landing/src/app/(public)/(home)/home/page.tsx delete mode 100644 apps/landing/src/app/(public)/(home)/page.tsx create mode 100644 apps/landing/src/hooks/use-auth.ts diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..a23fdfe --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,9 @@ +{ + "permissions": { + "allow": [ + "Bash(npm run typecheck:*)" + ], + "deny": [], + "ask": [] + } +} \ No newline at end of file diff --git a/apps/landing/src/app/(auth)/signin/_http/fetch-post-signin.ts b/apps/landing/src/app/(auth)/signin/_http/fetch-post-signin.ts index 52fbab2..9298101 100644 --- a/apps/landing/src/app/(auth)/signin/_http/fetch-post-signin.ts +++ b/apps/landing/src/app/(auth)/signin/_http/fetch-post-signin.ts @@ -22,3 +22,4 @@ export async function fetchPostSignin({ return data; } + diff --git a/apps/landing/src/app/(public)/(home)/home/page.tsx b/apps/landing/src/app/(public)/(home)/home/page.tsx new file mode 100644 index 0000000..ec0a397 --- /dev/null +++ b/apps/landing/src/app/(public)/(home)/home/page.tsx @@ -0,0 +1,14 @@ +import { CommunitySection } from '../_components/community-section'; +import { CTASection } from '../_components/cta-section'; +import { HeroSection } from '../_components/hero-section'; +import { TestimonialSection } from '../_components/testimonial-section'; +export default function Page() { + return ( + <> + + + + + > + ); +} diff --git a/apps/landing/src/app/(public)/(home)/page.tsx b/apps/landing/src/app/(public)/(home)/page.tsx deleted file mode 100644 index 535f374..0000000 --- a/apps/landing/src/app/(public)/(home)/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { CommunitySection } from './_components/community-section'; -import { CTASection } from './_components/cta-section'; -import { HeroSection } from './_components/hero-section'; -import { TestimonialSection } from './_components/testimonial-section'; -export default function Page() { - return ( - <> - - - - - > - ); -} diff --git a/apps/landing/src/app/(public)/_components/header.tsx b/apps/landing/src/app/(public)/_components/header.tsx index 63aae9a..3e5ef90 100644 --- a/apps/landing/src/app/(public)/_components/header.tsx +++ b/apps/landing/src/app/(public)/_components/header.tsx @@ -2,6 +2,7 @@ import { LogoSimple } from '@/app/_components/logo'; import NAVIGATIONS from '@/data/navigations.json'; +import { useAuth } from '@/hooks/use-auth'; import { Button } from '@components'; import { cn } from '@utils'; import { AnimatePresence, motion } from 'framer-motion'; @@ -13,6 +14,7 @@ import { LuMenu, LuX } from 'react-icons/lu'; export function Header() { const router = useRouter(); const pathname = usePathname(); + const { isAuthenticated } = useAuth(); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); useEffect(() => { @@ -30,6 +32,13 @@ export function Header() { setMobileMenuOpen(false); }, [pathname]); + const handleLogout = () => { + document.cookie = '__imphnen_access_token__=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; + document.cookie = '__imphnen_refresh_token__=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; + router.push('/'); + window.location.reload(); + }; + return ( @@ -62,19 +71,31 @@ export function Header() { - router.push('/signin')} - className="px-5 py-2 text-sm font-medium" - > - Masuk - - router.push('/signup')} - className="px-5 py-2 text-sm font-medium shadow-lg shadow-primary/20 hover:shadow-primary/30" - > - Daftar - + {isAuthenticated ? ( + + Keluar + + ) : ( + <> + router.push('/signin')} + className="px-5 py-2 text-sm font-medium" + > + Masuk + + router.push('/signup')} + className="px-5 py-2 text-sm font-medium shadow-lg shadow-primary/20 hover:shadow-primary/30" + > + Daftar + + > + )} - { - setMobileMenuOpen(false); - router.push('/signin'); - }} - className="w-full py-4 text-base" - > - Masuk - - { - setMobileMenuOpen(false); - router.push('/signup'); - }} - className="w-full py-4 text-base shadow-lg shadow-primary/20" - > - Daftar - + {isAuthenticated ? ( + { + setMobileMenuOpen(false); + handleLogout(); + }} + variant="bordered" + className="w-full py-4 text-base" + > + Keluar + + ) : ( + <> + { + setMobileMenuOpen(false); + router.push('/signin'); + }} + className="w-full py-4 text-base" + > + Masuk + + { + setMobileMenuOpen(false); + router.push('/signup'); + }} + className="w-full py-4 text-base shadow-lg shadow-primary/20" + > + Daftar + + > + )} )} diff --git a/apps/landing/src/hooks/use-auth.ts b/apps/landing/src/hooks/use-auth.ts new file mode 100644 index 0000000..38f7647 --- /dev/null +++ b/apps/landing/src/hooks/use-auth.ts @@ -0,0 +1,28 @@ +'use client'; + +import { useEffect, useState } from 'react'; + +export function useAuth() { + const [isAuthenticated, setIsAuthenticated] = useState(null); + const [cookie, setCookie] = useState(null) + + useEffect(() => { + const checkAuth = () => { + const accessToken = document.cookie + .split('; ') + .find(row => row.startsWith('__imphnen_access_token__=')) + ?.split('=')[1]; + + setIsAuthenticated(!!accessToken); + setCookie(accessToken || null) + }; + + checkAuth(); + }, []); + + function getToken (){ + if(isAuthenticated) return cookie + } + + return { isAuthenticated, getToken }; +}