import React, { useState, useEffect } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; import axios from 'axios'; import { ArrowLeft, Users, Calendar, FileText, X, User, Save, Upload, Plus } from 'lucide-react'; import MDEditor from '@uiw/react-md-editor'; import '@uiw/react-md-editor/markdown-editor.css'; import { buildApiUrl, API_ENDPOINTS } from '../config/api'; import './EditMeeting.css'; const EditMeeting = ({ user }) => { const navigate = useNavigate(); const { meeting_id } = useParams(); const [formData, setFormData] = useState({ title: '', meeting_time: '', summary: '', attendees: [] }); const [availableUsers, setAvailableUsers] = useState([]); const [userSearch, setUserSearch] = useState(''); const [showUserDropdown, setShowUserDropdown] = useState(false); const [audioFile, setAudioFile] = useState(null); const [isLoading, setIsLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [isUploading, setIsUploading] = useState(false); const [error, setError] = useState(''); const [meeting, setMeeting] = useState(null); useEffect(() => { fetchMeetingData(); fetchUsers(); }, [meeting_id]); const fetchMeetingData = async () => { try { const response = await axios.get(buildApiUrl(API_ENDPOINTS.MEETINGS.EDIT(meeting_id))); const meetingData = response.data; // Check if current user is the creator if (meetingData.creator_id !== user.user_id) { navigate('/dashboard'); return; } setMeeting(meetingData); setFormData({ title: meetingData.title, meeting_time: meetingData.meeting_time ? new Date(meetingData.meeting_time).toISOString().slice(0, 16) : '', summary: meetingData.summary || '', attendees: meetingData.attendees || [] }); } catch (err) { setError('无法加载会议信息'); console.error('Error fetching meeting:', err); } finally { setIsLoading(false); } }; const fetchUsers = async () => { try { const response = await axios.get(buildApiUrl(API_ENDPOINTS.USERS.LIST)); setAvailableUsers(response.data.filter(u => u.user_id !== user.user_id)); } catch (err) { console.error('Error fetching users:', err); } }; const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; const handleAddAttendee = (selectedUser) => { if (!formData.attendees.find(a => a.user_id === selectedUser.user_id)) { setFormData(prev => ({ ...prev, attendees: [...prev.attendees, selectedUser] })); } setUserSearch(''); setShowUserDropdown(false); }; const handleRemoveAttendee = (userId) => { setFormData(prev => ({ ...prev, attendees: prev.attendees.filter(a => a.user_id !== userId) })); }; const handleFileChange = (e) => { const file = e.target.files[0]; if (file) { // Check file type - include both MIME types and extensions const allowedMimeTypes = ['audio/mp3', 'audio/wav', 'audio/m4a', 'audio/mpeg', 'audio/mp4', 'audio/x-m4a']; const fileExtension = file.name.toLowerCase().split('.').pop(); const allowedExtensions = ['mp3', 'wav', 'm4a', 'mpeg']; if (!allowedMimeTypes.includes(file.type) && !allowedExtensions.includes(fileExtension)) { setError('请上传支持的音频格式 (MP3, WAV, M4A)'); return; } // Check file size (max 100MB) if (file.size > 100 * 1024 * 1024) { setError('音频文件大小不能超过100MB'); return; } setAudioFile(file); setError(''); } }; const handleSubmit = async (e) => { e.preventDefault(); if (!formData.title.trim()) { setError('请输入会议标题'); return; } setIsSaving(true); setError(''); try { const updateData = { title: formData.title, meeting_time: formData.meeting_time || null, summary: formData.summary, attendee_ids: formData.attendees.map(a => a.user_id) }; await axios.put(buildApiUrl(API_ENDPOINTS.MEETINGS.UPDATE(meeting_id)), updateData); navigate(`/meetings/${meeting_id}`); } catch (err) { setError(err.response?.data?.detail || '更新会议失败,请重试'); } finally { setIsSaving(false); } }; const handleUploadAudio = async () => { if (!audioFile) { setError('请先选择音频文件'); return; } setIsUploading(true); setError(''); try { // Upload new audio file const formDataUpload = new FormData(); formDataUpload.append('audio_file', audioFile); formDataUpload.append('meeting_id', meeting_id); const response = await axios.post(buildApiUrl(API_ENDPOINTS.MEETINGS.UPLOAD_AUDIO), formDataUpload, { headers: { 'Content-Type': 'multipart/form-data', }, }); // Update summary with new AI analysis result if (response.data.summary) { setFormData(prev => ({ ...prev, summary: response.data.summary })); } setAudioFile(null); // Reset file input const fileInput = document.getElementById('audio-file'); if (fileInput) fileInput.value = ''; } catch (err) { setError('上传音频文件失败,请重试'); } finally { setIsUploading(false); } }; const filteredUsers = availableUsers.filter(user => { // Exclude users already selected as attendees const isAlreadySelected = formData.attendees.some(attendee => attendee.user_id === user.user_id); if (isAlreadySelected) return false; // Filter by search text return user.caption.toLowerCase().includes(userSearch.toLowerCase()) || user.username.toLowerCase().includes(userSearch.toLowerCase()); }); if (isLoading) { return (
加载中...
修改会议信息、参会人员和摘要内容