From e9b00d572953de518f72eab22b545e718a194373 Mon Sep 17 00:00:00 2001 From: besscroft Date: Mon, 8 Apr 2024 15:02:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(default)/layout.tsx | 9 ++++- app/admin/layout.tsx | 23 ++++++----- components/Header.tsx | 16 +++----- components/Transitions.tsx | 80 ++++++++++++++++++++++++++++++++++++++ components/VaulDrawer.tsx | 62 +++++++++++++---------------- 5 files changed, 135 insertions(+), 55 deletions(-) create mode 100644 components/Transitions.tsx diff --git a/app/(default)/layout.tsx b/app/(default)/layout.tsx index 7b5d869..1208320 100644 --- a/app/(default)/layout.tsx +++ b/app/(default)/layout.tsx @@ -1,4 +1,5 @@ import Header from '~/components/Header' +import Transitions, { Animate } from '~/components/Transitions' export default async function DefaultLayout({ children, @@ -7,8 +8,12 @@ export default async function DefaultLayout({ }>) { return ( <> -
- {children} + +
+ + {children} + + ); } diff --git a/app/admin/layout.tsx b/app/admin/layout.tsx index 0966550..6510ccc 100644 --- a/app/admin/layout.tsx +++ b/app/admin/layout.tsx @@ -1,5 +1,6 @@ import DashHeader from '~/components/DashHeader' import { BaseSide } from '~/components/BaseSide' +import Transitions, { Animate } from '~/components/Transitions' export default function AdminLayout({ children, @@ -9,15 +10,19 @@ export default function AdminLayout({ return ( <>
- -
- -
- {children} -
-
+ + +
+ +
+ + {children} + +
+
+
); diff --git a/components/Header.tsx b/components/Header.tsx index 711925d..e822f7e 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -1,24 +1,20 @@ -'use client' - -import { Navbar, NavbarBrand, NavbarContent, NavbarItem, Link } from '@nextui-org/react' +import { Navbar, NavbarBrand, NavbarContent, NavbarItem } from '@nextui-org/react' import Logo from '~/components/Logo' import DynamicNavbar from '~/components/DynamicNavbar' -import { useRouter } from 'next-nprogress-bar' +import Link from 'next/link' export default function Header() { - const router = useRouter() - return ( - router.push('/')} className="cursor-pointer"> - 首页 + + 首页 - router.push('/about')} className="cursor-pointer"> - 关于 + + 关于 diff --git a/components/Transitions.tsx b/components/Transitions.tsx new file mode 100644 index 0000000..fcdb3b0 --- /dev/null +++ b/components/Transitions.tsx @@ -0,0 +1,80 @@ +'use client' + +import { AnimatePresence, motion } from 'framer-motion' +import { useRouter } from 'next-nprogress-bar' +import { + createContext, + MouseEventHandler, + PropsWithChildren, + use, + useTransition, +} from 'react' + +export const DELAY = 200; + +const sleep = (ms: number) => + new Promise((resolve) => setTimeout(() => resolve(), ms)); +const noop = () => {}; + +type TransitionContext = { + pending: boolean; + navigate: (url: string) => void; +}; +const Context = createContext({ + pending: false, + navigate: noop, +}); +export const usePageTransition = () => use(Context); + +type Props = PropsWithChildren<{ + className?: string; +}>; + +export default function Transitions({ children, className }: Props) { + const [pending, start] = useTransition(); + const router = useRouter(); + + const navigate = (href: string) => { + start(async () => { + router.push(href); + await sleep(DELAY); + }); + }; + + const onClick: MouseEventHandler = (e) => { + const a = (e.target as Element).closest("a"); + if (a) { + e.preventDefault(); + const href = a.getAttribute("href"); + if (href) { + navigate(href); + } + } + }; + + return ( + +
+ {children} +
+
+ ); +} + +export function Animate({ children, className }: Props) { + const { pending } = usePageTransition(); + return ( + + {!pending && ( + + {children} + + )} + + ); +} \ No newline at end of file diff --git a/components/VaulDrawer.tsx b/components/VaulDrawer.tsx index 54a4c50..3091e15 100644 --- a/components/VaulDrawer.tsx +++ b/components/VaulDrawer.tsx @@ -23,7 +23,6 @@ import { SunIcon } from '@radix-ui/react-icons' - export default function VaulDrawer() { const { data: session, status } = useSession() const router = useRouter() @@ -56,39 +55,34 @@ export default function VaulDrawer() { - { - pathname.startsWith('/admin') ? - pathname === '/admin' ? - } - onClick={() => router.push('/')} - > - - 首页 - - - : - } - onClick={() => router.push('/admin')} - > - - 控制台 - - - : - } - onClick={() => router.push('/admin')} - > - - 控制台 - - - } + } + onClick={() => router.push('/')} + > + + 首页 + + + } + onClick={() => router.push('/about')} + showDivider + > + + 关于 + + + } + onClick={() => router.push('/admin')} + > + + 控制台 + + }