feat(landing): login register

This commit is contained in:
xirf
2025-09-21 15:42:58 +07:00
parent 8e7c6e6c21
commit 4d4b92b357
6 changed files with 120 additions and 46 deletions
+9
View File
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(npm run typecheck:*)"
],
"deny": [],
"ask": []
}
}
@@ -22,3 +22,4 @@ export async function fetchPostSignin({
return data; return data;
} }
@@ -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 (
<>
<HeroSection />
<CommunitySection />
<TestimonialSection />
<CTASection />
</>
);
}
@@ -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 (
<>
<HeroSection />
<CommunitySection />
<TestimonialSection />
<CTASection />
</>
);
}
@@ -2,6 +2,7 @@
import { LogoSimple } from '@/app/_components/logo'; import { LogoSimple } from '@/app/_components/logo';
import NAVIGATIONS from '@/data/navigations.json'; import NAVIGATIONS from '@/data/navigations.json';
import { useAuth } from '@/hooks/use-auth';
import { Button } from '@components'; import { Button } from '@components';
import { cn } from '@utils'; import { cn } from '@utils';
import { AnimatePresence, motion } from 'framer-motion'; import { AnimatePresence, motion } from 'framer-motion';
@@ -13,6 +14,7 @@ import { LuMenu, LuX } from 'react-icons/lu';
export function Header() { export function Header() {
const router = useRouter(); const router = useRouter();
const pathname = usePathname(); const pathname = usePathname();
const { isAuthenticated } = useAuth();
const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
useEffect(() => { useEffect(() => {
@@ -30,6 +32,13 @@ export function Header() {
setMobileMenuOpen(false); setMobileMenuOpen(false);
}, [pathname]); }, [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 ( return (
<header className="sticky top-0 w-full z-50 bg-background/70"> <header className="sticky top-0 w-full z-50 bg-background/70">
<div className="container flex h-20 items-center justify-between"> <div className="container flex h-20 items-center justify-between">
@@ -62,19 +71,31 @@ export function Header() {
</nav> </nav>
<div className="hidden md:flex items-center gap-x-3"> <div className="hidden md:flex items-center gap-x-3">
<Button {isAuthenticated ? (
onClick={() => router.push('/signin')} <Button
className="px-5 py-2 text-sm font-medium" onClick={handleLogout}
> variant="bordered"
Masuk className="px-5 py-2 text-sm font-medium"
</Button> >
<Button Keluar
variant="bordered" </Button>
onClick={() => router.push('/signup')} ) : (
className="px-5 py-2 text-sm font-medium shadow-lg shadow-primary/20 hover:shadow-primary/30" <>
> <Button
Daftar onClick={() => router.push('/signin')}
</Button> className="px-5 py-2 text-sm font-medium"
>
Masuk
</Button>
<Button
variant="bordered"
onClick={() => router.push('/signup')}
className="px-5 py-2 text-sm font-medium shadow-lg shadow-primary/20 hover:shadow-primary/30"
>
Daftar
</Button>
</>
)}
</div> </div>
<button <button
@@ -144,25 +165,40 @@ export function Header() {
animate={{ y: 0, opacity: 1 }} animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.2 }} transition={{ delay: 0.2 }}
> >
<Button {isAuthenticated ? (
onClick={() => { <Button
setMobileMenuOpen(false); onClick={() => {
router.push('/signin'); setMobileMenuOpen(false);
}} handleLogout();
className="w-full py-4 text-base" }}
> variant="bordered"
Masuk className="w-full py-4 text-base"
</Button> >
<Button Keluar
variant="bordered" </Button>
onClick={() => { ) : (
setMobileMenuOpen(false); <>
router.push('/signup'); <Button
}} onClick={() => {
className="w-full py-4 text-base shadow-lg shadow-primary/20" setMobileMenuOpen(false);
> router.push('/signin');
Daftar }}
</Button> className="w-full py-4 text-base"
>
Masuk
</Button>
<Button
variant="bordered"
onClick={() => {
setMobileMenuOpen(false);
router.push('/signup');
}}
className="w-full py-4 text-base shadow-lg shadow-primary/20"
>
Daftar
</Button>
</>
)}
</motion.div> </motion.div>
</motion.div> </motion.div>
)} )}
+28
View File
@@ -0,0 +1,28 @@
'use client';
import { useEffect, useState } from 'react';
export function useAuth() {
const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null);
const [cookie, setCookie] = useState<string | null>(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 };
}