"use client" import { useState, useEffect } from "react" import Link from "next/link" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Download, Eye, Users, Heart, FileText, BarChart3, RefreshCw, Search, Filter, ArrowLeft, Sparkles, Settings, Plus, ChevronLeft, ChevronRight } from "lucide-react" import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import HeaderMusicControl from "@/components/header-music-control" import IpDisplay from "@/components/ip-display" interface WishData { id: number title: string current_pain: string expected_solution: string expected_effect: string is_public: boolean email: string images: any[] user_session: string status: string category: string priority: number like_count: number created_at: string updated_at: string } interface AdminStats { totalWishes: number publicWishes: number privateWishes: number totalLikes: number categories: { [key: string]: number } recentWishes: number } export default function AdminPage() { const [wishes, setWishes] = useState([]) const [filteredWishes, setFilteredWishes] = useState([]) const [stats, setStats] = useState(null) const [loading, setLoading] = useState(true) const [searchTerm, setSearchTerm] = useState("") const [statusFilter, setStatusFilter] = useState("all") const [visibilityFilter, setVisibilityFilter] = useState("all") const [isExporting, setIsExporting] = useState(false) // 分頁狀態 const [currentPage, setCurrentPage] = useState(1) const itemsPerPage = 10 // 獲取所有數據 const fetchData = async () => { try { setLoading(true) // 獲取困擾案例數據 const wishesResponse = await fetch('/api/admin/wishes') const wishesResult = await wishesResponse.json() if (wishesResult.success) { setWishes(wishesResult.data) setFilteredWishes(wishesResult.data) } // 獲取統計數據 const statsResponse = await fetch('/api/admin/stats') const statsResult = await statsResponse.json() if (statsResult.success) { setStats(statsResult.data) } } catch (error) { console.error('獲取數據失敗:', error) } finally { setLoading(false) } } // 過濾數據 const filterData = () => { let filtered = wishes // 搜索過濾 if (searchTerm) { filtered = filtered.filter(wish => wish.title.toLowerCase().includes(searchTerm.toLowerCase()) || wish.current_pain.toLowerCase().includes(searchTerm.toLowerCase()) || wish.expected_solution.toLowerCase().includes(searchTerm.toLowerCase()) ) } // 狀態過濾 if (statusFilter !== "all") { filtered = filtered.filter(wish => wish.status === statusFilter) } // 可見性過濾 if (visibilityFilter !== "all") { filtered = filtered.filter(wish => visibilityFilter === "public" ? wish.is_public : !wish.is_public ) } setFilteredWishes(filtered) setCurrentPage(1) // 重置到第一頁 } // 分頁計算 const totalPages = Math.ceil(filteredWishes.length / itemsPerPage) const startIndex = (currentPage - 1) * itemsPerPage const endIndex = startIndex + itemsPerPage const currentWishes = filteredWishes.slice(startIndex, endIndex) // 分頁組件 const PaginationComponent = () => { if (totalPages <= 1) return null const getPageNumbers = () => { const pages = [] const maxVisiblePages = 5 if (totalPages <= maxVisiblePages) { for (let i = 1; i <= totalPages; i++) { pages.push(i) } } else { if (currentPage <= 3) { for (let i = 1; i <= 4; i++) { pages.push(i) } pages.push('...') pages.push(totalPages) } else if (currentPage >= totalPages - 2) { pages.push(1) pages.push('...') for (let i = totalPages - 3; i <= totalPages; i++) { pages.push(i) } } else { pages.push(1) pages.push('...') for (let i = currentPage - 1; i <= currentPage + 1; i++) { pages.push(i) } pages.push('...') pages.push(totalPages) } } return pages } return (
顯示第 {startIndex + 1} - {Math.min(endIndex, filteredWishes.length)} 筆,共 {filteredWishes.length} 筆
{getPageNumbers().map((page, index) => ( ))}
) } // 匯出 CSV const exportToCSV = async () => { try { setIsExporting(true) const response = await fetch('/api/admin/export-csv', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ data: filteredWishes, filename: `困擾案例數據_${new Date().toISOString().split('T')[0]}.csv` }) }) if (response.ok) { const blob = await response.blob() const url = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `困擾案例數據_${new Date().toISOString().split('T')[0]}.csv` document.body.appendChild(a) a.click() window.URL.revokeObjectURL(url) document.body.removeChild(a) } else { throw new Error('匯出失敗') } } catch (error) { console.error('匯出 CSV 失敗:', error) alert('匯出失敗,請稍後再試') } finally { setIsExporting(false) } } useEffect(() => { fetchData() }, []) useEffect(() => { filterData() }, [searchTerm, statusFilter, visibilityFilter, wishes]) if (loading) { return (

載入中...

) } return (
{/* 星空背景 */}
{/* Header */}
{/* Logo 區域 */}

資訊部.心願星河

{/* 導航區域 */}
{/* 主要內容 */}
{/* 標題區域 */}

後台管理系統

困擾案例數據管理與分析

{/* 統計卡片 */} {stats && (
總案例數
{stats.totalWishes}

公開 {stats.publicWishes} + 私密 {stats.privateWishes}

總點讚數
{stats.totalLikes}

用戶支持總數

問題領域
{Object.keys(stats.categories).length}

不同類別

本週新增
{stats.recentWishes}

最近7天

)} {/* 主要內容區域 */} 數據管理 數據分析 {/* 搜索和過濾區域 */} 數據篩選 搜索和過濾困擾案例數據
setSearchTerm(e.target.value)} className="pl-10 bg-slate-700/50 border-slate-600/50 text-white placeholder:text-blue-300 focus:border-cyan-400/50" />
{/* 數據表格 */} 困擾案例列表 共 {filteredWishes.length} 筆數據
{currentWishes.map((wish) => ( ))}
ID 標題 狀態 可見性 點讚數 創建時間 操作
{wish.id} {wish.title} {wish.status === 'active' ? '活躍' : '非活躍'} {wish.is_public ? '公開' : '私密'} {wish.like_count} {new Date(wish.created_at).toLocaleDateString('zh-TW')}
{/* 分頁組件 */}
數據分析 困擾案例統計與分析
{/* 類別分布 */}

問題類別分布

{stats && Object.entries(stats.categories).map(([category, count]) => (
{category} {count}
))}
{/* 時間分布 */}

創建時間分布

{stats?.recentWishes}
最近7天新增
{stats?.totalWishes}
總案例數
) }