import { useState, useEffect } from 'react'; import api from '../services/api'; import Modal from '../components/Modal'; import ConfirmDialog from '../components/ConfirmDialog'; import EmptyState from '../components/EmptyState'; import { TableSkeleton } from '../components/LoadingSkeleton'; import PersianDateInput from '../components/PersianDateInput'; import toast from 'react-hot-toast'; import { Calendar, Edit3, Trash2, X, ArrowLeft } from 'lucide-react'; import { formatJalaliDate, todayIsoDate } from '../utils/date'; import { Link } from 'react-router-dom'; export default function MeetingList() { const [meetings, setMeetings] = useState([]); const [loading, setLoading] = useState(true); const [projects, setProjects] = useState([]); const [users, setUsers] = useState([]); const [filters, setFilters] = useState({ project_id: '', meeting_type: '' }); const [showModal, setShowModal] = useState(false); const [editing, setEditing] = useState(null); const [deleting, setDeleting] = useState(null); const [saving, setSaving] = useState(false); const [selected, setSelected] = useState(null); const [meta, setMeta] = useState({}); const [page, setPage] = useState(1); const [form, setForm] = useState({ title: '', date: '', start_time: '', end_time: '', meeting_type: 'online', location: '', meeting_link: '', project_id: '', agenda: '', notes: '', decisions: '' }); const [actionForm, setActionForm] = useState({ title: '', assigned_to: '', due_date: '' }); const fetchMeetings = () => { setLoading(true); const params = { page, per_page: 15 }; if (filters.project_id) params.project_id = filters.project_id; if (filters.meeting_type) params.meeting_type = filters.meeting_type; api.get('/meetings', { params }).then(({ data }) => { setMeetings(data.data || []); setMeta(data.meta || {}); }).catch(() => toast.error('خطا')).finally(() => setLoading(false)); }; useEffect(() => { fetchMeetings(); }, [page, filters]); useEffect(() => { api.get('/projects', { params: { per_page: 100 } }).then(({ data }) => setProjects(data.data || [])).catch(() => {}); api.get('/users', { params: { per_page: 100 } }).then(({ data }) => setUsers(data.data || [])).catch(() => {}); }, []); const openCreate = () => { setEditing(null); setForm({ title: '', date: todayIsoDate(), start_time: '', end_time: '', meeting_type: 'online', location: '', meeting_link: '', project_id: '', agenda: '', notes: '', decisions: '' }); setShowModal(true); }; const openEdit = (m) => { setEditing(m); setForm({ title: m.title, date: m.date?.slice(0, 10) || '', start_time: m.start_time || '', end_time: m.end_time || '', meeting_type: m.meeting_type, location: m.location || '', meeting_link: m.meeting_link || '', project_id: m.project_id || '', agenda: m.agenda || '', notes: m.notes || '', decisions: m.decisions || '', }); setShowModal(true); }; const handleSave = async (e) => { e.preventDefault(); if (!form.title || !form.date) { toast.error('عنوان و تاریخ الزامی است'); return; } setSaving(true); try { if (editing) { await api.put(`/meetings/${editing.id}`, { ...form, _method: 'PUT' }); toast.success('بهروزرسانی شد'); } else { await api.post('/meetings', form); toast.success('ایجاد شد'); } setShowModal(false); fetchMeetings(); } catch (err) { toast.error(err.response?.data?.message || 'خطا'); } finally { setSaving(false); } }; const handleDelete = async () => { try { await api.delete(`/meetings/${deleting.id}`); toast.success('حذف شد'); setDeleting(null); fetchMeetings(); } catch { toast.error('خطا'); } }; const viewDetail = async (m) => { try { const { data } = await api.get(`/meetings/${m.id}`); setSelected(data.data); } catch { toast.error('خطا'); } }; const addParticipant = async (userId) => { try { await api.post(`/meetings/${selected.id}/participants`, { user_id: userId }); toast.success('شرکتکننده اضافه شد'); viewDetail(selected); } catch { toast.error('خطا'); } }; const removeParticipant = async (userId) => { try { await api.delete(`/meetings/${selected.id}/participants/${userId}`); toast.success('شرکتکننده حذف شد'); viewDetail(selected); } catch { toast.error('خطا'); } }; const addActionItem = async () => { if (!actionForm.title.trim()) { toast.error('عنوان الزامی است'); return; } try { await api.post(`/meetings/${selected.id}/action-items`, actionForm); toast.success('ایتم اقدام اضافه شد'); setActionForm({ title: '', assigned_to: '', due_date: '' }); viewDetail(selected); } catch { toast.error('خطا'); } }; const toggleActionItem = async (item) => { try { await api.put(`/meetings/${selected.id}/action-items/${item.id}`, { is_completed: !item.is_completed }); viewDetail(selected); } catch { toast.error('خطا'); } }; const convertToTask = async (item) => { try { await api.post(`/meetings/${selected.id}/action-items/${item.id}/convert-to-task`, { project_id: selected.project_id || 1 }); toast.success('به تسک تبدیل شد'); viewDetail(selected); } catch { toast.error('خطا'); } }; return (
| عنوان | پروژه | نوع | تاریخ | ساعت | شرکتکنندگان | عملیات |
|---|---|---|---|---|---|---|
| {m.title} | {m.project?.title || '—'} | {m.meeting_type === 'online' ? 'آنلاین' : m.meeting_type === 'in_person' ? 'حضوری' : 'ترکیبی'} | {formatJalaliDate(m.date)} | {m.start_time || '—'} {m.end_time ? `- ${m.end_time}` : ''} | {m.participants_count ?? m.participants?.length ?? 0} |
e.stopPropagation()}>
|
{selected.agenda}
{selected.notes}
{selected.decisions}