import { formatDate, formatDateTime } from '@/lib/date'; import { CheckAssignmentCompletion, CheckSubjectCompletion } from '@/lib/progress'; import { getSubjectColorSet, type SubjectColor } from '@/lib/subjectColors'; import { supabase } from '@/lib/supabase'; import type { Assignment, Task } from '@/lib/types'; import { Session } from '@supabase/supabase-js'; import { router, Stack, useFocusEffect, useLocalSearchParams } from 'expo-router'; import { useCallback, useEffect, useState } from 'react'; import { Alert, Pressable, SectionList, Text, View } from "react-native"; export default function ViewDetailsAssignment() { const { aId } = useLocalSearchParams<{ aId: string }>(); const [assignment, SetAssignment] = useState(null); const [tasks, SetTasks] = useState([]); const [session, SetSession] = useState(null); const [subjectMeta, setSubjectMeta] = useState({ title: 'No Subject', color: 'slate' as SubjectColor, }); const taskSections = [ { title: "Upcoming Tasks", data: tasks.filter((task) => !task.isCompleted), emptyMessage: "No upcoming tasks" }, { title: "Completed Tasks", data: tasks.filter((task) => task.isCompleted), emptyMessage: "No completed tasks" }, ]; useEffect(() => { supabase.auth.getSession().then(({ data }) => SetSession(data.session ?? null)) const { data: sub } = supabase.auth.onAuthStateChange((_event, newSession) => { SetSession(newSession) }) return () => sub.subscription.unsubscribe() }, []) const GetAssignment = async (assignmentId: string) => { const { data, error } = await supabase .from('assignments') .select('*') .eq('aId', assignmentId) .single(); if (error || !data) { console.log('GetAssignment error:', error); Alert.alert('Assignment could not be fetched, please try again'); return; } SetAssignment(data); if (data.sId) { const { data: subjectData, error: subjectError } = await supabase .from('subjects') .select('title, color') .eq('sId', data.sId) .single(); if (subjectError || !subjectData) { console.log('GetSubjectMeta error:', subjectError); setSubjectMeta({ title: 'Unknown Subject', color: 'slate' }); return; } setSubjectMeta({ title: subjectData.title ?? 'Unknown Subject', color: (subjectData.color as SubjectColor | undefined) ?? 'slate' }); } }; const GetTasks = async (aId: string) => { const { data, error } = await supabase.from("tasks").select("*").eq("aId", aId); if (error) { Alert.alert("Tasks could not be fetched, please try again"); return; } SetTasks(data ?? []); } useFocusEffect( useCallback(() => { if (session && aId) { GetAssignment(aId); GetTasks(aId); } }, [session, aId]) ); const DeleteAssignment = async (aId: string) => { Alert.alert( "Delete Assignment", "Are you sure you want to delete this assignment?", [ { text: "Cancel", style: "cancel" }, { text: "Delete", style: "destructive", onPress: async () => { const { error } = await supabase.from("assignments").delete().eq("aId", aId); if (error) { Alert.alert("Assignment could not be deleted, please try again"); return; } Alert.alert("Assignment deleted successfully!"); const sId = assignment?.sId; if (sId) { try { await CheckSubjectCompletion(sId); } catch { Alert.alert("Failed to update subject status"); } } router.back(); } } ] ) } const DeleteTask = async (tId: string, aId: string) => { Alert.alert( "Delete Task", "Are you sure you want to delete this task?", [ { text: "Cancel", style: "cancel" }, { text: "Delete", style: "destructive", onPress: async () => { const { error } = await supabase.from("tasks").delete().eq("tId", tId); if (error) { Alert.alert("Task could not be deleted, please try again"); return; } Alert.alert("Task deleted successfully!"); if (aId) { try { await CheckAssignmentCompletion(aId); } catch { Alert.alert("Failed to update assignment completion state"); } } GetTasks(aId); } } ] ) } const colorSet = getSubjectColorSet(subjectMeta.color); const completedTasks = tasks.filter((task) => task.isCompleted).length; const totalTasks = tasks.length; const remainingTasks = totalTasks - completedTasks; const progress = totalTasks === 0 ? 0 : Math.round((completedTasks / totalTasks) * 100); if (!assignment) { return ( Assignment not found The assignment could not be loaded. router.back()} > Go back ); } return ( ( await supabase.auth.signOut()} > Logout ), }} /> item.tId} showsVerticalScrollIndicator={false} stickySectionHeadersEnabled={false} ListHeaderComponent={ {assignment.isCompleted && ( )} {assignment.title} {assignment.description ? ( {assignment.description} ) : null} {subjectMeta.title} Deadline: {formatDate(assignment.deadline) || 'No deadline'} Task Progress {completedTasks}/{totalTasks} {remainingTasks === 0 ? 'All tasks complete' : `${remainingTasks} task${remainingTasks === 1 ? '' : 's'} remaining`} Last changed: {formatDateTime(assignment.lastChanged)} router.push({ pathname: '/assignment/upsertAssignment', params: { aId: assignment.aId }, }) } > Edit DeleteAssignment(assignment.aId)} > Delete router.push({ pathname: '/task/createTask', params: { aId: assignment.aId }, }) } > Create Task } renderSectionHeader={({ section: { title, data } }) => ( {title} {data.length} )} renderItem={({ item }) => { const isOwner = session?.user.id === item.uId; return ( router.push({ pathname: '/task/viewDetailsTask', params: { tId: item.tId }, }) } > {item.isCompleted && ( )} {item.title} {item.description ? ( {item.description} ) : null} {isOwner && ( router.push({ pathname: '/task/editTask', params: { tId: item.tId }, }) } > Edit DeleteTask(item.tId, item.aId)} > Delete )} ); }} renderSectionFooter={({ section }) => section.data.length === 0 ? ( {section.emptyMessage} Tasks for this assignment will show up here. ) : ( ) } /> ); }