54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import { LoaderCircle } from 'lucide-react';
|
|
import { useEffect, useState } from 'react';
|
|
import { Badge } from '../../components/ui';
|
|
import { formatDateTime as formatDateTimeValue } from '../../lib/date-format';
|
|
|
|
export type BadgeTone = 'neutral' | 'green' | 'amber' | 'red' | 'blue' | 'violet';
|
|
|
|
export function statusTone(status?: string | null): BadgeTone {
|
|
if (!status) return 'neutral';
|
|
if (['활성', '완료', '게시됨', '게시중', '실행 중', '배포됨', '성공', 'Running', 'ACTIVE'].includes(status)) return 'green';
|
|
if (['주의', '예약됨', '예약', '대기', '준비중', '카나리', '만료', 'PENDING'].includes(status)) return 'amber';
|
|
if (['잠김', '실패', '오프라인', '비활성', '종료', 'FAILED', 'Error', 'CrashLoopBackOff'].includes(status)) return 'red';
|
|
if (['없음'].includes(status)) return 'neutral';
|
|
if (['런처'].includes(status)) return 'violet';
|
|
return 'neutral';
|
|
}
|
|
|
|
export function StatusBadge({ status, tone }: { status: string; tone?: BadgeTone }) {
|
|
return <Badge tone={tone ?? statusTone(status)}>{status}</Badge>;
|
|
}
|
|
|
|
export function formatDateTime(value?: string | null) {
|
|
return formatDateTimeValue(value);
|
|
}
|
|
|
|
export function LoadingModal({ open }: { open: boolean }) {
|
|
if (!open) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-x-0 bottom-0 top-16 z-[15] flex items-center justify-center bg-background/20 px-4 backdrop-blur-[1px] lg:left-[17rem]">
|
|
<div className="flex min-h-28 min-w-72 items-center justify-center gap-3 rounded-lg border border-border bg-card px-8 py-6 text-sm font-semibold shadow-2xl lg:-translate-x-[8.5rem]">
|
|
<LoaderCircle className="size-5 animate-spin text-primary" />
|
|
데이터를 불러오는 중입니다.
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function useMinimumLoading(loading: boolean, minimumMs = 500) {
|
|
const [visible, setVisible] = useState(loading);
|
|
|
|
useEffect(() => {
|
|
if (loading) {
|
|
setVisible(true);
|
|
return;
|
|
}
|
|
|
|
const timer = window.setTimeout(() => setVisible(false), minimumMs);
|
|
return () => window.clearTimeout(timer);
|
|
}, [loading, minimumMs]);
|
|
|
|
return visible;
|
|
}
|