import React, { useState, useEffect } from 'react';
import { Calendar, Users, FileText, AlertCircle, CheckCircle, Clock, TrendingUp, Settings, Plus, Edit2, Trash2, Save, X, ChevronRight, Download, Upload } from 'lucide-react';
// 學生會工作管理系統
export default function StudentUnionSystem() {
const [currentPage, setCurrentPage] = useState('dashboard');
const [data, setData] = useState({
meetings: [],
events: [],
attendance: [],
proposals: [],
calendar: [],
workRecords: [],
announcements: [],
tripRecords: []
});
// 載入數據
useEffect(() => {
loadData();
}, []);
const loadData = async () => {
try {
const result = await window.storage.get('student-union-data');
if (result) {
setData(JSON.parse(result.value));
}
} catch (error) {
console.log('初次使用,創建新數據');
}
};
const saveData = async (newData) => {
setData(newData);
try {
await window.storage.set('student-union-data', JSON.stringify(newData));
} catch (error) {
console.error('保存數據失敗:', error);
}
};
const renderPage = () => {
switch (currentPage) {
case 'dashboard':
return ;
case 'meeting-attendance':
return ;
case 'event-booth':
return ;
case 'event-attendance':
return ;
case 'event-management':
return ;
case 'admin-process':
return ;
case 'calendar':
return ;
case 'trip-record':
return ;
case 'work-record':
return ;
case 'announcements':
return ;
default:
return ;
}
};
return (
{/* 頂部導航 */}
{/* 主要內容 */}
{renderPage()}
{/* 版權資訊 */}
);
}
// 儀表板
function Dashboard({ data, setCurrentPage }) {
const menuItems = [
{
id: 'meeting-attendance',
title: '開會點名紀錄',
description: '記錄會議出席狀況',
icon: Users,
color: 'from-blue-500 to-cyan-500',
count: data.meetings.length
},
{
id: 'event-booth',
title: '活動顧攤紀錄',
description: '記錄顧攤人員報到',
icon: CheckCircle,
color: 'from-green-500 to-emerald-500',
count: data.attendance.filter(a => a.type === 'booth').length
},
{
id: 'event-attendance',
title: '活動出席紀錄',
description: '記錄活動參與人員',
icon: Users,
color: 'from-purple-500 to-pink-500',
count: data.attendance.filter(a => a.type === 'event').length
},
{
id: 'event-management',
title: '活動紀錄表',
description: '從企劃到檢討完整流程',
icon: FileText,
color: 'from-orange-500 to-red-500',
count: data.events.length
},
{
id: 'admin-process',
title: '會內行政流程',
description: '提案審核流程管理',
icon: TrendingUp,
color: 'from-indigo-500 to-purple-500',
count: data.proposals.length
},
{
id: 'calendar',
title: '會內行事曆',
description: '統整所有行程',
icon: Calendar,
color: 'from-teal-500 to-green-500',
count: data.calendar.length
},
{
id: 'trip-record',
title: '出差紀錄表',
description: '記錄外出公務',
icon: FileText,
color: 'from-yellow-500 to-orange-500',
count: data.tripRecords.length
},
{
id: 'work-record',
title: '工作紀錄表',
description: '各部會工作記錄',
icon: Clock,
color: 'from-pink-500 to-rose-500',
count: data.workRecords.length
},
{
id: 'announcements',
title: '公告紀錄表',
description: '經費、規章、聲明',
icon: AlertCircle,
color: 'from-red-500 to-pink-500',
count: data.announcements.length
}
];
return (
歡迎使用學生會管理系統
選擇功能開始管理您的學生會工作
{menuItems.map((item) => {
const Icon = item.icon;
return (
);
})}
{/* 快速統計 */}
e.status === 'ongoing').length} icon={TrendingUp} color="green" />
p.status === 'pending').length} icon={FileText} color="yellow" />
new Date(c.date).getMonth() === new Date().getMonth()).length} icon={Calendar} color="purple" />
);
}
function StatCard({ title, value, icon: Icon, color }) {
const colors = {
blue: 'from-blue-500 to-cyan-500',
green: 'from-green-500 to-emerald-500',
yellow: 'from-yellow-500 to-orange-500',
purple: 'from-purple-500 to-pink-500'
};
return (
);
}
// 1. 開會點名紀錄
function MeetingAttendance({ data, saveData }) {
const [meetings, setMeetings] = useState(data.meetings);
const [showForm, setShowForm] = useState(false);
const [editingId, setEditingId] = useState(null);
const [formData, setFormData] = useState({
date: '',
title: '',
type: '例行會議',
attendees: [],
absentees: [],
notes: ''
});
const handleSubmit = (e) => {
e.preventDefault();
const newMeetings = editingId
? meetings.map(m => m.id === editingId ? { ...formData, id: editingId } : m)
: [...meetings, { ...formData, id: Date.now() }];
setMeetings(newMeetings);
saveData({ ...data, meetings: newMeetings });
resetForm();
};
const resetForm = () => {
setFormData({
date: '',
title: '',
type: '例行會議',
attendees: [],
absentees: [],
notes: ''
});
setShowForm(false);
setEditingId(null);
};
const handleDelete = (id) => {
const newMeetings = meetings.filter(m => m.id !== id);
setMeetings(newMeetings);
saveData({ ...data, meetings: newMeetings });
};
const handleEdit = (meeting) => {
setFormData(meeting);
setEditingId(meeting.id);
setShowForm(true);
};
return (
開會點名紀錄
{showForm && (
)}
{meetings.length === 0 ? (
) : (
meetings.map((meeting) => (
{meeting.title}
{meeting.type}
{meeting.date}
出席人員 ({meeting.attendees.length}人)
{meeting.attendees.map((name, idx) => (
{name}
))}
缺席人員 ({meeting.absentees.length}人)
{meeting.absentees.map((name, idx) => (
{name}
))}
{meeting.notes && (
)}
))
)}
);
}
// 2&3. 活動顧攤 & 出席紀錄(合併)
function EventBooth({ data, saveData }) {
return ;
}
function EventAttendance({ data, saveData }) {
return ;
}
function AttendanceRecord({ data, saveData, type, title }) {
const [records, setRecords] = useState(data.attendance.filter(a => a.type === type));
const [showForm, setShowForm] = useState(false);
const [formData, setFormData] = useState({
eventName: '',
date: '',
checkInTime: '',
checkOutTime: '',
attendees: []
});
const handleSubmit = (e) => {
e.preventDefault();
const newRecord = { ...formData, id: Date.now(), type };
const allAttendance = [...data.attendance, newRecord];
setRecords([...records, newRecord]);
saveData({ ...data, attendance: allAttendance });
resetForm();
};
const resetForm = () => {
setFormData({
eventName: '',
date: '',
checkInTime: '',
checkOutTime: '',
attendees: []
});
setShowForm(false);
};
const handleDelete = (id) => {
const newRecords = records.filter(r => r.id !== id);
const allAttendance = data.attendance.filter(a => a.id !== id);
setRecords(newRecords);
saveData({ ...data, attendance: allAttendance });
};
return