mirror of
https://github.com/handsomezhuzhu/AeroStart.git
synced 2026-02-20 12:00:15 +00:00
94 lines
3.1 KiB
TypeScript
94 lines
3.1 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { useTranslation } from '../i18n';
|
|
|
|
interface ClockProps {
|
|
showSeconds?: boolean;
|
|
use24HourFormat?: boolean;
|
|
motto?: string;
|
|
}
|
|
|
|
const Clock: React.FC<ClockProps> = ({ showSeconds = true, use24HourFormat = true, motto = '同是天涯沦落人,相逢何必曾相识' }) => {
|
|
const [time, setTime] = useState(new Date());
|
|
const { language } = useTranslation();
|
|
|
|
useEffect(() => {
|
|
const timer = setInterval(() => {
|
|
setTime(new Date());
|
|
}, 1000);
|
|
|
|
return () => clearInterval(timer);
|
|
}, []);
|
|
|
|
const rawHours = time.getHours();
|
|
const rawMinutes = time.getMinutes();
|
|
const rawSeconds = time.getSeconds();
|
|
|
|
let displayHours = rawHours;
|
|
let ampm = '';
|
|
|
|
if (!use24HourFormat) {
|
|
displayHours = rawHours % 12 || 12; // Convert 0 to 12
|
|
ampm = rawHours >= 12 ? 'PM' : 'AM';
|
|
}
|
|
|
|
const hoursStr = displayHours.toString().padStart(2, '0');
|
|
const minutesStr = rawMinutes.toString().padStart(2, '0');
|
|
const secondsStr = rawSeconds.toString().padStart(2, '0');
|
|
|
|
const weekday = time.toLocaleDateString('en-US', { weekday: 'short' }).toUpperCase();
|
|
const month = (time.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = time.getDate().toString().padStart(2, '0');
|
|
const datePart = `${month}/${day}`;
|
|
|
|
return (
|
|
<div className="flex flex-col items-center select-none text-white drop-shadow-2xl">
|
|
<div className="flex items-baseline font-light tracking-tight">
|
|
{/* Short Date (Left side, stacked) */}
|
|
<div className="relative mr-2 md:mr-3">
|
|
<span className="absolute bottom-full right-0 mb-1 text-xs md:text-sm font-light text-white/60 tracking-widest uppercase whitespace-nowrap">
|
|
{weekday}
|
|
</span>
|
|
<span className="text-base md:text-xl font-light text-white/80 tracking-widest leading-none">
|
|
{datePart}
|
|
</span>
|
|
</div>
|
|
|
|
{/* Hours */}
|
|
<span className="text-5xl md:text-6xl lg:text-7xl font-sans font-extralight tracking-tighter tabular-nums text-white/95">
|
|
{hoursStr}
|
|
</span>
|
|
|
|
{/* Separator */}
|
|
<span className="text-4xl md:text-5xl lg:text-6xl px-2 md:px-4 text-white/60 animate-pulse -translate-y-1 md:-translate-y-2">
|
|
:
|
|
</span>
|
|
|
|
{/* Minutes */}
|
|
<span className="text-5xl md:text-6xl lg:text-7xl font-sans font-extralight tracking-tighter tabular-nums text-white/95">
|
|
{minutesStr}
|
|
</span>
|
|
|
|
{/* Seconds (Optional small display) */}
|
|
{showSeconds && (
|
|
<span className="ml-2 md:ml-3 text-xl md:text-2xl lg:text-3xl font-mono text-white/60 font-light w-12 tabular-nums">
|
|
{secondsStr}
|
|
</span>
|
|
)}
|
|
|
|
{/* AM/PM Indicator */}
|
|
{!use24HourFormat && (
|
|
<span className="ml-2 md:ml-3 text-lg md:text-xl font-light text-white/60 self-end mb-2 md:mb-3">
|
|
{ampm}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
{/* Motto */}
|
|
<div className="mt-4 text-lg md:text-xl font-light text-white/70 tracking-widest uppercase text-center max-w-2xl">
|
|
{motto}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Clock; |