pc: PC setup tracker at /trackers/pc on the hardware schema
All checks were successful
Deploy production / deploy (push) Successful in 1m4s

- model the existing hardware schema in Drizzle (devices, components, new sensitivities)
- idempotent reconciling migration: new columns, checks, setup_overview view, grants, meta.tables
- seed: main PC labels/hostnames, planned AMD X3D + RTX 5090 build, stan-ovh (OVH RISE-S),
  other devices, sensitivity placeholders (no invented cm/360)
- owner-only add/edit via modals; public view hides notes/order numbers
- trackers dropdown entry + icon, seo/title/sitemap, owner write prefix
This commit is contained in:
2026-10-24 17:55:48 +00:00
parent 8442d59b68
commit 085a30bec8
21 changed files with 23538 additions and 6 deletions

76
src/lib/pc/PcIcon.svelte Normal file
View File

@@ -0,0 +1,76 @@
<script lang="ts">
import Box from 'lucide-svelte/icons/box';
import CircuitBoard from 'lucide-svelte/icons/circuit-board';
import Cloud from 'lucide-svelte/icons/cloud';
import Cpu from 'lucide-svelte/icons/cpu';
import Fan from 'lucide-svelte/icons/fan';
import Gamepad2 from 'lucide-svelte/icons/gamepad-2';
import Gpu from 'lucide-svelte/icons/gpu';
import HardDrive from 'lucide-svelte/icons/hard-drive';
import Headphones from 'lucide-svelte/icons/headphones';
import Keyboard from 'lucide-svelte/icons/keyboard';
import Laptop from 'lucide-svelte/icons/laptop';
import Lightbulb from 'lucide-svelte/icons/lightbulb';
import MemoryStick from 'lucide-svelte/icons/memory-stick';
import Monitor from 'lucide-svelte/icons/monitor';
import Mouse from 'lucide-svelte/icons/mouse';
import Package from 'lucide-svelte/icons/package';
import PcCase from 'lucide-svelte/icons/pc-case';
import Server from 'lucide-svelte/icons/server';
import Smartphone from 'lucide-svelte/icons/smartphone';
import Snowflake from 'lucide-svelte/icons/snowflake';
import Speaker from 'lucide-svelte/icons/speaker';
import Tablet from 'lucide-svelte/icons/tablet';
import Zap from 'lucide-svelte/icons/zap';
import { CATEGORY_META, DEVICE_KIND_META } from './shared';
// A gradient tile with a white icon, for a part category or a device kind.
let {
category = undefined,
kind = undefined,
class: className = 'size-10'
}: { category?: string; kind?: string; class?: string } = $props();
const icons = {
case: PcCase,
cpu: Cpu,
motherboard: CircuitBoard,
ram: MemoryStick,
cpu_cooler: Snowflake,
gpu: Gpu,
psu: Zap,
storage: HardDrive,
fan: Fan,
lighting: Lightbulb,
monitor: Monitor,
mouse: Mouse,
keyboard: Keyboard,
headset: Headphones,
audio: Speaker,
controller: Gamepad2,
accessory: Package,
other: Box,
desktop: PcCase,
laptop: Laptop,
server: Server,
vm: Cloud,
phone: Smartphone,
tablet: Tablet
} as const;
const key = $derived(category ?? kind ?? 'other');
const meta = $derived(
(category ? CATEGORY_META[category] : kind ? DEVICE_KIND_META[kind] : undefined) ??
CATEGORY_META.other
);
const Icon = $derived(icons[key as keyof typeof icons] ?? Box);
const light = $derived(key === 'case' || key === 'psu' || key === 'controller');
</script>
<span
class="flex shrink-0 items-center justify-center rounded-xl shadow-sm ring-1 ring-black/10 ring-inset {className}"
style:background-image="linear-gradient(135deg, {meta.from}, {meta.to})"
style:color={light ? '#111' : '#fff'}
aria-hidden="true"
>
<Icon class="size-[52%]" strokeWidth={2} />
</span>