From 2ffdce498155520c397cca40e7c3cdd4d8c77d25 Mon Sep 17 00:00:00 2001 From: Johnson Mao Date: Sun, 29 Oct 2023 16:24:08 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor=20architectur?= =?UTF-8?q?al=20and=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Footer => app/[lang]}/Footer.tsx | 2 +- .../Header => app/[lang]}/Header.tsx | 65 +++++----- .../Header => app/[lang]}/Menu.tsx | 37 +++--- src/app/[lang]/layout.tsx | 15 ++- src/app/[lang]/posts/[postId]/page.tsx | 2 +- src/app/layout.tsx | 2 +- src/app/not-found.tsx | 2 +- src/components/Container/Container.tsx | 3 +- src/components/Footer/footer.test.tsx | 15 --- src/components/Footer/index.tsx | 3 - src/components/Header/header.test.tsx | 112 ------------------ src/components/Header/index.tsx | 5 - src/components/Header/menu.test.tsx | 64 ---------- 13 files changed, 67 insertions(+), 260 deletions(-) rename src/{components/Footer => app/[lang]}/Footer.tsx (89%) rename src/{components/Header => app/[lang]}/Header.tsx (76%) rename src/{components/Header => app/[lang]}/Menu.tsx (55%) delete mode 100644 src/components/Footer/footer.test.tsx delete mode 100644 src/components/Footer/index.tsx delete mode 100644 src/components/Header/header.test.tsx delete mode 100644 src/components/Header/index.tsx delete mode 100644 src/components/Header/menu.test.tsx diff --git a/src/components/Footer/Footer.tsx b/src/app/[lang]/Footer.tsx similarity index 89% rename from src/components/Footer/Footer.tsx rename to src/app/[lang]/Footer.tsx index 432e92fa..828e1c50 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/app/[lang]/Footer.tsx @@ -1,4 +1,4 @@ -import Container from '../Container'; +import Container from '@/components/Container'; type FooterProps = { copyright: string; diff --git a/src/components/Header/Header.tsx b/src/app/[lang]/Header.tsx similarity index 76% rename from src/components/Header/Header.tsx rename to src/app/[lang]/Header.tsx index 279cd295..ad79bfe4 100644 --- a/src/components/Header/Header.tsx +++ b/src/app/[lang]/Header.tsx @@ -1,30 +1,21 @@ 'use client'; -import type { StaticImport } from 'next/dist/shared/lib/get-img-props'; import { CSSProperties, useCallback, useRef, useState } from 'react'; +import Container from '@/components/Container'; +import Image from '@/components/Image'; +import Link from '@/components/Link'; import useScroll, { ScrollHandler } from '@/hooks/useScroll'; import useRafState from '@/hooks/useRafState'; import cn from '@/utils/cn'; import { clamp, pipe, toFixedNumber } from '@/utils/math'; -import Container from '../Container'; -import Image from '../Image'; -import Link from '../Link'; -import ThemeSwitcher from '../ThemeSwitcher'; -import Menu, { MenuProps } from './Menu'; - -type Avatar = { - src: string | StaticImport; - alt: string; -}; - -export type HeaderProps = { - avatar: Avatar; +type HeaderProps = { + avatar: React.ReactNode; scrollThreshold?: number; -} & MenuProps; +} & React.PropsWithChildren; -function Header({ avatar, menu, scrollThreshold = 100 }: HeaderProps) { +function Header({ avatar, children, scrollThreshold = 100 }: HeaderProps) { const [avatarScale, setAvatarScale] = useRafState(0); const [willChange, setWillChange] = useState(true); const [avatarTranslateY, setAvatarTranslateY] = useState(0); @@ -98,33 +89,43 @@ function Header({ avatar, menu, scrollThreshold = 100 }: HeaderProps) { )} style={headerStyles} > - - + {children} - - {avatar.alt} - + {avatar} ); } +type AvatarProps = { + src: string; + alt: string; +}; + +export const Avatar = ({ src, alt }: AvatarProps) => { + return ( + + {alt} + + ); +}; + export default Header; diff --git a/src/components/Header/Menu.tsx b/src/app/[lang]/Menu.tsx similarity index 55% rename from src/components/Header/Menu.tsx rename to src/app/[lang]/Menu.tsx index f4de9eff..8d2598a7 100644 --- a/src/components/Header/Menu.tsx +++ b/src/app/[lang]/Menu.tsx @@ -2,11 +2,10 @@ import { usePathname } from 'next/navigation'; +import Link from '@/components/Link'; import cn from '@/utils/cn'; import getLocale from '@/utils/getLocale'; -import Link from '../Link'; - type MenuItem = { text: string; href: DynamicRoutesWithoutLocalePath; @@ -30,23 +29,23 @@ function Menu({ menu }: MenuProps) { }; return ( - + ); } diff --git a/src/app/[lang]/layout.tsx b/src/app/[lang]/layout.tsx index 27df9753..82f9c08d 100644 --- a/src/app/[lang]/layout.tsx +++ b/src/app/[lang]/layout.tsx @@ -1,8 +1,10 @@ import type { Metadata } from 'next'; import { avatarUrl, name, copyright, createMetadata } from '~/data/metadata'; import { Locale, getDictionary, locales } from '~/i18n'; -import Header, { HeaderProps } from '@/components/Header'; -import Footer from '@/components/Footer'; +import ThemeSwitcher from '@/components/ThemeSwitcher'; +import Header, { Avatar } from './Header'; +import Footer from './Footer'; +import Menu, { MenuProps } from './Menu'; export async function generateStaticParams() { return locales.map((lang) => ({ lang })); @@ -36,13 +38,13 @@ export async function generateMetadata({ async function I18nLayout({ children, params: { lang }, -}: React.PropsWithChildren & RootParams) { +}: RootParams & React.PropsWithChildren) { const { common } = await getDictionary(lang); const avatar = { src: avatarUrl, alt: name, }; - const menu: HeaderProps['menu'] = [ + const menu: MenuProps['menu'] = [ { text: common.home, href: '/', @@ -55,7 +57,10 @@ async function I18nLayout({ return ( <> -
+
}> + + +
{children}