diff --git a/frontend/src/pages/admin/_auth/_appshell/projects/$projectId.decision.tsx b/frontend/src/pages/admin/_auth/_appshell/projects/$projectId.decision.tsx index b74bb4be..efed4592 100644 --- a/frontend/src/pages/admin/_auth/_appshell/projects/$projectId.decision.tsx +++ b/frontend/src/pages/admin/_auth/_appshell/projects/$projectId.decision.tsx @@ -3,165 +3,198 @@ import { useEffect, useState } from 'react'; import { FiCheck, FiX, FiAlertCircle } from 'react-icons/fi'; import { useAuth } from '@/contexts/AuthContext'; import { useNotification } from '@/contexts/NotificationContext'; -import { getProject, updateProjectStatus } from '@/services/projects'; +import { + getProject, + ProjectStatusEnum, + updateProjectStatus, +} from '@/services/projects'; -export const Route = createFileRoute('/admin/_auth/_appshell/projects/$projectId/decision')({ - component: ProjectDecisionPage, +export const Route = createFileRoute( + '/admin/_auth/_appshell/projects/$projectId/decision' +)({ + component: ProjectDecisionPage, }); function ProjectDecisionPage() { - const { projectId } = Route.useParams(); - const { accessToken } = useAuth(); - const { push } = useNotification(); - const navigate = useNavigate(); - const [loading, setLoading] = useState(true); - const [submitting, setSubmitting] = useState(false); - const [projectName, setProjectName] = useState(''); - const [selectedStatus, setSelectedStatus] = useState<'approved' | 'needs_revisions' | 'rejected'>(); + const { projectId } = Route.useParams(); + const { accessToken } = useAuth(); + const { push } = useNotification(); + const navigate = useNavigate(); + const [loading, setLoading] = useState(true); + const [submitting, setSubmitting] = useState(false); + const [projectName, setProjectName] = useState(''); + const [selectedStatus, setSelectedStatus] = useState(); - useEffect(() => { - async function loadProject() { - if (!accessToken || !projectId) return; + useEffect(() => { + async function loadProject() { + if (!accessToken || !projectId) return; - try { - const project = await getProject(accessToken, projectId); - setProjectName(project.title); - } catch (error) { - console.error('Failed to load project:', error); - push({ - message: 'Failed to load project details', - level: 'error' - }); - } finally { - setLoading(false); - } - } + try { + const project = await getProject(accessToken, projectId); + setProjectName(project.title); + } catch (error) { + console.error('Failed to load project:', error); + push({ + message: 'Failed to load project details', + level: 'error', + }); + } finally { + setLoading(false); + } + } + + loadProject(); + }, [accessToken, projectId, push]); - loadProject(); - }, [accessToken, projectId, push]); + const handleSubmit = async () => { + if (!selectedStatus || !accessToken || !projectId) return; - const handleSubmit = async () => { - if (!selectedStatus || !accessToken || !projectId) return; + try { + setSubmitting(true); + await updateProjectStatus(accessToken, projectId, selectedStatus); + push({ + message: 'Project status updated successfully', + level: 'success', + }); + navigate({ to: '/admin/dashboard' }); + } catch (error) { + console.error('Failed to update project status:', error); + push({ + message: 'Failed to update project status', + level: 'error', + }); + } finally { + setSubmitting(false); + } + }; - try { - setSubmitting(true); - await updateProjectStatus(accessToken, projectId, selectedStatus); - push({ - message: 'Project status updated successfully', - level: 'success' - }); - navigate({ to: '/admin/projects' }); - } catch (error) { - console.error('Failed to update project status:', error); - push({ - message: 'Failed to update project status', - level: 'error' - }); - } finally { - setSubmitting(false); + if (loading) { + return ( +
+

Loading project details...

+
+ ); } - }; - if (loading) { return ( -
-

Loading project details...

-
- ); - } +
+
+

+ Reviewing Project: {projectName} +

+

Submitted on Nov 8, 2024

+
- return ( -
-
-

Reviewing Project: {projectName}

-

Submitted on Nov 8, 2024

-
+
+

Project Status

+

+ Select the final status for this project. This action will + notify the project team. +

-
-

Project Status

-

- Select the final status for this project. This action will notify the project team. -

+
+ -
- + - -
+ ); +} -
- - -
-
- ); -} \ No newline at end of file diff --git a/frontend/src/services/projects.ts b/frontend/src/services/projects.ts index dd0f936d..fc2d362e 100644 --- a/frontend/src/services/projects.ts +++ b/frontend/src/services/projects.ts @@ -79,7 +79,9 @@ export async function getProjectDocuments( const json = await res.json(); return { - documents: (json.documents || []).map((doc: any) => snakeToCamel(doc) as DocumentResponse) + documents: (json.documents || []).map( + (doc: any) => snakeToCamel(doc) as DocumentResponse + ), }; } @@ -102,14 +104,24 @@ export async function getProjectComments( const json = await res.json(); return { - comments: (json.comments || []).map((comment: any) => snakeToCamel(comment) as CommentResponse) + comments: (json.comments || []).map( + (comment: any) => snakeToCamel(comment) as CommentResponse + ), }; } +export enum ProjectStatusEnum { + Draft = 'draft', + Pending = 'pending', + Verified = 'verified', + Declined = 'declined', + Withdrawn = 'withdrawn', +} + export async function updateProjectStatus( accessToken: string, projectId: string, - status: 'approved' | 'needs_revisions' | 'rejected' + status: ProjectStatusEnum ): Promise { const url = getApiUrl(`/project/${projectId}/status`); const res = await fetch(url, { @@ -122,6 +134,11 @@ export async function updateProjectStatus( }); if (res.status !== HttpStatusCode.OK) { - throw new ApiError('Failed to update project status', res.status, await res.json()); + throw new ApiError( + 'Failed to update project status', + res.status, + await res.json() + ); } -} \ No newline at end of file +} +