diff --git a/frontend/website/src/stores/schedules.ts b/frontend/website/src/stores/schedules.ts index f8844e6..090db7c 100644 --- a/frontend/website/src/stores/schedules.ts +++ b/frontend/website/src/stores/schedules.ts @@ -26,6 +26,15 @@ const scheduleAssignmentSchema = z.object({ }), }) +export const assignmentForDateSchema = scheduleAssignmentSchema.extend({ + schedule: z.object({ + id: z.number().int().positive(), + set: z.object({ + name: z.string().min(1), + }), + }), +}) + export const scheduleDetailSchema = scheduleSummarySchema.extend({ days: z.array( z.object({ @@ -43,12 +52,18 @@ const scheduleResponseSchema = z.object({ schedule: scheduleDetailSchema, }) +const assignmentsForDateResponseSchema = z.object({ + date: isoDateSchema, + assignments: z.array(assignmentForDateSchema), +}) + const errorResponseSchema = z.object({ error: z.string().min(1), }) export type ScheduleSummary = z.infer export type ScheduleDetail = z.infer +export type AssignmentForDate = z.infer export type CreateScheduleInput = { setId: number levelId: number @@ -59,6 +74,7 @@ export type CreateScheduleInput = { const LIST_ERROR = "We couldn't load your schedules." const DETAIL_ERROR = "We couldn't load this schedule." const CREATE_ERROR = "We couldn't create this schedule." +const ASSIGNMENTS_ERROR = "We couldn't load today's assignments." export const useSchedulesStore = defineStore('schedules', () => { const schedules = ref([]) @@ -70,7 +86,11 @@ export const useSchedulesStore = defineStore('schedules', () => { const detailNotFound = ref(false) const creating = ref(false) const createError = ref(null) + const assignmentsForDate = ref([]) + const assignmentsLoading = ref(false) + const assignmentsError = ref(null) let activeDetailRequestId = 0 + let assignmentsRequestId = 0 async function fetchSchedules(): Promise { listLoading.value = true @@ -202,6 +222,58 @@ export const useSchedulesStore = defineStore('schedules', () => { } } + async function fetchAssignmentsForDate(date: string): Promise { + const requestId = ++assignmentsRequestId + assignmentsForDate.value = [] + assignmentsLoading.value = true + assignmentsError.value = null + + try { + const query = new URLSearchParams({ date }) + const response = await fetch(`${API_BASE}/api/assignments?${query.toString()}`, { + method: 'GET', + credentials: 'include', + headers: { + Accept: 'application/json', + }, + }) + + if (requestId !== assignmentsRequestId) { + return false + } + + if (response.status !== 200) { + assignmentsError.value = ASSIGNMENTS_ERROR + + return false + } + + const responseBody: unknown = await response.json() + if (requestId !== assignmentsRequestId) { + return false + } + + const parsedResponse = assignmentsForDateResponseSchema.parse(responseBody) + if (parsedResponse.date !== date) { + throw new Error('assignment response did not match requested date') + } + assignmentsForDate.value = parsedResponse.assignments + + return true + } catch { + if (requestId === assignmentsRequestId) { + assignmentsForDate.value = [] + assignmentsError.value = ASSIGNMENTS_ERROR + } + + return false + } finally { + if (requestId === assignmentsRequestId) { + assignmentsLoading.value = false + } + } + } + return { schedules, listLoading, @@ -212,8 +284,12 @@ export const useSchedulesStore = defineStore('schedules', () => { detailNotFound, creating, createError, + assignmentsForDate, + assignmentsLoading, + assignmentsError, fetchSchedules, fetchSchedule, createSchedule, + fetchAssignmentsForDate, } }) diff --git a/frontend/website/src/views/DashboardView.vue b/frontend/website/src/views/DashboardView.vue index 12464ee..c99ccf4 100644 --- a/frontend/website/src/views/DashboardView.vue +++ b/frontend/website/src/views/DashboardView.vue @@ -1,6 +1,6 @@