Skip to main content

Overview

The types module (src/utils/types.ts) exports TypeScript type definitions used throughout stevenson.space for type-safe schedule management, theme configuration, and period tracking.

Schedule Types

Schedule

A schedule can be either single-day (like most schedules) or multi-day (like Finals week).
type Schedule = SingleDaySchedule | MultiDaySchedule;

ScheduleCollection

Groups multiple schedule modes together for a specific date range.
name
ScheduleType
required
The type of schedule (e.g., “Standard Schedule”, “Late Arrival”)
isSpecial
boolean
required
Whether this is a special schedule
dates
string[]
required
Array of date patterns this schedule applies to
modes
Schedule[]
required
Array of schedule modes available for this schedule type
eventAliases
string[]
Optional alternative names for this schedule

CustomSchedules

Format for storing user-defined schedules in localStorage.
type CustomSchedules = Record<string, Schedule[]>
Example:
const customSchedules: CustomSchedules = {
  "My Schedule": [
    {
      name: "Normal",
      isCustom: true,
      start: ["8:00", "9:30", "11:00"],
      end: ["9:20", "10:50", "12:20"],
      periods: ["1", "2", "3"]
    }
  ]
};

Period Types

Period

Represents a class period, passing period, or before/after school time.
type Period =
  | { beforeSchool: true, afterSchool?: false }
  | { beforeSchool?: false, afterSchool: true }
  | { beforeSchool?: false, afterSchool?: false, name: string, start: string, end: string }
Example Usage:
import { Period } from '@/utils/types';

// Before school
const beforeSchool: Period = { beforeSchool: true };

// Regular period
const period1: Period = {
  name: "1",
  start: "8:00",
  end: "9:20"
};

// Passing period (prefixed with !)
const passing: Period = {
  name: "!Passing",
  start: "9:20",
  end: "9:30"
};

Theme Types

Theme

Defines the complete structure for a visual theme.
metadata
ThemeMetadata
required
visibility
'show' | 'draft' | 'hide'
required
Controls whether theme appears in theme selector
seasonalDates
string
Date pattern for seasonal themes (e.g., “12/1-12/31”)
styling
ThemeStyling
required
Complete styling configuration (see ThemeStyling below)

ThemeStyling

Defines all visual styling properties for a theme.
base
'light' | 'dark'
Base color scheme
background
string
Background color (CSS color value)
secondaryBackground
string
Secondary background color for cards and panels
accent
string
Accent color for interactive elements
text
ThemeTextColors
header
ThemeHeaderConfig
iconCards
ThemeIconCards
particles
ThemeParticles
Example Theme:
import { Theme } from '@/utils/types';

const winterTheme: Theme = {
  metadata: {
    name: "Winter Wonderland",
    author: "Student Council"
  },
  visibility: "show",
  recommended: {
    timing: "season",
    message: "Get into the winter spirit!"
  },
  seasonalDates: "12/1-2/28",
  styling: {
    base: "dark",
    background: "#1a2332",
    accent: "#64b5f6",
    text: {
      primary: "#ffffff",
      secondary: "#b0bec5",
      tertiary: "#78909c"
    },
    particles: {
      images: ["/images/snowflake.png"],
      speed: 2,
      count: 50
    }
  }
};

Utility Types

NonEmptyArray

Ensures an array has at least one element.
type NonEmptyArray<T> = { 0: T } & T[];

MapStateToComputed

Helper type for mapping Vuex/Pinia state to computed properties.
type MapStateToComputed<S> = {
  [K in keyof S]: () => S[K]
}
Example:
import { MapStateToComputed } from '@/utils/types';

interface MyState {
  count: number;
  name: string;
}

// Creates: { count: () => number, name: () => string }
type MyComputed = MapStateToComputed<MyState>;

Usage in Components

import { Schedule, Period, Theme } from '@/utils/types';
import { useScheduleStore } from '@/stores/schedules';

export default {
  setup() {
    const scheduleStore = useScheduleStore();
    
    // Type-safe schedule access
    const currentSchedule: Schedule = scheduleStore.currentSchedule;
    
    // Type-safe period checking
    const checkPeriod = (period: Period) => {
      if (period.beforeSchool) {
        console.log('Before school');
      } else if (period.afterSchool) {
        console.log('After school');
      } else {
        console.log(`Period ${period.name}: ${period.start} - ${period.end}`);
      }
    };
  }
};

Build docs developers (and LLMs) love