summaryrefslogtreecommitdiff
path: root/lib/bidding/list/biddings-stats-cards.tsx
blob: 14e29c16f3ba1d48f9ead1112bfc49706fbbc486 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"use client"

import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { 
  FileText, 
  Clock, 
  CheckCircle, 
  TrendingUp,
  Users,
  DollarSign,
  Calendar,
  BarChart3
} from "lucide-react"
import { biddingStatusLabels, biddingTypeLabels } from "@/db/schema"

interface BiddingsStatsCardsProps {
  total: number
  statusCounts: Record<string, number>
  typeCounts: Record<string, number>
  managerCounts: Record<string, number>
  monthlyStats: Array<{ month: number; count: number }>
}

export function BiddingsStatsCards({
  total,
  statusCounts,
  typeCounts,
  managerCounts,
  monthlyStats
}: BiddingsStatsCardsProps) {
  // 이번 달 생성 건수
  const currentMonth = new Date().getMonth() + 1
  const thisMonthCount = monthlyStats.find(stat => stat.month === currentMonth)?.count || 0
  
  // 지난 달 대비 증감
  const lastMonthCount = monthlyStats.find(stat => stat.month === currentMonth - 1)?.count || 0
  const monthlyGrowth = lastMonthCount > 0 ? ((thisMonthCount - lastMonthCount) / lastMonthCount * 100).toFixed(1) : '0'
  
  // 진행중인 입찰 수 (active 상태들)
  const activeStatuses = ['bidding_opened', 'bidding_closed', 'evaluation_of_bidding']
  const activeBiddingsCount = activeStatuses.reduce((sum, status) => sum + (statusCounts[status] || 0), 0)
  
  // 완료된 입찰 수
  const completedCount = statusCounts['vendor_selected'] || 0
  
  // 가장 많은 담당자
  const topManager = Object.entries(managerCounts).sort(([,a], [,b]) => b - a)[0]
  
  // 가장 많은 입찰 유형
  const topBiddingType = Object.entries(typeCounts).sort(([,a], [,b]) => b - a)[0]

  return (
    <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
      {/* 전체 입찰 수 */}
      <Card>
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
          <CardTitle className="text-sm font-medium">전체 입찰</CardTitle>
          <FileText className="h-4 w-4 text-muted-foreground" />
        </CardHeader>
        <CardContent>
          <div className="text-2xl font-bold">{total.toLocaleString()}</div>
          {/* <p className="text-xs text-muted-foreground">
            이번 달 <span className="font-medium text-green-600">+{thisMonthCount}</span>건
          </p> */}
        </CardContent>
      </Card>

      {/* 진행중인 입찰 */}
      <Card>
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
          <CardTitle className="text-sm font-medium">진행중</CardTitle>
          <Clock className="h-4 w-4 text-muted-foreground" />
        </CardHeader>
        <CardContent>
          <div className="text-2xl font-bold text-orange-600">{activeBiddingsCount}</div>
          <div className="flex gap-1 mt-1">
            {activeStatuses.map(status => (
              statusCounts[status] > 0 && (
                <Badge key={status} variant="outline" className="text-xs">
                  {biddingStatusLabels[status]}: {statusCounts[status]}
                </Badge>
              )
            ))}
          </div>
        </CardContent>
      </Card>

      {/* 완료된 입찰 */}
      <Card>
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
          <CardTitle className="text-sm font-medium">완료</CardTitle>
          <CheckCircle className="h-4 w-4 text-muted-foreground" />
        </CardHeader>
        <CardContent>
          <div className="text-2xl font-bold text-green-600">{completedCount}</div>
          <p className="text-xs text-muted-foreground">
            완료율 {total > 0 ? ((completedCount / total) * 100).toFixed(1) : 0}%
          </p>
        </CardContent>
      </Card>

      {/* 월별 증감 */}
      <Card>
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
          <CardTitle className="text-sm font-medium">월별 증감</CardTitle>
          <TrendingUp className="h-4 w-4 text-muted-foreground" />
        </CardHeader>
        <CardContent>
          <div className="text-2xl font-bold">
            <span className={Number(monthlyGrowth) >= 0 ? 'text-green-600' : 'text-red-600'}>
              {Number(monthlyGrowth) >= 0 ? '+' : ''}{monthlyGrowth}%
            </span>
          </div>
          <p className="text-xs text-muted-foreground">
            지난 달 대비
          </p>
        </CardContent>
      </Card>
    </div>
  )
}