All files / Bandstand/src/components RunningOrder.tsx

0% Statements 0/42
0% Branches 0/1
0% Functions 0/1
0% Lines 0/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67                                                                                                                                     
import {formatClock, setSummary, timeRange, type OrderEntry} from '@/lib/gig'
 
type Row = {
  id: string
  kind: 'SONG' | 'SET' | 'BREAK'
  label: string | null
  minutes: number | null
  song: {title: string} | null
}
 
/**
 * A gig's running order at a glance: each set as a small heading with its
 * times, songs numbered within it, breaks as a quiet line between. Pure
 * markup (server-safe).
 */
export default function RunningOrder<T extends Row>({
  entries,
  song,
}: {
  entries: OrderEntry<T>[]
  /** How a song row reads; defaults to its title */
  song?: (item: T, n: number) => React.ReactNode
}) {
  return (
    <ol className="space-y-1">
      {entries.map((e) => {
        if (e.kind === 'SET')
          return (
            <li
              key={e.item.id}
              className="flex flex-wrap items-baseline gap-x-3 pb-1 pt-3 first:pt-0"
            >
              <span className="text-xs font-bold uppercase tracking-widest text-amber">
                {e.info.label}
              </span>
              <span className="font-mono text-sm">
                {timeRange(e.info.start, e.info.end)}
              </span>
              <span className="text-xs text-faint">{setSummary(e.info)}</span>
            </li>
          )
        if (e.kind === 'BREAK')
          return (
            <li
              key={e.item.id}
              className="my-2 flex items-center gap-3 text-sm text-faint"
            >
              <span className="h-px flex-1 bg-line" />
              Break
              {e.info.minutes ? ` · ${e.info.minutes} min` : ''}
              {e.info.end != null && ` · back ${formatClock(e.info.end)}`}
              <span className="h-px flex-1 bg-line" />
            </li>
          )
        return (
          <li key={e.item.id} className="flex gap-3">
            <span className="w-5 shrink-0 text-right font-mono text-faint">
              {e.n}
            </span>
            {song ? song(e.item, e.n) : e.item.song?.title}
          </li>
        )
      })}
    </ol>
  )
}