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`
This commit is contained in:
parent
4f5f216296
commit
c7ab08f01d
@ -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';
|
||||
|
@ -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<Metadata> {
|
||||
|
@ -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';
|
||||
|
@ -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}`,
|
||||
});
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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';
|
||||
|
||||
|
@ -20,7 +20,7 @@ export default function Error({ reset }: { reset: () => void }) {
|
||||
const router = useRouter();
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const t = useTranslations('ErrorPage');
|
||||
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col items-center justify-center gap-8">
|
||||
<Logo className="size-12" />
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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
|
1
src/constants.ts
Normal file
1
src/constants.ts
Normal file
@ -0,0 +1 @@
|
||||
export const POSTS_PER_PAGE = 6;
|
18
src/i18n/translator.ts
Normal file
18
src/i18n/translator.ts
Normal file
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export const POSTS_PER_PAGE = 6;
|
||||
|
||||
export const EMAIL_FROM = process.env.EMAIL_FROM;
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user