47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
/**
|
|||
|
|
* Determines if a submission was submitted before the due date
|
||
|
|
* @param createdAt Submission creation timestamp
|
||
|
|
* @param dueBy Exercise due date (can be null)
|
||
|
|
* @returns true if submission is early or on time, false if late
|
||
|
|
*/
|
||
|
|
export function isSubmissionEarly(createdAt: string, dueBy: string | null): boolean {
|
||
|
|
if (!dueBy) return true;
|
||
|
|
return new Date(createdAt).getTime() <= new Date(dueBy).getTime();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Calculates total points from a grades map
|
||
|
|
* @param grades Map of question IDs to point values
|
||
|
|
* @returns Sum of all points
|
||
|
|
*/
|
||
|
|
export function calculateTotalPoints(grades: { [questionId: string]: number }): number {
|
||
|
|
if (!grades) return 0;
|
||
|
|
return Object.values(grades).reduce(
|
||
|
|
(acc, grade) => acc + (typeof grade === 'number' ? grade : parseInt(String(grade), 10) || 0),
|
||
|
|
0
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets maximum possible points from questions array
|
||
|
|
* @param questions Array of questions with points property
|
||
|
|
* @returns Sum of all question points
|
||
|
|
*/
|
||
|
|
export function getMaxPoints(questions: Array<{ points: number }>): number {
|
||
|
|
if (!questions || !Array.isArray(questions)) return 0;
|
||
|
|
return questions.reduce((acc, question) => acc + (question.points || 0), 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Formats a date string for display
|
||
|
|
* @param date ISO date string
|
||
|
|
* @returns Formatted date string
|
||
|
|
*/
|
||
|
|
export function formatSubmittedDate(date: string): string {
|
||
|
|
const d = new Date(date);
|
||
|
|
return new Intl.DateTimeFormat('en-US', {
|
||
|
|
dateStyle: 'full',
|
||
|
|
timeStyle: 'medium'
|
||
|
|
}).format(d);
|
||
|
|
}
|