import type { GameDTO } from '$lib/api/schema-helpers'; /** * The shape the game editor binds to. Every field is present and non-null so the * inputs never see `undefined`, and `POST /api/Game` always receives a whole DTO — * `AddOrUpdate` replaces every column, so a partial body would blank the rest. * * `id` 0 marks an unsaved game: the API inserts on 0 and updates otherwise. */ export interface Draft { id: number; name: string; longName: string; /** Null while the number input sits empty; `Game.Order` is a non-nullable int. */ order: number | null; imgUrl: string; wordPressTag: string; wordPressTagOs: string; smashId: number | null; } export const blankDraft: Draft = { id: 0, name: '', longName: '', order: 0, imgUrl: '', wordPressTag: '', wordPressTagOs: '', smashId: null }; export function toDraft(game: GameDTO): Draft { return { id: game.id ?? 0, name: game.name ?? '', longName: game.longName ?? '', order: game.order ?? 0, imgUrl: game.imgUrl ?? '', wordPressTag: game.wordPressTag ?? '', wordPressTagOs: game.wordPressTagOs ?? '', smashId: game.smashId ?? null }; } /** Blank text is stored as NULL rather than as an empty string. */ export function toDto(draft: Draft): GameDTO { const text = (value: string) => (value.trim() === '' ? null : value.trim()); return { id: draft.id, name: text(draft.name), longName: text(draft.longName), order: draft.order ?? 0, imgUrl: text(draft.imgUrl), wordPressTag: text(draft.wordPressTag), wordPressTagOs: text(draft.wordPressTagOs), smashId: draft.smashId }; } /** A new game sorts after the current last one. */ export function nextOrder(games: GameDTO[]): number { return games.reduce((max, game) => Math.max(max, game.order ?? 0), 0) + 1; } /** * Whether the editor holds unsaved changes. * * Field by field rather than by comparing `JSON.stringify` output, which is * key-order dependent: it would report a clean draft as dirty the moment * `blankDraft` and `toDraft` listed their keys in a different order. */ export function isDirty(a: Draft, b: Draft): boolean { return ( a.id !== b.id || a.name !== b.name || a.longName !== b.longName || a.order !== b.order || a.imgUrl !== b.imgUrl || a.wordPressTag !== b.wordPressTag || a.wordPressTagOs !== b.wordPressTagOs || a.smashId !== b.smashId ); }