✨ 2025 Lunar New Year Countdown Basis
This commit is contained in:
parent
4682aa000f
commit
102e14f643
11
package.json
11
package.json
@ -26,7 +26,7 @@
|
||||
"axios-case-converter": "^1.1.1",
|
||||
"cookies-next": "^5.0.2",
|
||||
"feed": "^4.2.2",
|
||||
"next": "^15.1.4",
|
||||
"next": "^15.1.5",
|
||||
"next-nprogress-bar": "^2.4.3",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
@ -43,15 +43,16 @@
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.3",
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
"@types/node": "^20.17.12",
|
||||
"@types/react": "^19.0.4",
|
||||
"@types/react-dom": "^19.0.2",
|
||||
"postcss": "^8.4.49",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"daisyui": "^4.12.23",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-config-next": "15.1.3",
|
||||
"@eslint/eslintrc": "^3.2.0"
|
||||
"postcss": "^8.4.49",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.7.3"
|
||||
},
|
||||
"trustedDependencies": [
|
||||
"@vercel/speed-insights",
|
||||
|
76
src/components/events/CountdownTimer.tsx
Normal file
76
src/components/events/CountdownTimer.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
import { Noto_Serif_TC } from 'next/font/google'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export interface TimeDiff {
|
||||
days: number
|
||||
hours: number
|
||||
minutes: number
|
||||
seconds: number
|
||||
isCountdown: boolean
|
||||
}
|
||||
|
||||
const serifFont = Noto_Serif_TC({
|
||||
weight: ['400', '500', '700'],
|
||||
display: 'swap',
|
||||
})
|
||||
|
||||
export function CountdownTimer({ targetDate, onUpdate }: { targetDate: Date; onUpdate: (diff: TimeDiff) => void }) {
|
||||
const [timeDiff, setTimeDiff] = useState({
|
||||
days: 0,
|
||||
hours: 0,
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
isCountdown: true,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const updateTimeDiff = () => {
|
||||
const now = new Date()
|
||||
const diff = targetDate.getTime() - now.getTime()
|
||||
|
||||
const absDiff = Math.abs(diff)
|
||||
const isCountdown = diff > 0
|
||||
|
||||
const days = Math.floor(absDiff / (1000 * 60 * 60 * 24))
|
||||
const hours = Math.floor((absDiff / (1000 * 60 * 60)) % 24)
|
||||
const minutes = Math.floor((absDiff / (1000 * 60)) % 60)
|
||||
const seconds = Math.floor((absDiff / 1000) % 60)
|
||||
|
||||
setTimeDiff({ days, hours, minutes, seconds, isCountdown })
|
||||
onUpdate({ days, hours, minutes, seconds, isCountdown })
|
||||
}
|
||||
|
||||
const intervalId = setInterval(updateTimeDiff, 1000)
|
||||
|
||||
return () => clearInterval(intervalId)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex gap-5">
|
||||
<div>
|
||||
<span className="countdown font-mono text-4xl">
|
||||
<span style={{ '--value': timeDiff.days } as any}></span>
|
||||
</span>
|
||||
<span className={serifFont.className}>天</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="countdown font-mono text-4xl">
|
||||
<span style={{ '--value': timeDiff.hours } as any}></span>
|
||||
</span>
|
||||
<span className={serifFont.className}>小时</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="countdown font-mono text-4xl">
|
||||
<span style={{ '--value': timeDiff.minutes } as any}></span>
|
||||
</span>
|
||||
<span className={serifFont.className}>分钟</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="countdown font-mono text-4xl">
|
||||
<span style={{ '--value': timeDiff.seconds } as any}></span>
|
||||
</span>
|
||||
<span className={serifFont.className}>秒</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
33
src/pages/events/2025-lunar-countdown.tsx
Normal file
33
src/pages/events/2025-lunar-countdown.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { CountdownTimer } from '@/components/events/CountdownTimer'
|
||||
import { Box, Container, Typography } from '@mui/material'
|
||||
import { Noto_Serif_TC } from 'next/font/google'
|
||||
import { useState } from 'react'
|
||||
|
||||
const serifFont = Noto_Serif_TC({
|
||||
weight: ['400', '500', '700'],
|
||||
display: 'swap',
|
||||
})
|
||||
|
||||
export default function LunarCountdownFor2025() {
|
||||
const [isCountdown, setIsCountdown] = useState(true)
|
||||
|
||||
return (
|
||||
<Container sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 'calc(100vh - 64px)' }}>
|
||||
<Box>
|
||||
<Typography style={serifFont.style} sx={{ textAlign: 'center' }}>
|
||||
距离
|
||||
</Typography>
|
||||
<Typography variant="h5" style={serifFont.style} sx={{ textAlign: 'center', fontWeight: 'bold' }}>
|
||||
二〇二五乙巳年
|
||||
</Typography>
|
||||
<Typography style={serifFont.style} sx={{ textAlign: 'center', mb: 3 }}>
|
||||
{isCountdown ? '还有' : '已经'}
|
||||
</Typography>
|
||||
<CountdownTimer
|
||||
targetDate={new Date('2025-01-29T00:00:00')}
|
||||
onUpdate={({ isCountdown }) => setIsCountdown(isCountdown)}
|
||||
/>
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Box, Chip, Container, Grid2 as Grid, Link, Paper, Typography } from '@mui/material'
|
||||
import { Alert, AlertTitle, Box, Button, Chip, Container, Grid2 as Grid, Link, Paper, Typography } from '@mui/material'
|
||||
import { Roboto_Serif } from 'next/font/google'
|
||||
import NextLink from 'next/link'
|
||||
import Image from 'next/image'
|
||||
@ -21,6 +21,22 @@ export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<Container sx={{ py: 24, display: 'flex', flexDirection: 'column', gap: 32 }}>
|
||||
<Alert
|
||||
variant="filled"
|
||||
icon={<span>🎉</span>}
|
||||
severity="info"
|
||||
action={
|
||||
<NextLink href="/events/2025-lunar-countdown" passHref>
|
||||
<Button color="inherit" size="small">
|
||||
立即前往
|
||||
</Button>
|
||||
</NextLink>
|
||||
}
|
||||
>
|
||||
<AlertTitle gutterBottom={false}>预祝农历新年</AlertTitle>
|
||||
索尔幸茨的 2025 农历新年倒计时现已开启!
|
||||
</Alert>
|
||||
|
||||
<Box>
|
||||
<Image src="/logo.png" width={128} height={128} alt="company logo" className="mb-2 dark:invert" />
|
||||
<Typography variant="h3" component="h1" gutterBottom>
|
||||
|
@ -14,5 +14,5 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [require('@tailwindcss/typography')],
|
||||
plugins: [require('@tailwindcss/typography'), require('daisyui')],
|
||||
} satisfies Config
|
||||
|
Loading…
x
Reference in New Issue
Block a user