diff --git a/app/assignment/_layout.tsx b/app/assignment/_layout.tsx
index 87149d5..7fb96ef 100644
--- a/app/assignment/_layout.tsx
+++ b/app/assignment/_layout.tsx
@@ -3,9 +3,7 @@ import { Stack } from "expo-router";
export default function AssignmentLayout() {
return (
-
-
-
+
);
diff --git a/app/assignment/assignments.tsx b/app/assignment/assignments.tsx
deleted file mode 100644
index 8fb9f77..0000000
--- a/app/assignment/assignments.tsx
+++ /dev/null
@@ -1,336 +0,0 @@
-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';
-import { Session } from '@supabase/supabase-js';
-import { router, Stack, useFocusEffect } from 'expo-router';
-import { useCallback, useEffect, useState } from 'react';
-import {
- Alert,
- Pressable,
- SectionList,
- Text,
- View,
-} from 'react-native';
-
-export default function Assignments() {
- const [assignments, SetAssignments] = useState([]);
- const [tasksByAssignment, SetTasksByAssignment] = useState>({});
- const [session, SetSession] = useState(null);
-
- const assignmentSections = [
- {
- title: 'Upcoming Assignments',
- data: assignments.filter((assignment) => !assignment.isCompleted),
- emptyMessage: 'No upcoming assignments',
- },
- {
- title: 'Completed Assignments',
- data: assignments.filter((assignment) => assignment.isCompleted),
- emptyMessage: 'No completed assignments',
- },
- ];
-
- 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 GetAssignments = async () => {
- const { data: assignmentsData, error: assignmentsError } = await supabase
- .from('assignments')
- .select('*')
- .order('deadline', { ascending: false });
-
- if (assignmentsError) {
- Alert.alert('Assignments could not be fetched, please try again');
- return;
- }
-
- const assignmentRows = assignmentsData ?? [];
- SetAssignments(assignmentRows);
-
- if (assignmentRows.length === 0) {
- SetTasksByAssignment({});
- return;
- }
-
- const aIds = assignmentRows.map((assignment) => assignment.aId);
-
- const { data: tasksData, error: tasksError } = await supabase
- .from('tasks')
- .select('*')
- .in('aId', aIds);
-
- if (tasksError) {
- Alert.alert('Assignment tasks could not be fetched, please try again');
- SetTasksByAssignment({});
- return;
- }
-
- const groupedTasks: Record = {};
-
- for (const task of tasksData ?? []) {
- if (!groupedTasks[task.aId]) {
- groupedTasks[task.aId] = [];
- }
- groupedTasks[task.aId].push(task);
- }
-
- SetTasksByAssignment(groupedTasks);
- };
-
- useFocusEffect(
- useCallback(() => {
- if (session) {
- GetAssignments();
- }
- }, [session])
- );
-
- const DeleteAssignment = async (aId: string, sId: 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!');
-
- try {
- await CheckSubjectCompletion(sId);
- } catch {
- Alert.alert("Failed to update subject status");
- }
-
- GetAssignments();
- },
- },
- ]
- );
- };
-
- return (
-
- (
-
-
-
-
-
- await supabase.auth.signOut()}
- >
-
- Logout
-
-
-
- ),
- }}
- />
-
-
-
-
- Assignments
-
-
- Track what is coming up and what you have already finished.
-
-
-
- router.push('/assignment/createAssignment')}
- >
-
- Create Assignment
-
-
-
- item.aId}
- showsVerticalScrollIndicator={false}
- stickySectionHeadersEnabled={false}
- contentContainerStyle={{
- paddingBottom: 32,
- }}
- renderSectionHeader={({ section: { title, data } }) => (
-
-
- {title}
-
-
-
-
- {data.length}
-
-
-
- )}
- renderItem={({ item }) => {
- const isOwner = session?.user.id === item.uId;
-
- const assignmentTasks = tasksByAssignment[item.aId] ?? [];
- const progress = assignmentTasks.length === 0 ? 0 : Math.round((assignmentTasks.filter(task => task.isCompleted).length / assignmentTasks.length) * 100);
-
- return (
-
-
- router.push({
- pathname: '/assignment/viewDetailsAssignment',
- params: { aId: item.aId },
- })
- }
- >
-
-
- {item.isCompleted && (
-
- ✓
-
- )}
-
-
-
-
- {item.title}
-
-
- {item.description ? (
-
- {item.description}
-
- ) : null}
-
-
-
- Deadline: {item.deadline || 'No deadline'}
-
-
-
-
- {progress}%
-
-
-
-
-
-
-
-
-
- {isOwner && (
-
-
- router.push({
- pathname: '/assignment/editAssignment',
- params: { aId: item.aId },
- })
- }
- >
-
- Edit
-
-
-
- DeleteAssignment(item.aId, item.sId)}
- >
-
- Delete
-
-
-
- )}
-
- );
- }}
- renderSectionFooter={({ section }) =>
- section.data.length === 0 ? (
-
-
- {section.emptyMessage}
-
-
- New assignments will show up here.
-
-
- ) : (
-
- )
- }
- />
-
-
- );
-}
\ No newline at end of file
diff --git a/app/assignment/editAssignment.tsx b/app/assignment/editAssignment.tsx
deleted file mode 100644
index 7115942..0000000
--- a/app/assignment/editAssignment.tsx
+++ /dev/null
@@ -1,192 +0,0 @@
-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';
-import { router, Stack, useFocusEffect, useLocalSearchParams } from 'expo-router';
-import { useCallback, useState } from 'react';
-import { ActivityIndicator, Alert, Button, Keyboard, KeyboardAvoidingView, Platform, Pressable, Text, TextInput, TouchableWithoutFeedback, View } from 'react-native';
-
-export default function EditAssignment() {
- const { aId } = useLocalSearchParams<{ aId: string }>();
- const [assignment, SetAssignment] = useState(null)
- const [isSaving, SetIsSaving] = useState(false);
-
- const ScheduleDeadlineReminder = async (aId: string, title: string, deadline: string) => {
- const dl = new Date(deadline);
-
- if (isNaN(dl.getTime())) return null;
-
- const deadlineReminder = new Date(dl.getTime() - 24 * 60 * 60 * 1000);
-
- if (deadlineReminder <= new Date()) return null;
-
- const nId = await Notifications.scheduleNotificationAsync({
- content: {
- title: 'Assignment deadline coming up',
- body: `${title} is due in 24 hours.`,
- data: { aId },
- },
- trigger: {
- type: Notifications.SchedulableTriggerInputTypes.DATE,
- date: deadlineReminder,
- },
- });
-
- return nId;
- }
-
- const CancelDeadlineReminder = async (aId: string) => {
- const nId = await GetAssignmentNotificationId(aId);
-
- if (!nId) return;
-
- await Notifications.cancelScheduledNotificationAsync(nId);
- await RemoveAssignmentNotificationId(aId);
- }
-
- const GetAssignment = async (aId: string) => {
- const { data, error } = await supabase.from("assignments").select("*").eq("aId", aId).single();
-
- if (error) {
- Alert.alert("Assignment could not be fetched, please try again");
- return;
- }
-
- SetAssignment(data ?? null);
- }
-
- useFocusEffect(
- useCallback(() => {
- if (aId) {
- GetAssignment(aId);
- }
- }, [aId])
- );
-
- const EditAssignment = async () => {
- if (!assignment) return;
-
- if(assignment.title.trim() === '' || assignment.deadline.trim() === '') {
- Alert.alert("Title and deadline are required!");
- return;
- }
-
- const { data: userData, error: userError } = await supabase.auth.getUser();
-
- if(userError || !userData.user) {
- router.replace("../createUser");
- return;
- }
-
- SetIsSaving(true);
-
- const { data: assignmentData, error: dbError } = await supabase.from("assignments").update({
- title: assignment.title,
- description: assignment.description,
- deadline: assignment.deadline,
- isCompleted: assignment.isCompleted,
- lastChanged: new Date().toISOString(),
- uId: userData.user.id,
- sId: assignment.sId,
- })
- .eq("aId", aId)
- .select()
- .single();
-
- SetIsSaving(false);
-
- if (dbError) {
- Alert.alert("Assignment could not be edited, please try again");
- return;
- }
-
- Alert.alert("Assignment successfully edited!");
-
- if (assignmentData) {
- await CancelDeadlineReminder(assignmentData.aId);
-
- if (!assignmentData.isCompleted) {
- const nId = await ScheduleDeadlineReminder(assignmentData.aId, assignmentData.title, assignmentData.deadline);
-
- if (nId) {
- await SaveAssignmentNotificationId(assignmentData.aId, nId);
- }
- }
- }
-
- if (assignmentData.sId) {
- try {
- await CheckSubjectCompletion(assignmentData.sId);
- } catch {
- Alert.alert("Failed to update subject status");
- }
- }
-
- router.back();
- }
-
- return (
-
-
-
- {!assignment && (
-
- Assignment not found
-
- )}
-
- {assignment && (
-
- Edit Assignment
-
-
-
- SetAssignment(prev => prev ? { ...prev, title: text } : prev)}
- />
- SetAssignment(prev => prev ? { ...prev, description: text } : prev)}
- />
- SetAssignment(prev => prev ? { ...prev, deadline: text } : prev)}
- />
- SetAssignment(prev => prev ? { ...prev, isCompleted: !prev.isCompleted } : prev)}
- style={defaultStyles.checkboxContainer}
- >
-
- {assignment.isCompleted && ✓}
-
- {assignment.isCompleted ? 'Completed' : 'Not Completed'}
-
-
-
- {isSaving && (
-
- )}
-
-
-
-
- )}
-
- )
-}
-
diff --git a/app/assignment/createAssignment.tsx b/app/assignment/upsertAssignment.tsx
similarity index 60%
rename from app/assignment/createAssignment.tsx
rename to app/assignment/upsertAssignment.tsx
index f377cb0..d70a688 100644
--- a/app/assignment/createAssignment.tsx
+++ b/app/assignment/upsertAssignment.tsx
@@ -4,7 +4,7 @@ import { CheckSubjectCompletion } from '@/lib/progress';
import { supabase } from '@/lib/supabase';
import * as Notifications from 'expo-notifications';
import { router, Stack, useLocalSearchParams } from 'expo-router';
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import {
ActivityIndicator,
Alert,
@@ -19,28 +19,74 @@ import {
View,
} from 'react-native';
-export default function CreateAssignment() {
- const sId = (useLocalSearchParams().sId as string) ?? null;
+export default function UpsertAssignment() {
+ const { aId, sId: routeSId } = useLocalSearchParams<{
+ aId?: string;
+ sId?: string;
+ }>();
+
+ const isEditMode = Boolean(aId);
+
const [title, SetTitle] = useState('');
const [description, SetDescription] = useState('');
const [deadline, SetDeadline] = useState('');
const [isCompleted, SetIsCompleted] = useState(false);
+ const [subjectId, SetSubjectId] = useState(routeSId ?? null);
+
+ const [isLoading, SetIsLoading] = useState(isEditMode);
const [isSaving, SetIsSaving] = useState(false);
- const ScheduleDeadlineReminder = async (aId: string, title: string, deadline: string) => {
- const dl = new Date(deadline);
+ useEffect(() => {
+ if (!isEditMode || !aId) {
+ SetIsLoading(false);
+ return;
+ }
- if (isNaN(dl.getTime())) return null;
+ const loadAssignment = async () => {
+ SetIsLoading(true);
+
+ const { data, error } = await supabase
+ .from('assignments')
+ .select('*')
+ .eq('aId', aId)
+ .single();
+
+ SetIsLoading(false);
+
+ if (error || !data) {
+ Alert.alert('Assignment could not be loaded, please try again');
+ router.back();
+ return;
+ }
+
+ SetTitle(data.title ?? '');
+ SetDescription(data.description ?? '');
+ SetDeadline(data.deadline ?? '');
+ SetIsCompleted(data.isCompleted ?? false);
+ SetSubjectId(data.sId ?? routeSId ?? null);
+ };
+
+ loadAssignment();
+ }, [aId, isEditMode, routeSId]);
+
+ const ScheduleDeadlineReminder = async (
+ assignmentId: string,
+ assignmentTitle: string,
+ assignmentDeadline: string
+ ) => {
+ const dl = new Date(assignmentDeadline);
+
+ if (Number.isNaN(dl.getTime())) return null;
const deadlineReminder = new Date(dl.getTime() - 24 * 60 * 60 * 1000);
- if (deadlineReminder <= new Date()) return null;
+ if (deadlineReminder <= new Date()) return null;
const nId = await Notifications.scheduleNotificationAsync({
content: {
title: 'Assignment deadline coming up',
- body: `${title} is due in 24 hours.`,
- data: { aId },
+ body: `${assignmentTitle} is due in 24 hours.`,
+ data: { aId: assignmentId },
},
trigger: {
type: Notifications.SchedulableTriggerInputTypes.DATE,
@@ -49,9 +95,40 @@ export default function CreateAssignment() {
});
return nId;
- }
+ };
- const CreateAssignment = async () => {
+ const updateDeadlineReminder = async (
+ assignmentId: string,
+ assignmentTitle: string,
+ assignmentDeadline: string,
+ completed: boolean
+ ) => {
+ const existingNotificationId =
+ await AsyncStorage.GetAssignmentNotificationId(assignmentId);
+
+ if (existingNotificationId) {
+ try {
+ await Notifications.cancelScheduledNotificationAsync(
+ existingNotificationId
+ );
+ } catch {}
+ await AsyncStorage.RemoveAssignmentNotificationId(assignmentId);
+ }
+
+ if (completed) return;
+
+ const nId = await ScheduleDeadlineReminder(
+ assignmentId,
+ assignmentTitle,
+ assignmentDeadline
+ );
+
+ if (nId) {
+ await AsyncStorage.SaveAssignmentNotificationId(assignmentId, nId);
+ }
+ };
+
+ const handleSubmit = async () => {
if (title.trim() === '') {
Alert.alert('Title is required!');
return;
@@ -60,54 +137,70 @@ export default function CreateAssignment() {
const { data: userData, error: userError } = await supabase.auth.getUser();
if (userError || !userData.user) {
- router.replace('../createUser');
+ router.replace('/login');
+ return;
+ }
+
+ if (!subjectId) {
+ Alert.alert('Missing subject', 'This assignment is not linked to a subject.');
return;
}
SetIsSaving(true);
- const { data: assignmentData, error: dbError } = await supabase.from('assignments').insert({
+ const payload = {
title: title.trim(),
description: description.trim(),
deadline: deadline.trim(),
isCompleted,
lastChanged: new Date().toISOString(),
uId: userData.user.id,
- sId,
- })
- .select()
- .single();
+ sId: subjectId,
+ };
- if (dbError) {
+ const result =
+ isEditMode && aId
+ ? await supabase
+ .from('assignments')
+ .update(payload)
+ .eq('aId', aId)
+ .select()
+ .single()
+ : await supabase.from('assignments').insert(payload).select().single();
+
+ if (result.error || !result.data) {
SetIsSaving(false);
- Alert.alert('Assignment could not be created, please try again');
+ Alert.alert(
+ isEditMode
+ ? 'Assignment could not be updated, please try again'
+ : 'Assignment could not be created, please try again'
+ );
return;
}
- Alert.alert('Assignment successfully created!');
+ const savedAssignment = result.data;
- if (!isCompleted && assignmentData) {
- const nId = await ScheduleDeadlineReminder(assignmentData.aId, assignmentData.title, assignmentData.deadline);
+ await updateDeadlineReminder(
+ savedAssignment.aId,
+ savedAssignment.title,
+ savedAssignment.deadline,
+ savedAssignment.isCompleted
+ );
- if (nId) {
- await AsyncStorage.SaveAssignmentNotificationId(assignmentData.aId, nId);
- }
+ try {
+ await CheckSubjectCompletion(subjectId);
+ } catch {
+ Alert.alert('Failed to update subject status');
}
- if (sId) {
- try {
- await CheckSubjectCompletion(sId);
- } catch {
- Alert.alert("Failed to update subject status");
- }
- }
-
- SetTitle('');
- SetDescription('');
- SetDeadline('');
- SetIsCompleted(false);
SetIsSaving(false);
+ Alert.alert(
+ isEditMode
+ ? 'Assignment successfully updated!'
+ : 'Assignment successfully created!'
+ );
+
router.back();
};
@@ -116,11 +209,19 @@ export default function CreateAssignment() {
const labelClassName = 'mb-2 text-sm font-semibold text-text-secondary';
+ if (isLoading) {
+ return (
+
+
+
+ );
+ }
+
return (
<>
@@ -142,10 +243,12 @@ export default function CreateAssignment() {
>
- Create Assignment
+ {isEditMode ? 'Edit Assignment' : 'Create Assignment'}
- Add a new assignment to keep your subject organized.
+ {isEditMode
+ ? 'Update this assignment and keep your subject organized.'
+ : 'Add a new assignment to keep your subject organized.'}
@@ -155,6 +258,7 @@ export default function CreateAssignment() {
{isSaving ? (
- Creating...
+ {isEditMode ? 'Saving...' : 'Creating...'}
) : (
- Create Assignment
+ {isEditMode ? 'Save Changes' : 'Create Assignment'}
)}
diff --git a/app/assignment/viewDetailsAssignment.tsx b/app/assignment/viewDetailsAssignment.tsx
index 7f99ac7..15c4ed9 100644
--- a/app/assignment/viewDetailsAssignment.tsx
+++ b/app/assignment/viewDetailsAssignment.tsx
@@ -1,4 +1,4 @@
-import { formatDateTime } from '@/lib/date';
+import { formatDate, formatDateTime } from '@/lib/date';
import { CheckAssignmentCompletion, CheckSubjectCompletion } from '@/lib/progress';
import { getSubjectColorSet, type SubjectColor } from '@/lib/subjectColors';
import { supabase } from '@/lib/supabase';
@@ -288,7 +288,7 @@ export default function ViewDetailsAssignment() {
- Deadline: {formatDateTime(assignment.deadline) || 'No deadline'}
+ Deadline: {formatDate(assignment.deadline) || 'No deadline'}
@@ -332,7 +332,7 @@ export default function ViewDetailsAssignment() {
className="mr-3 flex-1 items-center justify-center rounded-2xl border border-app-border bg-app-subtle py-3"
onPress={() =>
router.push({
- pathname: '/assignment/editAssignment',
+ pathname: '/assignment/upsertAssignment',
params: { aId: assignment.aId },
})
}
@@ -385,7 +385,7 @@ export default function ViewDetailsAssignment() {
className="mb-4 rounded-3xl bg-app-surface p-4"
style={{
borderWidth: 1,
- borderColor: colorSet.soft,
+ borderColor: colorSet.strong,
}}
>
section.data.length === 0 ? (
-
+
{section.emptyMessage}
diff --git a/app/subject/viewDetailsSubject.tsx b/app/subject/viewDetailsSubject.tsx
index a815f02..7b5480f 100644
--- a/app/subject/viewDetailsSubject.tsx
+++ b/app/subject/viewDetailsSubject.tsx
@@ -86,6 +86,20 @@ export default function ViewDetailsSubject() {
}, [session, sId])
);
+ useEffect(() => {
+ const test = async () => {
+ try {
+ const { data, error } = await supabase.from('subjects').select('*').limit(1);
+ console.log('test data:', data);
+ console.log('test error:', error);
+ } catch (err) {
+ console.log('test crashed:', err);
+ }
+ };
+
+ test();
+ }, []);
+
const DeleteSubject = async (subjectId: string) => {
Alert.alert(
'Delete Subject',
@@ -348,7 +362,7 @@ export default function ViewDetailsSubject() {
className="mb-6 mt-5 h-14 items-center justify-center rounded-2xl bg-accent"
onPress={() =>
router.push({
- pathname: '/assignment/createAssignment',
+ pathname: '/assignment/upsertAssignment',
params: { sId: subject.sId },
})
}
@@ -374,7 +388,12 @@ export default function ViewDetailsSubject() {
const isOwner = session?.user.id === item.uId;
return (
-
+
router.push({
@@ -406,14 +425,6 @@ export default function ViewDetailsSubject() {
Deadline: {formatDate(item.deadline)}
-
-
-
-
- {item.isCompleted ? 'Completed' : 'Upcoming'}
-
-
-
@@ -423,7 +434,7 @@ export default function ViewDetailsSubject() {
className="mr-3 flex-1 items-center justify-center rounded-2xl border border-app-border bg-app-subtle py-3"
onPress={() =>
router.push({
- pathname: '/assignment/editAssignment',
+ pathname: '/assignment/upsertAssignment',
params: { aId: item.aId },
})
}
diff --git a/app/task/viewDetailsTask.tsx b/app/task/viewDetailsTask.tsx
index 76250dd..9c44b18 100644
--- a/app/task/viewDetailsTask.tsx
+++ b/app/task/viewDetailsTask.tsx
@@ -1,4 +1,6 @@
+import { formatDateTime } from '@/lib/date';
import { CheckAssignmentCompletion } from '@/lib/progress';
+import { getSubjectColorSet, type SubjectColor } from '@/lib/subjectColors';
import { supabase } from '@/lib/supabase';
import type { Task } from '@/lib/types';
import { Session } from '@supabase/supabase-js';
@@ -8,8 +10,14 @@ import { Alert, Pressable, Text, View } from 'react-native';
export default function ViewDetailsTask() {
const { tId } = useLocalSearchParams<{ tId: string }>();
+
const [task, SetTask] = useState(null);
const [session, SetSession] = useState(null);
+ const [contextMeta, setContextMeta] = useState({
+ subjectTitle: 'No Subject',
+ assignmentTitle: 'No Assignment',
+ subjectColor: 'slate' as SubjectColor,
+ });
useEffect(() => {
supabase.auth.getSession().then(({ data }) => SetSession(data.session ?? null));
@@ -28,12 +36,55 @@ export default function ViewDetailsTask() {
.eq('tId', taskId)
.single();
- if (error) {
+ if (error || !data) {
+ console.log('GetTask error:', error);
Alert.alert('Task could not be fetched, please try again');
return;
}
- SetTask(data ?? null);
+ SetTask(data);
+
+ if (data.aId) {
+ const { data: assignmentData, error: assignmentError } = await supabase
+ .from('assignments')
+ .select('title, sId')
+ .eq('aId', data.aId)
+ .single();
+
+ if (assignmentError || !assignmentData) {
+ console.log('GetTaskAssignment error:', assignmentError);
+ setContextMeta({
+ subjectTitle: 'Unknown Subject',
+ assignmentTitle: 'Unknown Assignment',
+ subjectColor: 'slate',
+ });
+ return;
+ }
+
+ if (assignmentData.sId) {
+ const { data: subjectData, error: subjectError } = await supabase
+ .from('subjects')
+ .select('title, color')
+ .eq('sId', assignmentData.sId)
+ .single();
+
+ if (subjectError || !subjectData) {
+ console.log('GetTaskSubject error:', subjectError);
+ setContextMeta({
+ subjectTitle: 'Unknown Subject',
+ assignmentTitle: assignmentData.title ?? 'Unknown Assignment',
+ subjectColor: 'slate',
+ });
+ return;
+ }
+
+ setContextMeta({
+ subjectTitle: subjectData.title ?? 'Unknown Subject',
+ assignmentTitle: assignmentData.title ?? 'Unknown Assignment',
+ subjectColor: (subjectData.color as SubjectColor | undefined) ?? 'slate',
+ });
+ }
+ }
};
useFocusEffect(
@@ -85,6 +136,8 @@ export default function ViewDetailsTask() {
);
};
+ const colorSet = getSubjectColorSet(contextMeta.subjectColor);
+
if (!task) {
return (
@@ -104,7 +157,13 @@ export default function ViewDetailsTask() {
}}
/>
-
+
Task not found
@@ -145,14 +204,20 @@ export default function ViewDetailsTask() {
}}
/>
-
+
{task.isCompleted && (
✓
@@ -179,15 +244,27 @@ export default function ViewDetailsTask() {
)}
+
+
+ {contextMeta.subjectTitle}
+
+
+
- {task.isCompleted ? 'Completed' : 'In progress'}
+ {contextMeta.assignmentTitle}
- Last changed: {task.lastChanged}
+ Last changed: {formatDateTime(task.lastChanged)}