refactor: clean up codebase by removing redundant comments
Remove unnecessary JSDoc comments and redundant explanations from components, types, and data files. Simplify code structure while maintaining functionality. Clean up language handling logic in components by removing redundant comments and simplifying state management. Move type imports to dedicated type import statements where applicable.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useTranslations, type Lang } from "@/i18n/utils";
|
||||
import { useTranslations } from "@/i18n/utils";
|
||||
import type { Lang } from "@/types/i18n";
|
||||
import { personalInfo } from "@/lib/data";
|
||||
import { motion } from "framer-motion";
|
||||
import { useState, useEffect } from "react";
|
||||
@@ -7,11 +8,9 @@ import Container from "./ui/Container";
|
||||
import { type FooterProps } from "@/types";
|
||||
|
||||
export default function Footer({ lang: propLang }: FooterProps) {
|
||||
// 优先使用props传入的语言,如果没有则尝试从HTML lang属性获取
|
||||
const [lang, setLang] = useState<Lang>(propLang || defaultLang);
|
||||
|
||||
useEffect(() => {
|
||||
// 在客户端运行时,从HTML lang属性获取当前语言
|
||||
const htmlLang = document.documentElement.lang as Lang;
|
||||
if (htmlLang && (!propLang || htmlLang !== lang)) {
|
||||
setLang(htmlLang);
|
||||
|
||||
@@ -2,21 +2,17 @@ import { personalInfo } from "@/lib/data";
|
||||
import LanguageSwitcher from "./LanguageSwitcher";
|
||||
import ThemeToggle from "./ui/theme-toggle";
|
||||
import Container from "./ui/Container";
|
||||
import { useTranslations, getLocalizedPath, type Lang } from "@/i18n/utils";
|
||||
import { useTranslations, getLocalizedPath } from "@/i18n/utils";
|
||||
import type { Lang } from "@/types/i18n";
|
||||
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获取当前语言
|
||||
|
||||
export default function GlassHeader({ lang: propLang }: GlassHeaderProps) {
|
||||
// 优先使用props传入的语言,如果没有则尝试从HTML lang属性获取
|
||||
const [lang, setLang] = useState<Lang>(propLang || defaultLang);
|
||||
|
||||
useEffect(() => {
|
||||
// 在客户端运行时,从HTML lang属性获取当前语言
|
||||
const htmlLang = document.documentElement.lang as Lang;
|
||||
if (htmlLang && (!propLang || htmlLang !== lang)) {
|
||||
setLang(htmlLang);
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { getLocalizedPath, type Lang } from "@/i18n/utils";
|
||||
import { getLocalizedPath } from "@/i18n/utils";
|
||||
import type { Lang } from "@/types/i18n";
|
||||
import { languages as i18nLanguages, defaultLang } from "@/i18n/ui";
|
||||
import { Languages, Check, ChevronDown } from "lucide-react";
|
||||
import { 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,
|
||||
name,
|
||||
// 语言图标映射
|
||||
icon: code === 'en' ? '🇬🇧' : code === 'zh' ? '🇨🇳' : '🌐'
|
||||
}));
|
||||
|
||||
export default function LanguageSwitcher({ lang: propLang }: LanguageSwitcherProps) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
// 获取当前语言,优先使用props传入的语言
|
||||
const [currentLang, setCurrentLang] = useState<Lang>(propLang || defaultLang);
|
||||
|
||||
// 在客户端运行时,从HTML lang属性获取当前语言
|
||||
useEffect(() => {
|
||||
if (typeof document !== 'undefined') {
|
||||
const htmlLang = document.documentElement.lang as Lang;
|
||||
@@ -50,39 +48,28 @@ export default function LanguageSwitcher({ lang: propLang }: LanguageSwitcherPro
|
||||
const currentPathParts = currentPathname.split('/').filter(p => p);
|
||||
let basePath = '';
|
||||
|
||||
// Check if the first part of the path is a known language code
|
||||
if (currentPathParts.length > 0 && Object.keys(i18nLanguages).includes(currentPathParts[0])) {
|
||||
// If the first part is a language code, remove it to get the base path
|
||||
basePath = '/' + currentPathParts.slice(1).join('/');
|
||||
} else {
|
||||
// If no language code in path, use the current path as base
|
||||
basePath = currentPathname;
|
||||
}
|
||||
|
||||
// Ensure basePath always starts with a slash, or is just a slash for the root
|
||||
if (!basePath.startsWith('/')) {
|
||||
basePath = '/' + basePath;
|
||||
}
|
||||
// Fix for empty paths
|
||||
if (basePath === '//') basePath = '/';
|
||||
if (basePath === '') basePath = '/';
|
||||
|
||||
let newPath;
|
||||
// If the target language is the default language and prefixDefaultLocale is false (as per our astro.config.mjs)
|
||||
// then no language prefix is needed.
|
||||
if (languageOpt.code === defaultLang) {
|
||||
newPath = basePath;
|
||||
} else {
|
||||
// For non-default languages, prefix with the language code.
|
||||
newPath = `/${languageOpt.code}${basePath}`;
|
||||
}
|
||||
|
||||
// Clean up double slashes, just in case
|
||||
newPath = newPath.replace(/\/\/+/g, '/');
|
||||
// Handle case where basePath might be empty resulting in just /zh or /en
|
||||
if (newPath === '') newPath = '/';
|
||||
|
||||
// Prevent unnecessary redirects to the same page
|
||||
if (newPath !== currentPathname) {
|
||||
window.location.href = newPath;
|
||||
}
|
||||
@@ -120,7 +107,7 @@ export default function LanguageSwitcher({ lang: propLang }: LanguageSwitcherPro
|
||||
role="menuitem"
|
||||
>
|
||||
<span className="flex items-center">
|
||||
<span className="mr-2">{lang.icon}</span> {/* Display icon */}
|
||||
<span className="mr-2">{lang.icon}</span>
|
||||
{lang.name}
|
||||
</span>
|
||||
{selectedLanguage.code === lang.code && <Check size={16} className="text-primary" />}
|
||||
|
||||
@@ -2,10 +2,6 @@ import { motion, type Variants } from "framer-motion";
|
||||
import { useTranslations } from "@/i18n/utils";
|
||||
import { type SkillItem } from "@/types";
|
||||
|
||||
/**
|
||||
* All skills data with corresponding skillicons names
|
||||
* Using skillicons.dev for consistent icon display
|
||||
*/
|
||||
const allSkills: SkillItem[] = [
|
||||
// Programming Languages
|
||||
{ name: "TypeScript", icon: "typescript" },
|
||||
|
||||
@@ -6,11 +6,6 @@ interface ContainerProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Container component for consistent content width across the site
|
||||
* @param children - The content to be wrapped
|
||||
* @param className - Additional classes to apply
|
||||
*/
|
||||
export default function Container({
|
||||
children,
|
||||
className
|
||||
|
||||
@@ -1,25 +1,9 @@
|
||||
/**
|
||||
* Translations module
|
||||
* Contains all translation data for the application
|
||||
*/
|
||||
|
||||
/**
|
||||
* Available languages in the application
|
||||
*/
|
||||
export const languages = {
|
||||
en: 'English',
|
||||
zh: '简体中文',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Default language for the application
|
||||
*/
|
||||
export const defaultLang = 'en';
|
||||
|
||||
/**
|
||||
* Structured translations data
|
||||
* Organized by language and feature area
|
||||
*/
|
||||
export const translations = {
|
||||
en: {
|
||||
nav: {
|
||||
|
||||
@@ -1,44 +1,18 @@
|
||||
/**
|
||||
* Internationalization utilities module
|
||||
* Contains helper functions for i18n functionality
|
||||
*/
|
||||
import { defaultLang, languages, flatTranslations } from './translations';
|
||||
import type { Lang } from '@/types/i18n';
|
||||
|
||||
/**
|
||||
* Translation key type
|
||||
* Represents a dot-notation path to a translation string
|
||||
*/
|
||||
export type TranslationKey = string;
|
||||
|
||||
/**
|
||||
* Get translation function
|
||||
* Returns a function that can be used to get translations for a specific language
|
||||
*
|
||||
* @param lang - The language to get translations for
|
||||
* @returns A translation function
|
||||
*/
|
||||
export function useTranslations(lang: Lang | undefined) {
|
||||
const currentLang = lang || defaultLang;
|
||||
|
||||
/**
|
||||
* Translation function
|
||||
* Gets a translation string for the specified key and replaces placeholders
|
||||
*
|
||||
* @param key - The translation key (dot notation)
|
||||
* @param args - Optional arguments to replace placeholders in the translation
|
||||
* @returns The translated string
|
||||
*/
|
||||
return function t(key: TranslationKey, ...args: any[]): string {
|
||||
// Get translation from flattened translations for better performance
|
||||
let translation = flatTranslations[currentLang][key];
|
||||
|
||||
// Fallback to default language if translation not found
|
||||
if (!translation && currentLang !== defaultLang) {
|
||||
translation = flatTranslations[defaultLang][key];
|
||||
}
|
||||
|
||||
// Fallback to key if translation not found in any language
|
||||
if (!translation) {
|
||||
console.warn(`Translation key not found: ${key}`);
|
||||
return key;
|
||||
|
||||
@@ -1,23 +1,7 @@
|
||||
/**
|
||||
* Data module (Legacy)
|
||||
* This file is kept for backward compatibility
|
||||
* All data has been moved to src/lib/data/ directory
|
||||
*/
|
||||
|
||||
// Re-export all data from the new modules
|
||||
export { personalInfo } from './data/personal-info';
|
||||
export { projects } from './data/projects';
|
||||
export { services } from './data/services';
|
||||
|
||||
// For TypeScript type checking
|
||||
import { personalInfo } from './data/personal-info';
|
||||
import { projects } from './data/projects';
|
||||
import { services } from './data/services';
|
||||
|
||||
// Type exports are now handled in src/types/index.ts
|
||||
// This file is now just a re-export wrapper
|
||||
// The actual data is in the respective files in src/lib/data/ directory
|
||||
|
||||
// export const projects = {
|
||||
// en: [{
|
||||
// id: "taskify",
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/**
|
||||
* Data index module
|
||||
* Re-exports all data modules to maintain backward compatibility
|
||||
*/
|
||||
|
||||
// Re-export all data modules
|
||||
export { personalInfo } from './personal-info';
|
||||
export { projects } from './projects';
|
||||
export { services } from './services';
|
||||
@@ -1,13 +1,4 @@
|
||||
/**
|
||||
* Personal information data module
|
||||
* Contains all personal information used throughout the site
|
||||
*/
|
||||
import type { PersonalInfo } from '@/types';
|
||||
|
||||
/**
|
||||
* Personal information data
|
||||
* This data is used in various components like Header, Footer, and About sections
|
||||
*/
|
||||
export const personalInfo: PersonalInfo = {
|
||||
name: "Joy Zhao",
|
||||
location: "China",
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
/**
|
||||
* Projects data module
|
||||
* Contains all project information displayed in the projects page
|
||||
*/
|
||||
import type { Project } from '@/types';
|
||||
|
||||
/**
|
||||
* Projects data with localization support
|
||||
* Each project contains information like id, tag, title, description, tech stack, etc.
|
||||
*/
|
||||
export const projects = {
|
||||
en: [
|
||||
{
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
/**
|
||||
* Services data module
|
||||
* Contains all service information displayed in the services section
|
||||
*/
|
||||
import type { Service } from '@/types';
|
||||
|
||||
/**
|
||||
* Services data with localization support
|
||||
* Each service contains information like title, icon, items, and color
|
||||
*/
|
||||
export const services = {
|
||||
en: [
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { Lang } from './i18n';
|
||||
export interface SkillItem {
|
||||
name: string;
|
||||
icon: string;
|
||||
color: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
/**
|
||||
* Data types module
|
||||
* Contains type definitions for all data structures used in the application
|
||||
*/
|
||||
import type { Lang } from './i18n.ts';
|
||||
|
||||
/**
|
||||
* Multi-language text type
|
||||
*/
|
||||
export type LocalizedText = {
|
||||
[K in Lang]: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Personal information interface
|
||||
*/
|
||||
export interface PersonalInfo {
|
||||
name: string;
|
||||
location: string;
|
||||
@@ -45,18 +35,12 @@ export interface PersonalInfo {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Project image interface
|
||||
*/
|
||||
export interface ProjectImage {
|
||||
bg: string;
|
||||
hover: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Project interface
|
||||
*/
|
||||
export interface Project {
|
||||
id: string;
|
||||
tag: string;
|
||||
@@ -69,17 +53,11 @@ export interface Project {
|
||||
link: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service icon interface
|
||||
*/
|
||||
export interface ServiceIcon {
|
||||
svg: string;
|
||||
gradient: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service interface
|
||||
*/
|
||||
export interface Service {
|
||||
title: string;
|
||||
icon: ServiceIcon;
|
||||
|
||||
@@ -1,36 +1,17 @@
|
||||
/**
|
||||
* Internationalization types module
|
||||
* Contains type definitions for i18n functionality
|
||||
*/
|
||||
import { languages } from '@/i18n/translations';
|
||||
|
||||
/**
|
||||
* Language type definition
|
||||
*/
|
||||
export type Lang = keyof typeof languages;
|
||||
|
||||
/**
|
||||
* UI translation keys type
|
||||
*/
|
||||
export type UiKeys = string;
|
||||
|
||||
/**
|
||||
* Language switcher component props
|
||||
*/
|
||||
export interface LanguageSwitcherProps {
|
||||
lang: Lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Glass header component props
|
||||
*/
|
||||
export interface GlassHeaderProps {
|
||||
lang: Lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Footer component props
|
||||
*/
|
||||
export interface FooterProps {
|
||||
lang?: Lang;
|
||||
}
|
||||
Reference in New Issue
Block a user