mirror of
https://github.com/Xevion/banner.git
synced 2026-02-01 08:23:40 -06:00
Extract DateRange, MeetingLocation, CreditHours, CrossList, Enrollment, and RmpRating into dedicated types. Replace primitive fields across backend models and frontend bindings with type-safe alternatives.
84 lines
2.2 KiB
TypeScript
84 lines
2.2 KiB
TypeScript
// columns.ts
|
|
import type { CourseResponse } from "$lib/api";
|
|
import type { ColumnDef } from "@tanstack/table-core";
|
|
import type { Component } from "svelte";
|
|
import {
|
|
abbreviateInstructor,
|
|
formatMeetingDays,
|
|
formatTimeRange,
|
|
getPrimaryInstructor,
|
|
} from "$lib/course";
|
|
|
|
import CrnCell from "./cells/CrnCell.svelte";
|
|
import CourseCodeCell from "./cells/CourseCodeCell.svelte";
|
|
import TitleCell from "./cells/TitleCell.svelte";
|
|
import InstructorCell from "./cells/InstructorCell.svelte";
|
|
import TimeCell from "./cells/TimeCell.svelte";
|
|
import LocationCell from "./cells/LocationCell.svelte";
|
|
import SeatsCell from "./cells/SeatsCell.svelte";
|
|
|
|
export const COLUMN_DEFS: ColumnDef<CourseResponse, unknown>[] = [
|
|
{
|
|
id: "crn",
|
|
accessorKey: "crn",
|
|
header: "CRN",
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
id: "course_code",
|
|
accessorFn: (row) => `${row.subject} ${row.courseNumber}`,
|
|
header: "Course",
|
|
enableSorting: true,
|
|
},
|
|
{
|
|
id: "title",
|
|
accessorKey: "title",
|
|
header: "Title",
|
|
enableSorting: true,
|
|
},
|
|
{
|
|
id: "instructor",
|
|
accessorFn: (row) => {
|
|
const primary = getPrimaryInstructor(row.instructors, row.primaryInstructorId);
|
|
if (!primary) return "Staff";
|
|
return abbreviateInstructor(primary.displayName);
|
|
},
|
|
header: "Instructor",
|
|
enableSorting: true,
|
|
},
|
|
{
|
|
id: "time",
|
|
accessorFn: (row) => {
|
|
if (row.meetingTimes.length === 0) return "";
|
|
const mt = row.meetingTimes[0];
|
|
return `${formatMeetingDays(mt)} ${formatTimeRange(mt.timeRange?.start ?? null, mt.timeRange?.end ?? null)}`;
|
|
},
|
|
header: "Time",
|
|
enableSorting: true,
|
|
},
|
|
{
|
|
id: "location",
|
|
accessorFn: (row) => row.primaryLocation ?? "",
|
|
header: "Location",
|
|
enableSorting: false,
|
|
},
|
|
{
|
|
id: "seats",
|
|
accessorFn: (row) => row.enrollment.max - row.enrollment.current,
|
|
header: "Seats",
|
|
enableSorting: true,
|
|
},
|
|
];
|
|
|
|
/** Column ID to Svelte cell component. Used by the row renderer. */
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
export const CELL_COMPONENTS: Record<string, Component<any>> = {
|
|
crn: CrnCell,
|
|
course_code: CourseCodeCell,
|
|
title: TitleCell,
|
|
instructor: InstructorCell,
|
|
time: TimeCell,
|
|
location: LocationCell,
|
|
seats: SeatsCell,
|
|
};
|