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:
joyzhao
2025-06-21 09:28:10 +08:00
parent ea01dc6dd8
commit 67f713565a
15 changed files with 9 additions and 168 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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" />}

View File

@@ -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" },

View File

@@ -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