refactor: optimize Header component with memoization and time tracking

This commit is contained in:
hamster1963 2025-02-06 00:15:37 +08:00
parent 010cfce1c4
commit 3ce131419f

View File

@ -9,7 +9,94 @@ import NumberFlow, { NumberFlowGroup } from "@number-flow/react"
import { DateTime } from "luxon" import { DateTime } from "luxon"
import { useTranslations } from "next-intl" import { useTranslations } from "next-intl"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import React from "react" import { memo, useCallback, useEffect, useState } from "react"
interface TimeState {
hh: number
mm: number
ss: number
}
interface CustomLink {
link: string
name: string
}
const useCurrentTime = () => {
const [time, setTime] = useState<TimeState>({
hh: DateTime.now().setLocale("en-US").hour,
mm: DateTime.now().setLocale("en-US").minute,
ss: DateTime.now().setLocale("en-US").second,
})
useEffect(() => {
const timer = setInterval(() => {
const now = DateTime.now().setLocale("en-US")
setTime({
hh: now.hour,
mm: now.minute,
ss: now.second,
})
}, 1000)
return () => clearInterval(timer)
}, [])
return time
}
const Links = memo(function Links() {
const linksEnv = getEnv("NEXT_PUBLIC_Links")
const links: CustomLink[] | null = linksEnv ? JSON.parse(linksEnv) : null
if (!links) return null
return (
<div className="flex items-center gap-2">
{links.map((link) => (
<a
key={link.link}
href={link.link}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-1 text-sm font-medium opacity-50 transition-opacity hover:opacity-100"
>
{link.name}
</a>
))}
</div>
)
})
const Overview = memo(function Overview() {
const t = useTranslations("Overview")
const time = useCurrentTime()
return (
<section className={"mt-10 flex flex-col md:mt-16"}>
<p className="text-base font-semibold">{t("p_2277-2331_Overview")}</p>
<div className="flex items-center gap-1.5">
<p className="text-sm font-medium opacity-50">{t("p_2390-2457_wherethetimeis")}</p>
<NumberFlowGroup>
<div
style={{ fontVariantNumeric: "tabular-nums" }}
className="flex text-sm font-medium mt-0.5"
>
<NumberFlow trend={1} value={time.hh} format={{ minimumIntegerDigits: 2 }} />
<NumberFlow
prefix=":"
trend={1}
value={time.mm}
digits={{ 1: { max: 5 } }}
format={{ minimumIntegerDigits: 2 }}
/>
<p className="mt-[0.5px]">:{time.ss.toString().padStart(2, "0")}</p>
</div>
</NumberFlowGroup>
</div>
</section>
)
})
function Header() { function Header() {
const t = useTranslations("Header") const t = useTranslations("Header")
@ -19,14 +106,16 @@ function Header() {
const router = useRouter() const router = useRouter()
const handleLogoClick = useCallback(() => {
sessionStorage.removeItem("selectedTag")
router.push("/")
}, [router])
return ( return (
<div className="mx-auto w-full max-w-5xl"> <div className="mx-auto w-full max-w-5xl">
<section className="flex items-center justify-between"> <section className="flex items-center justify-between">
<section <section
onClick={() => { onClick={handleLogoClick}
sessionStorage.removeItem("selectedTag")
router.push("/")
}}
className="flex cursor-pointer items-center text-base font-medium hover:opacity-50 transition-opacity duration-300" className="flex cursor-pointer items-center text-base font-medium hover:opacity-50 transition-opacity duration-300"
> >
<div className="mr-1 flex flex-row items-center justify-start"> <div className="mr-1 flex flex-row items-center justify-start">
@ -67,80 +156,4 @@ function Header() {
) )
} }
type links = {
link: string
name: string
}
function Links() {
const linksEnv = getEnv("NEXT_PUBLIC_Links")
const links: links[] | null = linksEnv ? JSON.parse(linksEnv) : null
if (!links) return null
return (
<div className="flex items-center gap-2">
{links.map((link) => {
return (
<a
key={link.link}
href={link.link}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-1 text-sm font-medium opacity-50 transition-opacity hover:opacity-100"
>
{link.name}
</a>
)
})}
</div>
)
}
function Overview() {
const t = useTranslations("Overview")
const [time, setTime] = React.useState({
hh: DateTime.now().setLocale("en-US").hour,
mm: DateTime.now().setLocale("en-US").minute,
ss: DateTime.now().setLocale("en-US").second,
})
React.useEffect(() => {
const timer = setInterval(() => {
setTime({
hh: DateTime.now().setLocale("en-US").hour,
mm: DateTime.now().setLocale("en-US").minute,
ss: DateTime.now().setLocale("en-US").second,
})
}, 1000)
return () => clearInterval(timer)
}, [])
return (
<section className={"mt-10 flex flex-col md:mt-16"}>
<p className="text-base font-semibold">{t("p_2277-2331_Overview")}</p>
<div className="flex items-center gap-1.5">
<p className="text-sm font-medium opacity-50">{t("p_2390-2457_wherethetimeis")}</p>
<NumberFlowGroup>
<div
style={{ fontVariantNumeric: "tabular-nums" }}
className="flex text-sm font-medium mt-0.5"
>
<NumberFlow trend={1} value={time.hh} format={{ minimumIntegerDigits: 2 }} />
<NumberFlow
prefix=":"
trend={1}
value={time.mm}
digits={{ 1: { max: 5 } }}
format={{ minimumIntegerDigits: 2 }}
/>
<p className="mt-[0.5px]">:{time.ss.toString().padStart(2, "0")}</p>
</div>
</NumberFlowGroup>
</div>
</section>
)
}
export default Header export default Header