ERP-node/frontend/app/(main)/admin/mail/dashboard/page.tsx

283 lines
9.9 KiB
TypeScript

"use client";
import React, { useState, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import {
Mail,
Send,
Inbox,
FileText,
RefreshCw,
TrendingUp,
Users,
Calendar,
Clock
} from "lucide-react";
import { getMailAccounts, getMailTemplates } from "@/lib/api/mail";
interface DashboardStats {
totalAccounts: number;
totalTemplates: number;
sentToday: number;
receivedToday: number;
sentThisMonth: number;
successRate: number;
}
export default function MailDashboardPage() {
const [stats, setStats] = useState<DashboardStats>({
totalAccounts: 0,
totalTemplates: 0,
sentToday: 0,
receivedToday: 0,
sentThisMonth: 0,
successRate: 0,
});
const [loading, setLoading] = useState(false);
const loadStats = async () => {
setLoading(true);
try {
// 계정 수 (apiClient를 통해 토큰 포함)
const accounts = await getMailAccounts();
// 템플릿 수 (apiClient를 통해 토큰 포함)
const templates = await getMailTemplates();
setStats({
totalAccounts: accounts.length,
totalTemplates: templates.length,
sentToday: 0, // TODO: 실제 발송 통계 API 연동
receivedToday: 0,
sentThisMonth: 0,
successRate: 0,
});
} catch (error) {
// console.error('통계 로드 실패:', error);
} finally {
setLoading(false);
}
};
useEffect(() => {
loadStats();
}, []);
const statCards = [
{
title: "등록된 계정",
value: stats.totalAccounts,
icon: Users,
color: "blue",
bgColor: "bg-blue-100",
iconColor: "text-blue-500",
},
{
title: "템플릿 수",
value: stats.totalTemplates,
icon: FileText,
color: "green",
bgColor: "bg-green-100",
iconColor: "text-green-500",
},
{
title: "오늘 발송",
value: stats.sentToday,
icon: Send,
color: "orange",
bgColor: "bg-orange-100",
iconColor: "text-orange-500",
},
{
title: "오늘 수신",
value: stats.receivedToday,
icon: Inbox,
color: "purple",
bgColor: "bg-purple-100",
iconColor: "text-purple-500",
},
];
return (
<div className="min-h-screen bg-gray-50">
<div className="w-full max-w-none px-4 py-8 space-y-8">
{/* 페이지 제목 */}
<div className="flex items-center justify-between bg-white rounded-lg shadow-sm border p-6">
<div>
<h1 className="text-3xl font-bold text-gray-900"> </h1>
<p className="mt-2 text-gray-600"> </p>
</div>
<Button
variant="outline"
size="sm"
onClick={loadStats}
disabled={loading}
>
<RefreshCw className={`w-4 h-4 mr-2 ${loading ? 'animate-spin' : ''}`} />
</Button>
</div>
{/* 통계 카드 */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{statCards.map((stat, index) => (
<Card key={index} className="shadow-sm hover:shadow-md transition-shadow">
<CardContent className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-gray-500 mb-1">{stat.title}</p>
<p className="text-3xl font-bold text-gray-900">{stat.value}</p>
</div>
<div className={`${stat.bgColor} p-3 rounded-lg`}>
<stat.icon className={`w-6 h-6 ${stat.iconColor}`} />
</div>
</div>
</CardContent>
</Card>
))}
</div>
{/* 이번 달 통계 */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Card className="shadow-sm">
<CardHeader className="border-b bg-gradient-to-r from-slate-50 to-gray-50">
<CardTitle className="flex items-center">
<Calendar className="w-5 h-5 mr-2 text-orange-500" />
</CardTitle>
</CardHeader>
<CardContent className="p-6">
<div className="space-y-4">
<div className="flex items-center justify-between">
<span className="text-sm text-gray-600"> </span>
<span className="text-lg font-semibold text-gray-900">
{stats.sentThisMonth}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-sm text-gray-600"></span>
<span className="text-lg font-semibold text-green-600">
{stats.successRate}%
</span>
</div>
<div className="pt-4 border-t">
<div className="flex items-center text-sm text-gray-500">
<TrendingUp className="w-4 h-4 mr-2 text-green-500" />
12%
</div>
</div>
</div>
</CardContent>
</Card>
<Card className="shadow-sm">
<CardHeader className="border-b bg-gradient-to-r from-slate-50 to-gray-50">
<CardTitle className="flex items-center">
<Clock className="w-5 h-5 mr-2 text-blue-500" />
</CardTitle>
</CardHeader>
<CardContent className="p-6">
<div className="space-y-3">
<div className="text-center text-gray-500 py-8">
<Mail className="w-12 h-12 mx-auto mb-3 text-gray-300" />
<p className="text-sm"> </p>
</div>
</div>
</CardContent>
</Card>
</div>
{/* 빠른 액세스 */}
<Card className="shadow-sm">
<CardHeader className="border-b bg-gradient-to-r from-slate-50 to-gray-50">
<CardTitle> </CardTitle>
</CardHeader>
<CardContent className="p-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<a
href="/admin/mail/accounts"
className="flex items-center p-4 rounded-lg border border-gray-200 hover:border-orange-300 hover:bg-orange-50 transition-all"
>
<Users className="w-8 h-8 text-blue-500 mr-3" />
<div>
<p className="font-medium text-gray-900"> </p>
<p className="text-sm text-gray-500"> </p>
</div>
</a>
<a
href="/admin/mail/templates"
className="flex items-center p-4 rounded-lg border border-gray-200 hover:border-orange-300 hover:bg-orange-50 transition-all"
>
<FileText className="w-8 h-8 text-green-500 mr-3" />
<div>
<p className="font-medium text-gray-900">릿 </p>
<p className="text-sm text-gray-500">릿 </p>
</div>
</a>
<a
href="/admin/mail/send"
className="flex items-center p-4 rounded-lg border border-gray-200 hover:border-orange-300 hover:bg-orange-50 transition-all"
>
<Send className="w-8 h-8 text-orange-500 mr-3" />
<div>
<p className="font-medium text-gray-900"> </p>
<p className="text-sm text-gray-500"> </p>
</div>
</a>
<a
href="/admin/mail/receive"
className="flex items-center p-4 rounded-lg border border-gray-200 hover:border-orange-300 hover:bg-orange-50 transition-all"
>
<Inbox className="w-8 h-8 text-purple-500 mr-3" />
<div>
<p className="font-medium text-gray-900"></p>
<p className="text-sm text-gray-500"> </p>
</div>
</a>
</div>
</CardContent>
</Card>
{/* 안내 정보 */}
<Card className="bg-gradient-to-r from-orange-50 to-amber-50 border-orange-200 shadow-sm">
<CardHeader>
<CardTitle className="text-lg flex items-center">
<Mail className="w-5 h-5 mr-2 text-orange-500" />
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-700 mb-4">
💡 !
</p>
<ul className="space-y-2 text-sm text-gray-600">
<li className="flex items-start">
<span className="text-orange-500 mr-2"></span>
<span>SMTP </span>
</li>
<li className="flex items-start">
<span className="text-orange-500 mr-2"></span>
<span> 릿 </span>
</li>
<li className="flex items-start">
<span className="text-orange-500 mr-2"></span>
<span> SQL </span>
</li>
<li className="flex items-start">
<span className="text-orange-500 mr-2"></span>
<span> </span>
</li>
</ul>
</CardContent>
</Card>
</div>
</div>
);
}