88 lines
4.1 KiB
TypeScript
88 lines
4.1 KiB
TypeScript
import { Sun, Moon, Cloud, Trees, Stars, Bird } from 'lucide-react';
|
|
import { formatTime, formatDate } from '@/lib/formatters';
|
|
|
|
const DynamicScene = ({ hour }: { hour: number }) => {
|
|
if (hour >= 5 && hour < 11) {
|
|
return (
|
|
<div className="relative h-24 w-32 overflow-hidden">
|
|
<Sun className="absolute bottom-0 left-4 h-16 w-16 animate-pulse text-amber-400" fill="currentColor" />
|
|
<Cloud className="absolute top-2 right-2 h-10 w-10 animate-bounce text-white/80" fill="currentColor" />
|
|
<Cloud className="absolute top-8 left-0 h-8 w-8 animate-bounce text-white/60 [animation-delay:1s]" fill="currentColor" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (hour >= 11 && hour < 15) {
|
|
return (
|
|
<div className="relative h-24 w-32 overflow-hidden">
|
|
<Sun className="absolute top-0 right-4 h-14 w-14 animate-spin-slow text-yellow-400" fill="currentColor" />
|
|
<Trees className="absolute bottom-0 left-2 h-14 w-14 text-green-600 dark:text-green-500" />
|
|
<Cloud className="absolute top-4 left-4 h-8 w-8 animate-pulse text-white/80" fill="currentColor" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (hour >= 15 && hour < 19) {
|
|
return (
|
|
<div className="relative h-24 w-32 overflow-hidden">
|
|
<Sun className="absolute bottom-[-10px] left-8 h-16 w-16 text-orange-500" fill="currentColor" />
|
|
<Bird className="absolute top-4 left-4 h-6 w-6 animate-bounce text-orange-800 dark:text-orange-200" />
|
|
<Bird className="absolute top-8 right-8 h-5 w-5 animate-bounce text-orange-800 dark:text-orange-200 [animation-delay:0.5s]" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="relative h-24 w-32 overflow-hidden">
|
|
<Moon className="absolute top-2 left-6 h-14 w-14 rotate-12 text-indigo-200" fill="currentColor" />
|
|
<Stars className="absolute top-4 right-4 h-6 w-6 animate-pulse text-yellow-200" />
|
|
<Stars className="absolute bottom-4 left-2 h-4 w-4 animate-pulse text-yellow-100 [animation-delay:1s]" />
|
|
<div className="absolute bottom-2 right-6 h-1 w-1 animate-ping rounded-full bg-white"></div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export interface WelcomeCardProps {
|
|
user: { name: string };
|
|
time: Date;
|
|
theme: {
|
|
class: string;
|
|
decoration: string;
|
|
text: string;
|
|
subtext: string;
|
|
greeting: string;
|
|
};
|
|
}
|
|
|
|
export function WelcomeCard({ user, time, theme }: WelcomeCardProps) {
|
|
const hour = time.getHours();
|
|
|
|
return (
|
|
<div className={`relative flex flex-col justify-between gap-4 overflow-hidden rounded-xl border p-6 shadow-2xl transition-all duration-1000 md:flex-row md:items-center ${theme.class}`}>
|
|
{/* Decorative Elements */}
|
|
<div className={`absolute -right-10 -top-10 h-40 w-40 rounded-full blur-3xl ${theme.decoration} opacity-60`} />
|
|
<div className={`absolute -bottom-10 left-1/3 h-32 w-32 rounded-full blur-3xl ${theme.decoration} opacity-40`} />
|
|
|
|
<div className="z-10">
|
|
<h1 className={`text-3xl font-extrabold tracking-tight ${theme.text}`}>
|
|
{theme.greeting}, {user.name}!
|
|
</h1>
|
|
<p className={`mt-1 text-lg font-medium ${theme.subtext}`}>
|
|
Senang melihat Anda kembali. Berikut adalah ringkasan bisnis Anda hari ini.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="z-10 flex flex-col items-start gap-4 md:flex-row md:items-center md:gap-8">
|
|
<DynamicScene hour={hour} />
|
|
<div className="flex flex-col items-start gap-1 md:items-end">
|
|
<div className={`text-4xl font-mono font-black tracking-tighter ${theme.text}`}>
|
|
{formatTime(time)}
|
|
</div>
|
|
<div className={`text-sm font-bold uppercase tracking-wider ${theme.subtext}`}>
|
|
{formatDate(time)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |