summaryrefslogtreecommitdiff
path: root/lib/dashboard/dashboard-client.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dashboard/dashboard-client.tsx')
-rw-r--r--lib/dashboard/dashboard-client.tsx115
1 files changed, 115 insertions, 0 deletions
diff --git a/lib/dashboard/dashboard-client.tsx b/lib/dashboard/dashboard-client.tsx
new file mode 100644
index 00000000..37dc1901
--- /dev/null
+++ b/lib/dashboard/dashboard-client.tsx
@@ -0,0 +1,115 @@
+"use client";
+
+import { useState } from "react";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import { Button } from "@/components/ui/button";
+import { RefreshCw } from "lucide-react";
+import { DashboardStatsCard } from "./dashboard-stats-card";
+import { DashboardOverviewChart } from "./dashboard-overview-chart";
+import { DashboardSummaryCards } from "./dashboard-summary-cards";
+import { toast } from "sonner";
+import { DashboardData } from "./service";
+
+interface DashboardClientProps {
+ initialData: DashboardData;
+ onRefresh: () => Promise<DashboardData>;
+}
+
+export function DashboardClient({ initialData, onRefresh }: DashboardClientProps) {
+ const [data, setData] = useState<DashboardData>(initialData);
+ const [isRefreshing, setIsRefreshing] = useState(false);
+
+
+ const handleRefresh = async () => {
+ try {
+ setIsRefreshing(true);
+ const newData = await onRefresh();
+ setData(newData);
+ toast.success("대시보드 데이터가 새로고침되었습니다.");
+ } catch (error) {
+ toast.error("데이터 새로고침에 실패했습니다.");
+ console.error("Dashboard refresh error:", error);
+ } finally {
+ setIsRefreshing(false);
+ }
+ };
+
+ const getDomainDisplayName = (domain: string) => {
+ const domainNames: Record<string, string> = {
+ 'procurement': '구매 관리',
+ 'sales': '영업 관리',
+ "partners": 'Partners',
+ 'engineering': '엔지니어링'
+ };
+ return domainNames[domain] || domain;
+ };
+
+ return (
+ <div className="space-y-6">
+ {/* 헤더 */}
+ <div className="flex items-center justify-between">
+ <div>
+ <h2 className="text-2xl font-bold tracking-tight">
+ {getDomainDisplayName(data.domain)} Dashboard
+ </h2>
+ <p className="text-muted-foreground">
+ {data.domain ==="partners"? "회사와 개인에게 할당된 일들을 보여줍니다.":"팀과 개인에게 할당된 일들을 보여줍니다."}
+ </p>
+ </div>
+ <Button
+ onClick={handleRefresh}
+ disabled={isRefreshing}
+ variant="outline"
+ size="sm"
+ >
+ <RefreshCw
+ className={`w-4 h-4 mr-2 ${isRefreshing ? 'animate-spin' : ''}`}
+ />
+ 새로고침
+ </Button>
+ </div>
+
+ {/* 요약 카드 */}
+ <DashboardSummaryCards summary={data.summary} />
+
+ {/* 차트 */}
+ <DashboardOverviewChart
+ data={data.teamStats}
+ title={getDomainDisplayName(data.domain)}
+ description="업무 타입별 현황을 확인하세요"
+ />
+
+ {/* 탭 */}
+ <Tabs defaultValue="team" className="space-y-4">
+ <TabsList className="grid w-full grid-cols-2 max-w-md">
+ <TabsTrigger value="team"> {data.domain ==="partners"? "회사 업무 현황":"팀 업무 현황"}</TabsTrigger>
+ <TabsTrigger value="personal">내 업무 현황</TabsTrigger>
+ </TabsList>
+
+ <TabsContent value="team" className="space-y-4">
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
+ {data.teamStats.map((stats) => (
+ <DashboardStatsCard
+ key={stats.tableName}
+ stats={stats}
+ showUserStats={false}
+ />
+ ))}
+ </div>
+ </TabsContent>
+
+ <TabsContent value="personal" className="space-y-4">
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
+ {data.userStats.map((stats) => (
+ <DashboardStatsCard
+ key={stats.tableName}
+ stats={stats}
+ showUserStats={true}
+ />
+ ))}
+ </div>
+ </TabsContent>
+ </Tabs>
+ </div>
+ );
+} \ No newline at end of file