diff --git a/app/admin/dsoc/projects/[id]/edit/page.tsx b/app/admin/dsoc/projects/[id]/edit/page.tsx new file mode 100644 index 0000000..0293b7e --- /dev/null +++ b/app/admin/dsoc/projects/[id]/edit/page.tsx @@ -0,0 +1,519 @@ +'use client'; + +import Link from "next/link"; +import { useState, useEffect, use } from "react"; +import { useRouter } from "next/navigation"; +import { + ArrowLeft, + Save, + Plus, + Trash2, + AlertCircle +} from "lucide-react"; +import "../../../../../dsoc/styles.css"; + +export default function EditProjectPage({ params }: { params: Promise<{ id: string }> }) { + const resolvedParams = use(params); + const router = useRouter(); + const [loading, setLoading] = useState(true); + const [submitting, setSubmitting] = useState(false); + const [error, setError] = useState(''); + const [success, setSuccess] = useState(false); + + const [formData, setFormData] = useState({ + title: '', + description: '', + longDescription: '', + organization: '', + repositoryUrl: '', + websiteUrl: '', + difficulty: 'intermediate', + duration: '3 months', + technologies: '', + tags: '', + maxMentees: 3, + applicationDeadline: '', + startDate: '', + endDate: '', + requirements: [''], + learningOutcomes: [''], + season: '2025', + status: 'draft' + }); + + useEffect(() => { + fetchProject(); + }, [resolvedParams.id]); + + const fetchProject = async () => { + try { + const res = await fetch(`/api/dsoc/projects/${resolvedParams.id}`); + const data = await res.json(); + + if (data.success) { + const project = data.data; + setFormData({ + title: project.title || '', + description: project.description || '', + longDescription: project.longDescription || '', + organization: project.organization || '', + repositoryUrl: project.repositoryUrl || '', + websiteUrl: project.websiteUrl || '', + difficulty: project.difficulty || 'intermediate', + duration: project.duration || '3 months', + technologies: Array.isArray(project.technologies) ? project.technologies.join(', ') : '', + tags: Array.isArray(project.tags) ? project.tags.join(', ') : '', + maxMentees: project.maxMentees || 3, + applicationDeadline: project.applicationDeadline ? new Date(project.applicationDeadline).toISOString().split('T')[0] : '', + startDate: project.startDate ? new Date(project.startDate).toISOString().split('T')[0] : '', + endDate: project.endDate ? new Date(project.endDate).toISOString().split('T')[0] : '', + requirements: project.requirements && project.requirements.length > 0 ? project.requirements : [''], + learningOutcomes: project.learningOutcomes && project.learningOutcomes.length > 0 ? project.learningOutcomes : [''], + season: project.season || '2025', + status: project.status || 'draft' + }); + } else { + setError(data.error || 'Failed to load project'); + } + } catch (err) { + console.error('Error fetching project:', err); + setError('Failed to load project. Please try again.'); + } finally { + setLoading(false); + } + }; + + const handleChange = (e: React.ChangeEvent) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + + const handleArrayChange = (field: 'requirements' | 'learningOutcomes', index: number, value: string) => { + const updated = [...formData[field]]; + updated[index] = value; + setFormData({ ...formData, [field]: updated }); + }; + + const addArrayItem = (field: 'requirements' | 'learningOutcomes') => { + setFormData({ ...formData, [field]: [...formData[field], ''] }); + }; + + const removeArrayItem = (field: 'requirements' | 'learningOutcomes', index: number) => { + const updated = formData[field].filter((_, i) => i !== index); + setFormData({ ...formData, [field]: updated }); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(''); + setSuccess(false); + setSubmitting(true); + + try { + const res = await fetch(`/api/dsoc/projects/${resolvedParams.id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + title: formData.title, + description: formData.description, + longDescription: formData.longDescription, + organization: formData.organization, + repositoryUrl: formData.repositoryUrl, + websiteUrl: formData.websiteUrl, + difficulty: formData.difficulty, + duration: formData.duration, + technologies: formData.technologies.split(',').map(s => s.trim()).filter(Boolean), + tags: formData.tags.split(',').map(s => s.trim()).filter(Boolean), + maxMentees: parseInt(formData.maxMentees as unknown as string), + applicationDeadline: formData.applicationDeadline, + startDate: formData.startDate, + endDate: formData.endDate, + requirements: formData.requirements.filter(Boolean), + learningOutcomes: formData.learningOutcomes.filter(Boolean), + season: formData.season, + status: formData.status + }) + }); + + const data = await res.json(); + + if (data.success) { + setSuccess(true); + setTimeout(() => { + router.push('/admin/dsoc'); + }, 1500); + } else { + setError(data.error || 'Failed to update project'); + } + } catch (err) { + console.error('Error updating project:', err); + setError('Something went wrong. Please try again.'); + } finally { + setSubmitting(false); + } + }; + + if (loading) { + return ( +
+
+
+

Loading project...

+
+
+ ); + } + + return ( +
+
+
+ + + Back to DSOC Admin + + +
+

Edit Project

+ +
+ {error && ( +
+ + {error} +
+ )} + + {success && ( +
+ ✓ Project updated successfully! Redirecting... +
+ )} + + {/* Basic Info */} +
+

Basic Information

+ +
+ + +
+ +
+ + +
+ +
+ +