SPB Git forge
3commits 1branches 0releases
417.0 KBsize
maindefault branch
10 days agolast push
TypeScript 66.5% Python 30.9% JavaScript 1.4% CSS 0.7%
2.9 KB · 57 lines tsx
Raw Blame History
1import Link from 'next/link';2import { fmtDate, fmtInt, num } from '@/lib/format';3import { routes } from '@/lib/site';4import type { LaunchRow } from '@/lib/types';56/** Launch rows (list page, site detail, launch detail siblings). `ownerHref` lets the caller scope owner chips to its context. */7export function LaunchesTable({ rows, ownerHref = (code) => routes.launches(`owner=${encodeURIComponent(code)}`), showSite = true }: { rows: LaunchRow[]; ownerHref?: (code: string) => string; showSite?: boolean }) {8  return (9    <div className="overflow-x-auto scrollbar-thin">10      <table className="data-table stack">11        <thead>12          <tr>13            <th>Date</th>14            <th>COSPAR</th>15            <th>Primary payload</th>16            <th className="num">Payloads</th>17            <th className="num">Objects</th>18            <th className="num">On orbit</th>19            {showSite && <th>Site</th>}20            <th>Owners</th>21          </tr>22        </thead>23        <tbody>24          {rows.map((l) => {25            const owners = l.owner_codes ?? [];26            const onOrbit = num(l.on_orbit_count);27            const objects = num(l.object_count);28            return (29              <tr key={l.id}>30                <td data-label="Date" className="mono text-xs">{fmtDate(l.launch_date)}</td>31                <td data-label="COSPAR"><Link href={routes.launch(l.cospar_launch_id)} className="link mono text-xs">{l.cospar_launch_id}</Link></td>32                <td data-label="Primary payload" className="primary"><Link href={routes.launch(l.cospar_launch_id)} className="link font-medium">{l.primary_name ?? <span className="text-ink-3">unnamed</span>}</Link></td>33                <td data-label="Payloads" className="num mono text-xs">{fmtInt(l.payload_count)}</td>34                <td data-label="Objects" className="num mono text-xs">{fmtInt(l.object_count)}</td>35                <td data-label="On orbit" className={`num mono text-xs ${onOrbit === 0 && objects ? 'text-ink-3' : ''}`}>{fmtInt(l.on_orbit_count)}</td>36                {showSite && <td data-label="Site" className="text-xs">{l.site_slug ? <Link href={routes.launchSite(l.site_slug)} className="link">{l.site_name}</Link> : l.site_name ?? '—'}</td>}37                <td data-label="Owners" className="text-xs">38                  {owners.length ? (39                    <span className="flex flex-wrap gap-1">40                      {owners.slice(0, 4).map((c) => (41                        <Link key={c} href={ownerHref(c)} className="mono rounded border border-rule px-1.5 py-px text-[11px] text-ink-2 hover:border-rule-strong hover:text-ink">{c}</Link>42                      ))}43                      {owners.length > 4 && <span className="text-ink-3">+{owners.length - 4}</span>}44                    </span>45                  ) : (46                    '—'47                  )}48                </td>49              </tr>50            );51          })}52        </tbody>53      </table>54    </div>55  );56}57