diff --git a/app/(tabs)/assignments.tsx b/app/(tabs)/assignments.tsx
index 69190ab..8fb9f77 100644
--- a/app/(tabs)/assignments.tsx
+++ b/app/(tabs)/assignments.tsx
@@ -1,4 +1,5 @@
import { defaultStyles } from '@/constants/defaultStyles';
+import { CheckSubjectCompletion } from '@/lib/progress';
import { supabase } from '@/lib/supabase';
import type { Assignment, Task } from '@/lib/types';
import { Ionicons } from '@expo/vector-icons';
@@ -97,7 +98,7 @@ export default function Assignments() {
}, [session])
);
- const DeleteAssignment = async (aId: string) => {
+ const DeleteAssignment = async (aId: string, sId: string) => {
Alert.alert(
'Delete Assignment',
'Are you sure you want to delete this assignment?',
@@ -121,6 +122,13 @@ export default function Assignments() {
}
Alert.alert('Assignment deleted successfully!');
+
+ try {
+ await CheckSubjectCompletion(sId);
+ } catch {
+ Alert.alert("Failed to update subject status");
+ }
+
GetAssignments();
},
},
@@ -296,7 +304,7 @@ export default function Assignments() {
DeleteAssignment(item.aId)}
+ onPress={() => DeleteAssignment(item.aId, item.sId)}
>
Delete
diff --git a/app/(tabs)/subjects.tsx b/app/(tabs)/subjects.tsx
index 323d021..f5f5f79 100644
--- a/app/(tabs)/subjects.tsx
+++ b/app/(tabs)/subjects.tsx
@@ -1,6 +1,6 @@
import { defaultStyles } from '@/constants/defaultStyles';
import { supabase } from '@/lib/supabase';
-import type { Subject } from '@/lib/types';
+import type { Assignment, Subject } from '@/lib/types';
import { Ionicons } from '@expo/vector-icons';
import { Session } from '@supabase/supabase-js';
import { router, Stack, useFocusEffect } from 'expo-router';
@@ -15,6 +15,7 @@ import {
export default function Subjects() {
const [subjects, SetSubjects] = useState([]);
+ const [assignmentsBySubject, SetAssignmentsBySubject] = useState>({});
const [session, SetSession] = useState(null);
const subjectSections = [
@@ -45,17 +46,47 @@ export default function Subjects() {
}, []);
const GetSubjects = async () => {
- const { data, error } = await supabase
+ const { data: subjectsData, error: subjectsError } = await supabase
.from('subjects')
.select('*')
.order('lastChanged', { ascending: false });
- if (error) {
+ if (subjectsError) {
Alert.alert('Subjects could not be fetched, please try again');
return;
}
- SetSubjects(data ?? []);
+ const subjectRows = subjectsData ?? [];
+ SetSubjects(subjectsData ?? []);
+
+ if (subjectRows.length === 0) {
+ SetAssignmentsBySubject({});
+ return;
+ }
+
+ const sIds = subjectRows.map((subject) => subject.sId);
+
+ const { data: assignmentsData, error: assignmentsError } = await supabase
+ .from('assignments')
+ .select('*')
+ .in('sId', sIds);
+
+ if (assignmentsError) {
+ Alert.alert('Subject assignments could not be fetched, please try again');
+ SetAssignmentsBySubject({});
+ return;
+ }
+
+ const groupedAssignments: Record = {};
+
+ for (const assignment of assignmentsData ?? []) {
+ if (!groupedAssignments[assignment.sId]) {
+ groupedAssignments[assignment.sId] = [];
+ }
+ groupedAssignments[assignment.sId].push(assignment);
+ }
+
+ SetAssignmentsBySubject(groupedAssignments);
};
useFocusEffect(
@@ -169,6 +200,9 @@ export default function Subjects() {
renderItem={({ item }) => {
const isOwner = session?.user.id === item.uId;
+ const subjectAssignments = assignmentsBySubject[item.sId] ?? [];
+ const progress = subjectAssignments.length === 0 ? 0 : Math.round((subjectAssignments.filter(assignment => assignment.isCompleted).length / subjectAssignments.length) * 100);
+
return (
+
+ {progress}%
+
+
+
+
+
diff --git a/app/(tabs)/tasks.tsx b/app/(tabs)/tasks.tsx
index 6b204e4..7e08755 100644
--- a/app/(tabs)/tasks.tsx
+++ b/app/(tabs)/tasks.tsx
@@ -1,4 +1,5 @@
import { defaultStyles } from '@/constants/defaultStyles';
+import { CheckAssignmentCompletion } from '@/lib/progress';
import { supabase } from '@/lib/supabase';
import type { Task } from '@/lib/types';
import { Ionicons } from '@expo/vector-icons';
@@ -63,7 +64,7 @@ export default function Tasks() {
}, [session])
);
- const DeleteTask = async (tId: string) => {
+ const DeleteTask = async (tId: string, aId: string) => {
Alert.alert(
'Delete Task',
'Are you sure you want to delete this task?',
@@ -87,6 +88,13 @@ export default function Tasks() {
}
Alert.alert('Task deleted successfully!');
+
+ try {
+ await CheckAssignmentCompletion(aId);
+ } catch {
+ Alert.alert("Failed to update assignment completion state");
+ }
+
GetTasks();
},
},
@@ -237,7 +245,7 @@ export default function Tasks() {
DeleteTask(item.tId)}
+ onPress={() => DeleteTask(item.tId, item.aId)}
>
Delete
diff --git a/app/assignment/createAssignment.tsx b/app/assignment/createAssignment.tsx
index 68be4c6..f377cb0 100644
--- a/app/assignment/createAssignment.tsx
+++ b/app/assignment/createAssignment.tsx
@@ -1,5 +1,6 @@
import { defaultStyles } from '@/constants/defaultStyles';
import * as AsyncStorage from '@/lib/asyncStorage';
+import { CheckSubjectCompletion } from '@/lib/progress';
import { supabase } from '@/lib/supabase';
import * as Notifications from 'expo-notifications';
import { router, Stack, useLocalSearchParams } from 'expo-router';
@@ -93,6 +94,14 @@ export default function CreateAssignment() {
}
}
+ if (sId) {
+ try {
+ await CheckSubjectCompletion(sId);
+ } catch {
+ Alert.alert("Failed to update subject status");
+ }
+ }
+
SetTitle('');
SetDescription('');
SetDeadline('');
diff --git a/app/assignment/editAssignment.tsx b/app/assignment/editAssignment.tsx
index 76e0348..7115942 100644
--- a/app/assignment/editAssignment.tsx
+++ b/app/assignment/editAssignment.tsx
@@ -1,5 +1,6 @@
import { defaultStyles } from '@/constants/defaultStyles';
import { GetAssignmentNotificationId, RemoveAssignmentNotificationId, SaveAssignmentNotificationId } from '@/lib/asyncStorage';
+import { CheckSubjectCompletion } from '@/lib/progress';
import { supabase } from '@/lib/supabase';
import type { Assignment } from '@/lib/types';
import * as Notifications from 'expo-notifications';
@@ -115,6 +116,14 @@ export default function EditAssignment() {
}
}
+ if (assignmentData.sId) {
+ try {
+ await CheckSubjectCompletion(assignmentData.sId);
+ } catch {
+ Alert.alert("Failed to update subject status");
+ }
+ }
+
router.back();
}
diff --git a/app/assignment/viewDetailsAssignment.tsx b/app/assignment/viewDetailsAssignment.tsx
index 99a97d4..e7dc364 100644
--- a/app/assignment/viewDetailsAssignment.tsx
+++ b/app/assignment/viewDetailsAssignment.tsx
@@ -1,4 +1,5 @@
import { defaultStyles } from '@/constants/defaultStyles';
+import { CheckAssignmentCompletion, CheckSubjectCompletion } from '@/lib/progress';
import { supabase } from '@/lib/supabase';
import type { Assignment, Task } from '@/lib/types';
import { Session } from '@supabase/supabase-js';
@@ -78,6 +79,17 @@ export default function ViewDetailsAssignment() {
}
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();
}
}
@@ -106,6 +118,15 @@ export default function ViewDetailsAssignment() {
}
Alert.alert("Task deleted successfully!");
+
+ if (aId) {
+ try {
+ await CheckAssignmentCompletion(aId);
+ } catch {
+ Alert.alert("Failed to update assignment completion state");
+ }
+ }
+
GetTasks(aId);
}
}
@@ -153,9 +174,10 @@ export default function ViewDetailsAssignment() {
{assignment.isCompleted && ✓}
-
+ {assignment.lastChanged}
+
{progress}%
-
+
- {assignment.lastChanged}