전체적인 리팩토링

This commit is contained in:
2026-03-12 09:26:27 +09:00
parent 406af7408a
commit e51d767878
97 changed files with 13651 additions and 363 deletions

View File

@@ -1,5 +1,6 @@
import { BarChart3, TrendingDown, TrendingUp } from "lucide-react";
import { RefreshCcw } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import {
Card,
CardContent,
@@ -22,6 +23,7 @@ interface MarketSummaryProps {
isLoading: boolean;
error: string | null;
warning?: string | null;
isWebSocketReady?: boolean;
isRealtimePending?: boolean;
onRetry?: () => void;
}
@@ -35,22 +37,46 @@ export function MarketSummary({
isLoading,
error,
warning = null,
isWebSocketReady = false,
isRealtimePending = false,
onRetry,
}: MarketSummaryProps) {
const realtimeBadgeText = isRealtimePending
? "실시간 대기중"
: isWebSocketReady
? "실시간 수신중"
: items.length > 0
? "REST 데이터"
: "데이터 준비중";
return (
<Card className="overflow-hidden border-brand-200/80 bg-linear-to-br from-brand-50/50 to-background dark:border-brand-800/45 dark:from-brand-950/20 dark:to-background">
<Card className="overflow-hidden border-brand-200/80 bg-linear-to-br from-brand-100/65 via-brand-50/30 to-background shadow-sm dark:border-brand-800/45 dark:from-brand-900/35 dark:via-brand-950/20 dark:to-background">
<CardHeader className="pb-2">
<div className="flex items-center justify-between">
<CardTitle className="flex items-center gap-2 text-base text-brand-700 dark:text-brand-300">
<BarChart3 className="h-4 w-4" />
</CardTitle>
<Badge
variant="outline"
className={cn(
"border-brand-300/70 bg-background/80 text-[11px] font-medium dark:border-brand-700/60 dark:bg-brand-950/30",
isRealtimePending
? "text-amber-700 dark:text-amber-300"
: isWebSocketReady
? "text-emerald-700 dark:text-emerald-300"
: "text-muted-foreground",
)}
>
{realtimeBadgeText}
</Badge>
</div>
<CardDescription> / .</CardDescription>
<CardDescription>
/ .
</CardDescription>
</CardHeader>
<CardContent className="grid gap-3 sm:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2">
<CardContent className="grid gap-3 sm:grid-cols-2">
{/* ========== LOADING STATE ========== */}
{isLoading && items.length === 0 && (
<div className="col-span-full py-4 text-center text-sm text-muted-foreground animate-pulse">
@@ -133,23 +159,23 @@ function IndexItem({ item }: { item: DashboardMarketIndexItem }) {
: "text-muted-foreground";
const bgClass = isUp
? "bg-red-50/50 dark:bg-red-950/10 border-red-100 dark:border-red-900/30"
? "bg-linear-to-br from-red-50/90 to-background dark:from-red-950/20 dark:to-background border-red-100/80 dark:border-red-900/40"
: isDown
? "bg-blue-50/50 dark:bg-blue-950/10 border-blue-100 dark:border-blue-900/30"
: "bg-muted/50 border-border/50";
? "bg-linear-to-br from-blue-50/90 to-background dark:from-blue-950/20 dark:to-background border-blue-100/80 dark:border-blue-900/40"
: "bg-linear-to-br from-muted/60 to-background border-border/50";
const flash = usePriceFlash(item.price, item.code);
return (
<div
className={cn(
"relative flex flex-col justify-between rounded-xl border p-4 transition-all hover:bg-background/80",
"relative flex flex-col justify-between rounded-2xl border p-4 shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-md",
bgClass,
)}
>
<div className="flex items-center justify-between">
<span className="text-sm font-medium text-muted-foreground">
{item.market}
{item.name} ({item.market})
</span>
{isUp ? (
<TrendingUp className="h-4 w-4 text-red-500/70" />
@@ -158,7 +184,7 @@ function IndexItem({ item }: { item: DashboardMarketIndexItem }) {
) : null}
</div>
<div className="mt-2 text-2xl font-bold tracking-tight relative w-fit">
<div className="relative mt-2 w-fit text-2xl font-bold tracking-tight">
{formatCurrency(item.price)}
{/* Flash Indicator */}
@@ -176,14 +202,9 @@ function IndexItem({ item }: { item: DashboardMarketIndexItem }) {
)}
</div>
<div
className={cn(
"mt-1 flex items-center gap-2 text-sm font-medium",
toneClass,
)}
>
<div className={cn("mt-2 flex items-center gap-2 text-sm font-medium", toneClass)}>
<span>{formatSignedCurrency(item.change)}</span>
<span className="rounded-md bg-background/50 px-1.5 py-0.5 text-xs shadow-sm">
<span className="rounded-md bg-background/70 px-1.5 py-0.5 text-xs shadow-sm">
{formatSignedPercent(item.changeRate)}
</span>
</div>