This commit is contained in:
giancarlo
2024-03-24 02:23:22 +08:00
parent 648d77b430
commit bce3479368
589 changed files with 37067 additions and 9596 deletions

View File

@@ -0,0 +1,7 @@
export function GridList({ children }: React.PropsWithChildren) {
return (
<div className="mb-16 grid grid-cols-1 gap-y-8 md:grid-cols-2 md:gap-x-8 md:gap-y-12 lg:grid-cols-3 lg:gap-x-12">
{children}
</div>
);
}

View File

@@ -0,0 +1,132 @@
import Link from 'next/link';
import { AppLogo } from '~/components/app-logo';
import appConfig from '~/config/app.config';
const YEAR = new Date().getFullYear();
export function SiteFooter() {
return (
<footer className={'py-8 lg:py-24'}>
<div className={'container mx-auto'}>
<div className={'flex flex-col space-y-8 lg:flex-row lg:space-y-0'}>
<div
className={
'flex w-full space-x-2 lg:w-4/12 xl:w-3/12' +
' xl:space-x-6 2xl:space-x-8'
}
>
<div className={'flex flex-col space-y-4'}>
<div>
<AppLogo className={'w-[85px] md:w-[115px]'} />
</div>
<div>
<p className={'text-sm text-gray-500 dark:text-gray-400'}>
Add a short tagline about your product
</p>
</div>
<div className={'flex text-xs text-gray-500 dark:text-gray-400'}>
<p>
© Copyright {YEAR} {appConfig.name}. All Rights Reserved.
</p>
</div>
</div>
</div>
<div
className={
'flex flex-col space-y-8 lg:space-x-6 lg:space-y-0' +
' xl:space-x-16 2xl:space-x-20' +
' w-full lg:flex-row lg:justify-end'
}
>
<div>
<div className={'flex flex-col space-y-4'}>
<FooterSectionHeading>About</FooterSectionHeading>
<FooterSectionList>
<FooterLink>
<Link href={'#'}>Who we are</Link>
</FooterLink>
<FooterLink>
<Link href={'/blog'}>Blog</Link>
</FooterLink>
<FooterLink>
<Link href={'/contact'}>Contact</Link>
</FooterLink>
</FooterSectionList>
</div>
</div>
<div>
<div className={'flex flex-col space-y-4'}>
<FooterSectionHeading>Product</FooterSectionHeading>
<FooterSectionList>
<FooterLink>
<Link href={'/docs'}>Documentation</Link>
</FooterLink>
<FooterLink>
<Link href={'#'}>Help Center</Link>
</FooterLink>
<FooterLink>
<Link href={'#'}>Changelog</Link>
</FooterLink>
</FooterSectionList>
</div>
</div>
<div>
<div className={'flex flex-col space-y-4'}>
<FooterSectionHeading>Legal</FooterSectionHeading>
<FooterSectionList>
<FooterLink>
<Link href={'#'}>Terms of Service</Link>
</FooterLink>
<FooterLink>
<Link href={'#'}>Privacy Policy</Link>
</FooterLink>
<FooterLink>
<Link href={'#'}>Cookie Policy</Link>
</FooterLink>
</FooterSectionList>
</div>
</div>
</div>
</div>
</div>
</footer>
);
}
function FooterSectionHeading(props: React.PropsWithChildren) {
return (
<p>
<span className={'font-semibold'}>{props.children}</span>
</p>
);
}
function FooterSectionList(props: React.PropsWithChildren) {
return (
<ul className={'flex flex-col space-y-4 text-gray-500 dark:text-gray-400'}>
{props.children}
</ul>
);
}
function FooterLink(props: React.PropsWithChildren) {
return (
<li
className={
'text-sm [&>a]:transition-colors [&>a]:hover:text-gray-800' +
' dark:[&>a]:hover:text-white'
}
>
{props.children}
</li>
);
}

View File

