Files
2025-12-29 13:59:17 -05:00

85 lines
1.8 KiB
TypeScript

// types/builderSlots.ts
export type CategoryGroup = "lower" | "upper" | "accessories";
/**
* Canonical key used across UI, localStorage, and (ideally) backend part_roles.key.
* Keep these in sync with part_roles.key to avoid mapping hell.
*/
export type BuilderSlotKey =
// ===== LOWER =====
| "lower-receiver"
| "complete-lower"
| "lower-parts-kit"
| "trigger"
| "grip"
| "safety-selector"
| "buffer"
| "stock"
// ===== UPPER =====
| "upper-receiver"
| "complete-upper"
| "barrel"
| "handguard"
| "gas-block"
| "gas-tube"
| "muzzle-device"
| "bcg"
| "charging-handle"
| "suppressor"
| "sights"
| "optic"
// ===== ACCESSORIES =====
| "magazine"
| "weapon-light"
| "foregrip"
| "bipod"
| "sling"
| "rail-accessory"
| "tools";
export interface Category {
id: BuilderSlotKey;
name: string;
description?: string;
group?: CategoryGroup;
}
export interface Part {
id: string;
name: string;
brand: string;
categoryId: BuilderSlotKey;
price: number;
affiliateUrl?: string;
url?: string;
imageUrl?: string;
notes?: string;
}
/**
* Legacy localStorage / URL keys support (read-only).
* Add/remove as needed during migration.
*/
const LEGACY_SLOT_ALIASES: Record<string, BuilderSlotKey> = {
completeUpper: "complete-upper",
gasBlock: "gas-block",
gasTube: "gas-tube",
muzzleDevice: "muzzle-device",
chargingHandle: "charging-handle",
completeLower: "complete-lower",
lowerParts: "lower-parts-kit",
weaponLight: "weapon-light",
railAccessory: "rail-accessory",
// also handle older kebab mismatches if they exist:
"lower-parts": "lower-parts-kit",
safety: "safety-selector",
};
export function normalizeSlotKey(key: string): BuilderSlotKey | null {
const k = (key ?? "").trim();
if (!k) return null;
return (LEGACY_SLOT_ALIASES[k] ?? (k as BuilderSlotKey)) || null;
}