refactor(types): centralize type definitions in shared types file
Move all interface and type definitions to src/types/index.ts to reduce code duplication and improve maintainability. This includes types for components, blog posts, personal info, and localization.
This commit is contained in:
@@ -1,19 +1,6 @@
|
||||
import type { Lang } from '../i18n/utils';
|
||||
import { type AuthorCardProps } from '@/types';
|
||||
import { personalInfo } from '@/lib/data';
|
||||
|
||||
interface AuthorCardProps {
|
||||
lang: Lang;
|
||||
author?: {
|
||||
name: string;
|
||||
bio?: string;
|
||||
avatar?: string;
|
||||
website?: string;
|
||||
twitter?: string;
|
||||
github?: string;
|
||||
linkedin?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default function AuthorCard({ lang, author }: AuthorCardProps) {
|
||||
// Default author info based on personalInfo
|
||||
const defaultAuthor = {
|
||||
|
||||
@@ -1,27 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useTranslations, type Lang } from '../i18n/utils';
|
||||
|
||||
/**
|
||||
* Blog post interface definition
|
||||
*/
|
||||
interface BlogPost {
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
slug: string;
|
||||
tags: string[];
|
||||
date: string;
|
||||
readTime: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Props interface for BlogList component
|
||||
*/
|
||||
interface BlogListProps {
|
||||
posts: BlogPost[];
|
||||
lang: Lang;
|
||||
baseUrl?: string; // Base URL for blog posts, defaults to '/blog/posts/'
|
||||
}
|
||||
import { useTranslations, type Lang } from '@/i18n/utils';
|
||||
import { type BlogPost, type BlogListProps } from '@/types';
|
||||
|
||||
/**
|
||||
* Reusable blog list component that displays blog posts in a grid layout
|
||||
|
||||
@@ -3,10 +3,7 @@ import { personalInfo } from "@/lib/data";
|
||||
import { motion } from "framer-motion";
|
||||
import { useState, useEffect } from "react";
|
||||
import { defaultLang } from "@/i18n/ui";
|
||||
|
||||
interface FooterProps {
|
||||
lang?: Lang;
|
||||
}
|
||||
import { type FooterProps } from "@/types";
|
||||
|
||||
export default function Footer({ lang: propLang }: FooterProps) {
|
||||
// 优先使用props传入的语言,如果没有则尝试从HTML lang属性获取
|
||||
|
||||
@@ -3,13 +3,12 @@ import LanguageSwitcher from "./LanguageSwitcher";
|
||||
import ThemeToggle from "./ui/theme-toggle";
|
||||
import { useTranslations, getLocalizedPath, type Lang } from "@/i18n/utils";
|
||||
import { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { Menu, X } from "lucide-react";
|
||||
import { defaultLang } from "@/i18n/ui";
|
||||
import { type GlassHeaderProps } from "@/types";
|
||||
|
||||
// 从window.document.documentElement.lang获取当前语言
|
||||
interface GlassHeaderProps {
|
||||
lang?: Lang;
|
||||
}
|
||||
|
||||
export default function GlassHeader({ lang: propLang }: GlassHeaderProps) {
|
||||
// 优先使用props传入的语言,如果没有则尝试从HTML lang属性获取
|
||||
|
||||
@@ -3,6 +3,7 @@ import { getLocalizedPath, type Lang } from "@/i18n/utils";
|
||||
import { languages as i18nLanguages, defaultLang } from "@/i18n/ui";
|
||||
import { Languages, Check, ChevronDown } from "lucide-react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { type LanguageSwitcherProps } from "@/types";
|
||||
|
||||
const availableLanguages = Object.entries(i18nLanguages).map(([code, name]) => ({
|
||||
code: code as Lang,
|
||||
@@ -11,10 +12,6 @@ const availableLanguages = Object.entries(i18nLanguages).map(([code, name]) => (
|
||||
icon: code === 'en' ? '🇬🇧' : code === 'zh' ? '🇨🇳' : '🌐'
|
||||
}));
|
||||
|
||||
interface LanguageSwitcherProps {
|
||||
lang?: Lang;
|
||||
}
|
||||
|
||||
export default function LanguageSwitcher({ lang: propLang }: LanguageSwitcherProps) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
// 获取当前语言,优先使用props传入的语言
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import type { Lang } from '../i18n/utils';
|
||||
|
||||
interface ShareButtonsProps {
|
||||
lang: Lang;
|
||||
title: string;
|
||||
url?: string;
|
||||
}
|
||||
import React, { useState } from 'react';
|
||||
import { type ShareButtonsProps } from '@/types';
|
||||
|
||||
export default function ShareButtons({ lang, title, url }: ShareButtonsProps) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
import { motion, useAnimation } from "framer-motion";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslations } from "@/i18n/utils";
|
||||
|
||||
/**
|
||||
* Skill item interface for the marquee component
|
||||
*/
|
||||
interface SkillItem {
|
||||
name: string;
|
||||
icon: string; // skillicons icon name
|
||||
}
|
||||
import { type SkillItem } from "@/types";
|
||||
|
||||
/**
|
||||
* All skills data with corresponding skillicons names
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import { type BlogPost as BaseBlogPost } from '@/types';
|
||||
|
||||
const currentPath = Astro.url.pathname;
|
||||
const isZh = currentPath.includes('/zh/');
|
||||
const lang = isZh ? 'zh' : 'en';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import type { Lang } from '../../i18n/utils';
|
||||
import { type Lang } from '@/types';
|
||||
|
||||
interface Props {
|
||||
lang: Lang;
|
||||
|
||||
Reference in New Issue
Block a user