From c7ab08f01d6dcd570e5c4d23ea1584d11291cb88 Mon Sep 17 00:00:00 2001 From: javayhu Date: Sun, 9 Mar 2025 23:40:29 +0800 Subject: [PATCH] refactor: consolidate configuration and utility files - Move menu, footer, and social links to `config.tsx` - Create `constants.ts` for shared constants like `POSTS_PER_PAGE` - Extract translation utility to `translator.ts` - Move table of contents generation to `lib/blog/toc.ts` - Update import paths across multiple components - Simplify email configuration using `siteConfig` --- .../blog/(blog)/category/[slug]/page.tsx | 2 +- .../[locale]/(marketing)/blog/(blog)/page.tsx | 2 +- .../(marketing)/blog/[...slug]/page.tsx | 2 +- src/app/[locale]/auth/error/page.tsx | 2 +- src/components/blog/blog-grid.tsx | 2 +- src/components/blog/blog-toc.tsx | 2 +- src/components/error/error.tsx | 2 +- src/components/layout/footer.tsx | 6 +----- src/components/layout/navbar-mobile.tsx | 3 ++- src/components/layout/navbar.tsx | 3 ++- src/components/layout/user-button.tsx | 2 +- src/{config => }/config.tsx | 20 +------------------ src/constants.ts | 1 + src/i18n/translator.ts | 18 +++++++++++++++++ src/lib/{ => blog}/toc.ts | 0 src/lib/constants.ts | 3 --- src/lib/metadata.ts | 2 +- src/mail/emails/verify-email.tsx | 7 +------ src/mail/provider/resend.ts | 6 +++--- 19 files changed, 38 insertions(+), 47 deletions(-) rename src/{config => }/config.tsx (94%) create mode 100644 src/constants.ts create mode 100644 src/i18n/translator.ts rename src/lib/{ => blog}/toc.ts (100%) delete mode 100644 src/lib/constants.ts diff --git a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx b/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx index fe9d560..a9ce28f 100644 --- a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx +++ b/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx @@ -1,7 +1,7 @@ import BlogGrid from '@/components/blog/blog-grid'; import EmptyGrid from '@/components/shared/empty-grid'; import CustomPagination from '@/components/shared/pagination'; -import { POSTS_PER_PAGE } from '@/lib/constants'; +import { POSTS_PER_PAGE } from '@/constants'; import { allPosts, allCategories } from 'content-collections'; import { siteConfig } from '@/config/site'; import { constructMetadata } from '@/lib/metadata'; diff --git a/src/app/[locale]/(marketing)/blog/(blog)/page.tsx b/src/app/[locale]/(marketing)/blog/(blog)/page.tsx index 9c31a4c..02b7952 100644 --- a/src/app/[locale]/(marketing)/blog/(blog)/page.tsx +++ b/src/app/[locale]/(marketing)/blog/(blog)/page.tsx @@ -3,7 +3,7 @@ import { Metadata } from 'next'; import BlogGrid from '@/components/blog/blog-grid'; import EmptyGrid from '@/components/shared/empty-grid'; import CustomPagination from '@/components/shared/pagination'; -import { POSTS_PER_PAGE } from '@/lib/constants'; +import { POSTS_PER_PAGE } from '@/constants'; import { NextPageProps } from '@/types/next-page-props'; export async function generateMetadata(): Promise { diff --git a/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx b/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx index 09a35ec..f7e431c 100644 --- a/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx +++ b/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx @@ -2,7 +2,7 @@ import AllPostsButton from '@/components/blog/all-posts-button'; import { BlogToc } from '@/components/blog/blog-toc'; import { Mdx } from '@/components/shared/mdx-component'; import { LocaleLink } from '@/i18n/navigation'; -import { getTableOfContents } from '@/lib/toc'; +import { getTableOfContents } from '@/lib/blog/toc'; import { getBaseUrl } from '@/lib/urls/get-base-url'; import { estimateReadingTime, getLocaleDate } from '@/lib/utils'; import type { NextPageProps } from '@/types/next-page-props'; diff --git a/src/app/[locale]/auth/error/page.tsx b/src/app/[locale]/auth/error/page.tsx index 343055d..5e1dabf 100644 --- a/src/app/[locale]/auth/error/page.tsx +++ b/src/app/[locale]/auth/error/page.tsx @@ -5,7 +5,7 @@ import { Routes } from '@/routes'; export const metadata = constructMetadata({ title: 'Auth Error', - description: 'Auth Error', + description: 'Auth Error', canonicalUrl: `${getBaseUrl()}${Routes.AuthError}`, }); diff --git a/src/components/blog/blog-grid.tsx b/src/components/blog/blog-grid.tsx index 7d9ebfe..b7b7bd3 100644 --- a/src/components/blog/blog-grid.tsx +++ b/src/components/blog/blog-grid.tsx @@ -1,5 +1,5 @@ import BlogCard, { BlogCardSkeleton } from '@/components/blog/blog-card'; -import { POSTS_PER_PAGE } from '@/lib/constants'; +import { POSTS_PER_PAGE } from '@/constants'; import { Post } from 'content-collections'; interface BlogGridProps { diff --git a/src/components/blog/blog-toc.tsx b/src/components/blog/blog-toc.tsx index 4acf997..6f4a5a1 100644 --- a/src/components/blog/blog-toc.tsx +++ b/src/components/blog/blog-toc.tsx @@ -1,7 +1,7 @@ 'use client'; import { useMounted } from '@/hooks/use-mounted'; -import type { TableOfContents } from '@/lib/toc'; +import type { TableOfContents } from '@/lib/blog/toc'; import { cn } from '@/lib/utils'; import * as React from 'react'; diff --git a/src/components/error/error.tsx b/src/components/error/error.tsx index fc7e622..78eec9b 100644 --- a/src/components/error/error.tsx +++ b/src/components/error/error.tsx @@ -20,7 +20,7 @@ export default function Error({ reset }: { reset: () => void }) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const t = useTranslations('ErrorPage'); - + return (
diff --git a/src/components/layout/footer.tsx b/src/components/layout/footer.tsx index c77831a..d5e68e4 100644 --- a/src/components/layout/footer.tsx +++ b/src/components/layout/footer.tsx @@ -4,11 +4,7 @@ import Container from '@/components/container'; import { ThemeSwitcherHorizontal } from '@/components/layout/theme-switcher-horizontal'; import { Logo } from '@/components/logo'; import BuiltWithButton from '@/components/shared/built-with-button'; -import { - createTranslator, - getFooterLinks, - getSocialLinks, -} from '@/config/config'; +import { createTranslator, getFooterLinks, getSocialLinks } from '@/config'; import { siteConfig } from '@/config/site'; import { LocaleLink } from '@/i18n/navigation'; import { cn } from '@/lib/utils'; diff --git a/src/components/layout/navbar-mobile.tsx b/src/components/layout/navbar-mobile.tsx index 59b7b6a..ca5c410 100644 --- a/src/components/layout/navbar-mobile.tsx +++ b/src/components/layout/navbar-mobile.tsx @@ -9,7 +9,8 @@ import { CollapsibleContent, CollapsibleTrigger, } from '@/components/ui/collapsible'; -import { createTranslator, getMenuLinks } from '@/config/config'; +import { getMenuLinks } from '@/config'; +import { createTranslator } from '@/i18n/translator'; import { siteConfig } from '@/config/site'; import { LocaleLink, useLocalePathname } from '@/i18n/navigation'; import { authClient } from '@/lib/auth-client'; diff --git a/src/components/layout/navbar.tsx b/src/components/layout/navbar.tsx index 5c4464a..40e2325 100644 --- a/src/components/layout/navbar.tsx +++ b/src/components/layout/navbar.tsx @@ -17,7 +17,8 @@ import { NavigationMenuTrigger, navigationMenuTriggerStyle, } from '@/components/ui/navigation-menu'; -import { createTranslator, getMenuLinks } from '@/config/config'; +import { getMenuLinks } from '@/config'; +import { createTranslator } from '@/i18n/translator'; import { siteConfig } from '@/config/site'; import { useScroll } from '@/hooks/use-scroll'; import { LocaleLink, useLocalePathname } from '@/i18n/navigation'; diff --git a/src/components/layout/user-button.tsx b/src/components/layout/user-button.tsx index c568985..f0cccf2 100644 --- a/src/components/layout/user-button.tsx +++ b/src/components/layout/user-button.tsx @@ -17,7 +17,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; -import { createTranslator, getAvatarLinks } from '@/config/config'; +import { createTranslator, getAvatarLinks } from '@/config'; import { useMediaQuery } from '@/hooks/use-media-query'; import { LocaleLink, useLocaleRouter } from '@/i18n/navigation'; import { authClient } from '@/lib/auth-client'; diff --git a/src/config/config.tsx b/src/config.tsx similarity index 94% rename from src/config/config.tsx rename to src/config.tsx index cf3de83..3b40156 100644 --- a/src/config/config.tsx +++ b/src/config.tsx @@ -32,25 +32,7 @@ import { ThumbsUpIcon, WandSparklesIcon, } from 'lucide-react'; - -type TranslationFunction = (key: string, ...args: any[]) => string; - -/** - * Creates a translation function that works with our menu functions - * @param t - The next-intl translation function - * @returns A translation function that accepts string keys - */ -export function createTranslator(t: any): TranslationFunction { - return (key: string) => { - try { - // @ts-ignore - We know this is a valid key because we've defined it in our messages - return t(key); - } catch (error) { - console.error(`Translation key not found: ${key}`); - return key.split('.').pop() || key; - } - }; -} +import { TranslationFunction } from './i18n/translator'; /** * Get menu links with translations diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..86dd757 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1 @@ +export const POSTS_PER_PAGE = 6; diff --git a/src/i18n/translator.ts b/src/i18n/translator.ts new file mode 100644 index 0000000..9f0cdce --- /dev/null +++ b/src/i18n/translator.ts @@ -0,0 +1,18 @@ +export type TranslationFunction = (key: string, ...args: any[]) => string; + +/** + * Creates a translation function that works with our menu functions + * @param t - The next-intl translation function + * @returns A translation function that accepts string keys + */ +export function createTranslator(t: any): TranslationFunction { + return (key: string) => { + try { + // @ts-ignore - We know this is a valid key because we've defined it in our messages + return t(key); + } catch (error) { + console.error(`Translation key not found: ${key}`); + return key.split('.').pop() || key; + } + }; +} diff --git a/src/lib/toc.ts b/src/lib/blog/toc.ts similarity index 100% rename from src/lib/toc.ts rename to src/lib/blog/toc.ts diff --git a/src/lib/constants.ts b/src/lib/constants.ts deleted file mode 100644 index bf57b66..0000000 --- a/src/lib/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const POSTS_PER_PAGE = 6; - -export const EMAIL_FROM = process.env.EMAIL_FROM; diff --git a/src/lib/metadata.ts b/src/lib/metadata.ts index 15df666..9b00318 100644 --- a/src/lib/metadata.ts +++ b/src/lib/metadata.ts @@ -20,7 +20,7 @@ export function constructMetadata({ } = {}): Metadata { const fullTitle = title ? `${title} - ${siteConfig.title}` : siteConfig.title; const ogImageUrl = new URL(`${getBaseUrl()}/${image}`); - + return { title: fullTitle, description, diff --git a/src/mail/emails/verify-email.tsx b/src/mail/emails/verify-email.tsx index 9ef3c74..daf8e6f 100644 --- a/src/mail/emails/verify-email.tsx +++ b/src/mail/emails/verify-email.tsx @@ -11,12 +11,7 @@ type VerifyEmailProps = { name: string; } & BaseMailProps; -export function VerifyEmail({ - url, - name, - locale, - messages, -}: VerifyEmailProps) { +export function VerifyEmail({ url, name, locale, messages }: VerifyEmailProps) { const t = createTranslator({ locale, messages, diff --git a/src/mail/provider/resend.ts b/src/mail/provider/resend.ts index e6da039..f6c1072 100644 --- a/src/mail/provider/resend.ts +++ b/src/mail/provider/resend.ts @@ -1,6 +1,6 @@ -import { EMAIL_FROM } from '@/lib/constants'; -import { Resend } from 'resend'; +import { siteConfig } from '@/config/site'; import { SendEmailHandler } from '@/mail/types'; +import { Resend } from 'resend'; export const resend = new Resend(process.env.RESEND_API_KEY); @@ -12,7 +12,7 @@ export const sendEmail: SendEmailHandler = async ({ to, subject, html }) => { Authorization: `Bearer ${process.env.RESEND_API_KEY}`, }, body: JSON.stringify({ - from: EMAIL_FROM, + from: siteConfig.mail, to, subject, html,