mad cleanup.

This commit is contained in:
2025-12-29 13:59:17 -05:00
parent 0dd89a751b
commit cc386d14f4
14 changed files with 1054 additions and 315 deletions
+85
View File
@@ -0,0 +1,85 @@
// 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;
}
-129
View File
@@ -1,129 +0,0 @@
// Grouping for nav + layout
export type CategoryGroup = "lower" | "upper" | "accessories";
/**
* CategoryId is the canonical identifier used throughout the UI + localStorage.
*
* ✅ Canonical IDs are kebab-case to match route segments and `gunbuilderParts.ts`.
*
* 🧯 Legacy camelCase IDs are temporarily supported to avoid breaking older
* localStorage/build-state and older code paths. Prefer kebab-case going forward.
*/
export type CategoryId =
// ===== LOWER =====
| "lower-receiver"
| "complete-lower"
| "lower-parts"
| "trigger"
| "grip"
| "safety"
| "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"
// ===== LEGACY (temporary) =====
| "completeUpper"
| "gasBlock"
| "gasTube"
| "muzzleDevice"
| "chargingHandle"
| "completeLower"
| "lowerParts"
| "weaponLight"
| "railAccessory";
export interface Category {
id: CategoryId;
name: string;
description?: string;
/** used for nav & grouping */
group?: CategoryGroup;
/** optional slug override (mostly for legacy IDs) */
slug?: string;
}
export interface Part {
id: string;
name: string;
brand: string;
categoryId: CategoryId;
price: number;
affiliateUrl?: string;
url?: string;
imageUrl?: string;
notes?: string;
}
/**
* Route / UI slug for each CategoryId.
*
* - Canonical kebab-case ids map 1:1.
* - Legacy camelCase ids map to the same slug.
*/
export const CATEGORY_SLUGS = {
// LOWER
"lower-receiver": "lower-receiver",
"complete-lower": "complete-lower",
"lower-parts": "lower-parts",
trigger: "trigger",
grip: "grip",
safety: "safety",
buffer: "buffer",
stock: "stock",
// UPPER
"upper-receiver": "upper-receiver",
"complete-upper": "complete-upper",
barrel: "barrel",
handguard: "handguard",
"gas-block": "gas-block",
"gas-tube": "gas-tube",
"muzzle-device": "muzzle-device",
sights: "sights",
bcg: "bcg",
"charging-handle": "charging-handle",
suppressor: "suppressor",
optic: "optic",
// ACCESSORIES
magazine: "magazine",
"weapon-light": "weapon-light",
foregrip: "foregrip",
bipod: "bipod",
sling: "sling",
"rail-accessory": "rail-accessory",
tools: "tools",
// LEGACY (temporary)
completeUpper: "complete-upper",
gasBlock: "gas-block",
gasTube: "gas-tube",
muzzleDevice: "muzzle-device",
chargingHandle: "charging-handle",
completeLower: "complete-lower",
lowerParts: "lower-parts",
weaponLight: "weapon-light",
railAccessory: "rail-accessory",
} as const satisfies Record<CategoryId, string>;