refactor: enhance website configuration with comprehensive social and metadata options

- Expand `websiteConfig` to include detailed metadata and social media links
- Add optional social media platform URLs to improve website connectivity
- Update type definitions to support more flexible configuration
- Modify social links generation to conditionally render based on configuration
- Update references to website configuration across components and utilities
- Improve metadata generation with optional author information
This commit is contained in:
javayhu 2025-03-10 01:06:39 +08:00
parent 8b4dde9042
commit 031a05e549
6 changed files with 132 additions and 61 deletions

View File

@ -51,7 +51,7 @@ export default async function AboutPage() {
<div className="flex items-center gap-4">
<Button className="rounded-lg">
<MailIcon className="mr-1 size-4" />
<a href={`mailto:${websiteConfig.mail}`}>{t('talkWithMe')}</a>
<a href={`mailto:${websiteConfig.mail.from}`}>{t('talkWithMe')}</a>
</Button>
</div>
</div>

View File

@ -15,8 +15,8 @@ export function Footer({ className }: React.HTMLAttributes<HTMLElement>) {
const t = useTranslations();
const translator = createTranslator(t);
const footerLinks = getFooterLinks(translator);
const socialLinks = getSocialLinks();
const websiteInfo = getWebsiteInfo(translator);
const socialLinks = getSocialLinks();
return (
<footer className={cn('border-t', className)}>

View File

@ -35,8 +35,23 @@ import {
import { TranslationFunction } from './i18n/translator';
export const websiteConfig: WebsiteConfig = {
image: '/og.png',
mail: 'support@mksaas.com',
metadata: {
author: 'MkSaaS Team',
image: '/og.png',
},
mail: {
from: 'support@mksaas.com',
},
social: {
github: 'https://github.com/MkSaaSHQ',
twitter: 'https://twitter.com/mksaas',
blueSky: 'https://bsky.app/profile/mksaas.com',
youtube: 'https://www.youtube.com/@MkSaaSHQ',
linkedin: 'https://linkedin.com/company/mksaas',
facebook: 'https://facebook.com/mksaas',
instagram: 'https://instagram.com/mksaas',
tiktok: 'https://tiktok.com/@mksaas',
}
};
/**
@ -323,59 +338,6 @@ export function getFooterLinks(t: TranslationFunction): NestedMenuItem[] {
];
}
/**
* list all the social links here, you can delete the ones that are not needed
*/
export function getSocialLinks(): MenuItem[] {
return [
{
title: 'Email',
href: 'mailto:mksaas@gmail.com',
icon: <MailIcon className="size-4 shrink-0" />,
},
{
title: 'GitHub',
href: 'https://github.com/MkSaaSHQ',
icon: <GitHubIcon className="size-4 shrink-0" />,
},
{
title: 'Twitter',
href: 'https://twitter.com/mksaas',
icon: <TwitterIcon className="size-4 shrink-0" />,
},
{
title: 'Bluesky',
href: 'https://bsky.app/profile/mksaas.com',
icon: <BlueskyIcon className="size-4 shrink-0" />,
},
{
title: 'YouTube',
href: 'https://www.youtube.com/@MkSaaSHQ',
icon: <YouTubeIcon className="size-4 shrink-0" />,
},
{
title: 'LinkedIn',
href: 'https://www.linkedin.com/company/mksaas',
icon: <LinkedInIcon className="size-4 shrink-0" />,
},
{
title: 'Facebook',
href: 'https://www.facebook.com/mksaas',
icon: <FacebookIcon className="size-4 shrink-0" />,
},
{
title: 'Instagram',
href: 'https://www.instagram.com/mksaas',
icon: <InstagramIcon className="size-4 shrink-0" />,
},
{
title: 'TikTok',
href: 'https://www.tiktok.com/@mksaas',
icon: <TikTokIcon className="size-4 shrink-0" />,
},
];
}
/**
* Get avatar links with translations
* @param t - The translation function
@ -395,3 +357,85 @@ export function getAvatarLinks(t: TranslationFunction): MenuItem[] {
},
];
}
/**
* list all the social links here, you can delete the ones that are not needed
*/
export function getSocialLinks(): MenuItem[] {
const socialLinks: MenuItem[] = [];
// Only add social links that are configured in websiteConfig
if (websiteConfig.mail.from) {
socialLinks.push({
title: 'Email',
href: `mailto:${websiteConfig.mail.from}`,
icon: <MailIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.github) {
socialLinks.push({
title: 'GitHub',
href: websiteConfig.social.github,
icon: <GitHubIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.twitter) {
socialLinks.push({
title: 'Twitter',
href: websiteConfig.social.twitter,
icon: <TwitterIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.blueSky) {
socialLinks.push({
title: 'Bluesky',
href: websiteConfig.social.blueSky,
icon: <BlueskyIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.youtube) {
socialLinks.push({
title: 'YouTube',
href: websiteConfig.social.youtube,
icon: <YouTubeIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.linkedin) {
socialLinks.push({
title: 'LinkedIn',
href: websiteConfig.social.linkedin,
icon: <LinkedInIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.facebook) {
socialLinks.push({
title: 'Facebook',
href: websiteConfig.social.facebook,
icon: <FacebookIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.instagram) {
socialLinks.push({
title: 'Instagram',
href: websiteConfig.social.instagram,
icon: <InstagramIcon className="size-4 shrink-0" />,
});
}
if (websiteConfig.social.tiktok) {
socialLinks.push({
title: 'TikTok',
href: websiteConfig.social.tiktok,
icon: <TikTokIcon className="size-4 shrink-0" />,
});
}
return socialLinks;
}

View File

@ -27,7 +27,7 @@ export function constructMetadata({
title = title || websiteInfo.name;
description = description || websiteInfo.description;
image = image || websiteConfig.image;
image = image || websiteConfig.metadata.image;
const fullTitle = title ? `${title} - ${websiteInfo.title}` : websiteInfo.title;
const ogImageUrl = new URL(`${getBaseUrl()}${image}`);
@ -55,6 +55,7 @@ export function constructMetadata({
description,
images: [ogImageUrl.toString()],
site: getBaseUrl(),
creator: websiteConfig.metadata.author,
},
icons: {
icon: '/favicon.ico',

View File

@ -12,7 +12,7 @@ export const sendEmail: SendEmailHandler = async ({ to, subject, html }) => {
Authorization: `Bearer ${process.env.RESEND_API_KEY}`,
},
body: JSON.stringify({
from: websiteConfig.mail,
from: websiteConfig.mail.from,
to,
subject,
html,

30
src/types/index.d.ts vendored
View File

@ -4,12 +4,32 @@ import type { ReactNode } from 'react';
* website config, without translations
*/
export type WebsiteConfig = {
image: string;
mail: string;
metadata: {
author?: string;
image?: string;
};
mail: {
from?: string;
}
social: {
twitter?: string;
github?: string;
blueSky?: string;
youtube?: string;
linkedin?: string;
facebook?: string;
instagram?: string;
tiktok?: string;
};
};
/**
* website info, with translations
*
* name: the name of the website
* title: the title of the website, used in metadata
* tagline: the tagline of the website, used in footer
* description: the description of the website, used in metadata
*/
export type WebsiteInfo = {
name: string;
@ -20,6 +40,12 @@ export type WebsiteInfo = {
/**
* menu item
*
* title: the text to display
* description?: the description of the item
* icon?: the icon to display
* href?: the url to link to
* external?: whether the link is external
*/
export type MenuItem = {
title: string;