@@ -0,0 +1,47 @@
'use client';
import Link from 'next/link';
import { ChevronRightIcon } from 'lucide-react';
import pathsConfig from '~/config/paths.config';
import { PersonalAccountDropdown } from '@kit/accounts/personal-account-dropdown';
import { useSignOut } from '@kit/supabase/hooks/use-sign-out';
import { useUserSession } from '@kit/supabase/hooks/use-user-session';
import { Button } from '@kit/ui/button';
export function SiteHeaderAccountSection() {
const signOut = useSignOut();
const userSession = useUserSession();
if (userSession.data) {
return (
<PersonalAccountDropdown
session={userSession.data}
paths={{
home: pathsConfig.app.home,
}}
signOutRequested={() => signOut.mutateAsync()}
/>
);
}
return <AuthButtons />;
}
function AuthButtons() {
return (
<div className={'hidden space-x-2 lg:flex'}>
<Button variant={'link'}>
<Link href={pathsConfig.auth.signIn}>Sign In</Link>
</Button>
<Link href={pathsConfig.auth.signUp}>
<Button className={'rounded-full'}>
Sign Up
<ChevronRightIcon className={'h-4'} />
</Button>
</Link>
</div>
);
}

View File

@@ -0,0 +1,29 @@
import { SiteHeaderAccountSection } from '~/(marketing)/components/site-header-account-section';
import { SiteNavigation } from '~/(marketing)/components/site-navigation';
import { AppLogo } from '~/components/app-logo';
export function SiteHeader() {
return (
<div className={'container mx-auto'}>
<div className="flex h-16 items-center justify-between">
<div className={'w-4/12'}>
<AppLogo />
</div>
<div className={'hidden w-4/12 justify-center lg:flex'}>
<SiteNavigation />
</div>
<div className={'flex flex-1 items-center justify-end space-x-4'}>
<div className={'flex items-center'}></div>
<SiteHeaderAccountSection />
<div className={'flex lg:hidden'}>
<SiteNavigation />
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,102 @@
import Link from 'next/link';
import { MenuIcon } from 'lucide-react';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@kit/ui/dropdown-menu';
import {
NavigationMenu,
NavigationMenuItem,
NavigationMenuList,
} from '@kit/ui/navigation-menu';
const links = {
SignIn: {
label: 'Sign In',
path: '/auth/sign-in',
},
Blog: {
label: 'Blog',
path: '/blog',
},
Docs: {
label: 'Documentation',
path: '/docs',
},
Pricing: {
label: 'Pricing',
path: '/pricing',
},
FAQ: {
label: 'FAQ',
path: '/faq',
},
};
export function SiteNavigation() {
const className = `hover:underline text-sm`;
return (
<>
<div className={'hidden items-center lg:flex'}>
<NavigationMenu>
<NavigationMenuList className={'space-x-2.5'}>
<NavigationMenuItem>
<Link className={className} href={links.Blog.path}>
{links.Blog.label}
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<Link className={className} href={links.Docs.path}>
{links.Docs.label}
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<Link className={className} href={links.Pricing.path}>
{links.Pricing.label}
</Link>
</NavigationMenuItem>
<NavigationMenuItem>
<Link className={className} href={links.FAQ.path}>
{links.FAQ.label}
</Link>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
</div>
<div className={'flex items-center lg:hidden'}>
<MobileDropdown />
</div>
</>
);
}
function MobileDropdown() {
return (
<DropdownMenu>
<DropdownMenuTrigger aria-label={'Open Menu'}>
<MenuIcon className={'h-9'} />
</DropdownMenuTrigger>
<DropdownMenuContent>
{Object.values(links).map((item) => {
const className = 'flex w-full h-full items-center';
return (
<DropdownMenuItem key={item.path}>
<Link className={className} href={item.path}>
{item.label}
</Link>
</DropdownMenuItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
);
}

View File

@@ -0,0 +1,20 @@
import { Heading } from '@kit/ui/heading';
import { cn } from '@kit/ui/utils';
export function SitePageHeader(props: {
title: string;
subtitle: string;
className?: string;
}) {
return (
<div
className={cn('flex flex-col items-center space-y-2.5', props.className)}
>
<Heading level={1}>{props.title}</Heading>
<Heading level={2} className={'text-muted-foreground'}>
<span className={'font-normal'}>{props.subtitle}</span>
</Heading>
</div>
);
}