fix: wire catalog add buttons, fix Trans bold rendering, lint cleanup
Some checks failed
CI / ci (push) Failing after 1m44s
CI / e2e (push) Has been skipped
CI / deploy (push) Has been skipped

- CatalogSearchOverlay: replace handleAddStub with real openAddToCollection/openAddToThread routing based on catalogSearchMode
- ConfirmDialog + __root.tsx: swap t() for Trans component on deleteItemMessage, deleteCandidateMessage, pickWinnerMessage — fixes <bold> rendering as literal text
- Biome format pass: fix 23 lint/format errors across scripts, services, tests
- Planning: mark all UAT and verification gaps resolved for phases 07, 11, 16, 20, 21, 22, 24, 32, 34; close debug sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 15:36:16 +02:00
parent 16058d0f4d
commit 4ccbb2b070
40 changed files with 807 additions and 227 deletions

View File

@@ -21,21 +21,111 @@ export const DEV_CATEGORIES = [
// Seeded with onConflictDoNothing — safe to overlap with SEED_MANUFACTURERS.
export const DEV_MANUFACTURERS = [
{ name: "Rockgeist", slug: "rockgeist", website: "https://rockgeist.com", country: "US", tier: 1 },
{ name: "Oveja Negra", slug: "oveja-negra", website: "https://ovejanegrabikewear.com", country: "US", tier: 1 },
{ name: "Durston", slug: "durston", website: "https://durstondesigns.com", country: "US", tier: 1 },
{ name: "Enlightened Equipment", slug: "enlightened-equipment", website: "https://enlightenedequipment.com", country: "US", tier: 1 },
{ name: "BRS", slug: "brs", website: "https://brs-outdoor.com", country: "CN", tier: 1 },
{ name: "Soto", slug: "soto", website: "https://sotostoves.com", country: "JP", tier: 1 },
{ name: "Snow Peak", slug: "snow-peak", website: "https://snowpeak.com", country: "JP", tier: 1 },
{ name: "Lezyne", slug: "lezyne", website: "https://lezyne.com", country: "US", tier: 1 },
{ name: "Fenix", slug: "fenix", website: "https://fenixlighting.com", country: "CN", tier: 1 },
{ name: "Park Tool", slug: "park-tool", website: "https://parktool.com", country: "US", tier: 1 },
{ name: "Gorilla Tape", slug: "gorilla-tape", website: "https://gorillatough.com", country: "US", tier: 1 },
{ name: "Patagonia", slug: "patagonia", website: "https://patagonia.com", country: "US", tier: 1 },
{ name: "Frogg Toggs", slug: "frogg-toggs", website: "https://froggtoggs.com", country: "US", tier: 1 },
{ name: "Buff", slug: "buff", website: "https://buffwear.com", country: "ES", tier: 1 },
{ name: "Anker", slug: "anker", website: "https://anker.com", country: "CN", tier: 1 },
{
name: "Rockgeist",
slug: "rockgeist",
website: "https://rockgeist.com",
country: "US",
tier: 1,
},
{
name: "Oveja Negra",
slug: "oveja-negra",
website: "https://ovejanegrabikewear.com",
country: "US",
tier: 1,
},
{
name: "Durston",
slug: "durston",
website: "https://durstondesigns.com",
country: "US",
tier: 1,
},
{
name: "Enlightened Equipment",
slug: "enlightened-equipment",
website: "https://enlightenedequipment.com",
country: "US",
tier: 1,
},
{
name: "BRS",
slug: "brs",
website: "https://brs-outdoor.com",
country: "CN",
tier: 1,
},
{
name: "Soto",
slug: "soto",
website: "https://sotostoves.com",
country: "JP",
tier: 1,
},
{
name: "Snow Peak",
slug: "snow-peak",
website: "https://snowpeak.com",
country: "JP",
tier: 1,
},
{
name: "Lezyne",
slug: "lezyne",
website: "https://lezyne.com",
country: "US",
tier: 1,
},
{
name: "Fenix",
slug: "fenix",
website: "https://fenixlighting.com",
country: "CN",
tier: 1,
},
{
name: "Park Tool",
slug: "park-tool",
website: "https://parktool.com",
country: "US",
tier: 1,
},
{
name: "Gorilla Tape",
slug: "gorilla-tape",
website: "https://gorillatough.com",
country: "US",
tier: 1,
},
{
name: "Patagonia",
slug: "patagonia",
website: "https://patagonia.com",
country: "US",
tier: 1,
},
{
name: "Frogg Toggs",
slug: "frogg-toggs",
website: "https://froggtoggs.com",
country: "US",
tier: 1,
},
{
name: "Buff",
slug: "buff",
website: "https://buffwear.com",
country: "ES",
tier: 1,
},
{
name: "Anker",
slug: "anker",
website: "https://anker.com",
country: "CN",
tier: 1,
},
] as const;
// ── Global Items ───────────────────────────────────────────────────

View File

@@ -83,7 +83,10 @@ async function seedDevData(database: Db = db) {
// ── 1. Seed global items, tags, and dev-specific manufacturers ─
await seedGlobalItems(database);
for (const m of DEV_MANUFACTURERS) {
await database.insert(schema.manufacturers).values(m).onConflictDoNothing();
await database
.insert(schema.manufacturers)
.values(m)
.onConflictDoNothing();
}
console.log(" Global items, tags, and manufacturers seeded.");
@@ -145,7 +148,9 @@ async function seedDevData(database: Db = db) {
for (const item of DEV_GLOBAL_ITEMS) {
const mfId = mfBySlug.get(item.manufacturerSlug);
if (!mfId) {
console.warn(` Skipping "${item.model}" — unknown manufacturer slug: ${item.manufacturerSlug}`);
console.warn(
` Skipping "${item.model}" — unknown manufacturer slug: ${item.manufacturerSlug}`,
);
globalItemIds.push(0); // placeholder to keep index alignment
continue;
}

View File

@@ -5,58 +5,261 @@ import { globalItems, manufacturers, tags } from "./schema.ts";
type Db = typeof prodDb;
export const SEED_MANUFACTURERS = [
{ name: "Revelate Designs", slug: "revelate-designs", website: "https://revelatedesigns.com", country: "US", tier: 1 },
{ name: "Apidura", slug: "apidura", website: "https://apidura.com", country: "GB", tier: 1 },
{ name: "Ortlieb", slug: "ortlieb", website: "https://ortlieb.com", country: "DE", tier: 1 },
{ name: "Big Agnes", slug: "big-agnes", website: "https://bigagnes.com", country: "US", tier: 1 },
{ name: "Tarptent", slug: "tarptent", website: "https://tarptent.com", country: "US", tier: 1 },
{ name: "Zpacks", slug: "zpacks", website: "https://zpacks.com", country: "US", tier: 1 },
{ name: "Sea to Summit", slug: "sea-to-summit", website: "https://seatosummit.com", country: "AU", tier: 1 },
{ name: "Western Mountaineering", slug: "western-mountaineering", website: "https://westernmountaineering.com", country: "US", tier: 1 },
{ name: "MSR", slug: "msr", website: "https://msrgear.com", country: "US", tier: 1 },
{ name: "BioLite", slug: "biolite", website: "https://bioliteenergy.com", country: "US", tier: 1 },
{ name: "Petzl", slug: "petzl", website: "https://petzl.com", country: "FR", tier: 1 },
{ name: "Black Diamond", slug: "black-diamond", website: "https://blackdiamondequipment.com", country: "US", tier: 1 },
{ name: "Garmin", slug: "garmin", website: "https://garmin.com", country: "US", tier: 1 },
{ name: "Wahoo", slug: "wahoo", website: "https://wahoofitness.com", country: "US", tier: 1 },
{ name: "Sawyer", slug: "sawyer", website: "https://sawyerproducts.com", country: "US", tier: 1 },
{ name: "Canyon", slug: "canyon", website: "https://canyon.com", country: "DE", tier: 1 },
{ name: "Specialized", slug: "specialized", website: "https://specialized.com", country: "US", tier: 1 },
{ name: "Trek", slug: "trek", website: "https://trekbikes.com", country: "US", tier: 1 },
{ name: "Salsa Cycles", slug: "salsa-cycles", website: "https://salsacycles.com", country: "US", tier: 1 },
{ name: "Surly", slug: "surly", website: "https://surlybikes.com", country: "US", tier: 1 },
{
name: "Revelate Designs",
slug: "revelate-designs",
website: "https://revelatedesigns.com",
country: "US",
tier: 1,
},
{
name: "Apidura",
slug: "apidura",
website: "https://apidura.com",
country: "GB",
tier: 1,
},
{
name: "Ortlieb",
slug: "ortlieb",
website: "https://ortlieb.com",
country: "DE",
tier: 1,
},
{
name: "Big Agnes",
slug: "big-agnes",
website: "https://bigagnes.com",
country: "US",
tier: 1,
},
{
name: "Tarptent",
slug: "tarptent",
website: "https://tarptent.com",
country: "US",
tier: 1,
},
{
name: "Zpacks",
slug: "zpacks",
website: "https://zpacks.com",
country: "US",
tier: 1,
},
{
name: "Sea to Summit",
slug: "sea-to-summit",
website: "https://seatosummit.com",
country: "AU",
tier: 1,
},
{
name: "Western Mountaineering",
slug: "western-mountaineering",
website: "https://westernmountaineering.com",
country: "US",
tier: 1,
},
{
name: "MSR",
slug: "msr",
website: "https://msrgear.com",
country: "US",
tier: 1,
},
{
name: "BioLite",
slug: "biolite",
website: "https://bioliteenergy.com",
country: "US",
tier: 1,
},
{
name: "Petzl",
slug: "petzl",
website: "https://petzl.com",
country: "FR",
tier: 1,
},
{
name: "Black Diamond",
slug: "black-diamond",
website: "https://blackdiamondequipment.com",
country: "US",
tier: 1,
},
{
name: "Garmin",
slug: "garmin",
website: "https://garmin.com",
country: "US",
tier: 1,
},
{
name: "Wahoo",
slug: "wahoo",
website: "https://wahoofitness.com",
country: "US",
tier: 1,
},
{
name: "Sawyer",
slug: "sawyer",
website: "https://sawyerproducts.com",
country: "US",
tier: 1,
},
{
name: "Canyon",
slug: "canyon",
website: "https://canyon.com",
country: "DE",
tier: 1,
},
{
name: "Specialized",
slug: "specialized",
website: "https://specialized.com",
country: "US",
tier: 1,
},
{
name: "Trek",
slug: "trek",
website: "https://trekbikes.com",
country: "US",
tier: 1,
},
{
name: "Salsa Cycles",
slug: "salsa-cycles",
website: "https://salsacycles.com",
country: "US",
tier: 1,
},
{
name: "Surly",
slug: "surly",
website: "https://surlybikes.com",
country: "US",
tier: 1,
},
// Additional manufacturers referenced in seed data
{ name: "Nemo", slug: "nemo", website: "https://nemoequipment.com", country: "US", tier: 1 },
{ name: "Therm-a-Rest", slug: "therm-a-rest", website: "https://thermarest.com", country: "US", tier: 1 },
{ name: "Toaks", slug: "toaks", website: "https://toaksoutdoor.com", country: "CN", tier: 1 },
{ name: "Katadyn", slug: "katadyn", website: "https://katadyn.com", country: "CH", tier: 1 },
{ name: "HydraPak", slug: "hydrapak", website: "https://hydrapak.com", country: "US", tier: 1 },
{ name: "Nitecore", slug: "nitecore", website: "https://nitecore.com", country: "CN", tier: 1 },
{ name: "Outdoor Research", slug: "outdoor-research", website: "https://outdoorresearch.com", country: "US", tier: 1 },
{ name: "Exposure Lights", slug: "exposure-lights", website: "https://exposurelights.com", country: "GB", tier: 1 },
{
name: "Nemo",
slug: "nemo",
website: "https://nemoequipment.com",
country: "US",
tier: 1,
},
{
name: "Therm-a-Rest",
slug: "therm-a-rest",
website: "https://thermarest.com",
country: "US",
tier: 1,
},
{
name: "Toaks",
slug: "toaks",
website: "https://toaksoutdoor.com",
country: "CN",
tier: 1,
},
{
name: "Katadyn",
slug: "katadyn",
website: "https://katadyn.com",
country: "CH",
tier: 1,
},
{
name: "HydraPak",
slug: "hydrapak",
website: "https://hydrapak.com",
country: "US",
tier: 1,
},
{
name: "Nitecore",
slug: "nitecore",
website: "https://nitecore.com",
country: "CN",
tier: 1,
},
{
name: "Outdoor Research",
slug: "outdoor-research",
website: "https://outdoorresearch.com",
country: "US",
tier: 1,
},
{
name: "Exposure Lights",
slug: "exposure-lights",
website: "https://exposurelights.com",
country: "GB",
tier: 1,
},
];
const SEED_TAGS = [
"bikepacking", "cycling", "hiking", "backpacking", "camping", "climbing",
"mountaineering", "road-cycling", "gravel", "running", "trail-running",
"handlebar-bag", "framebag", "saddlebag", "top-tube-bag", "stem-bag",
"fork-bag", "feed-bag", "dry-bag", "stuff-sack", "bike-bag",
"tent", "bivy", "tarp", "hammock",
"sleeping-bag", "sleeping-pad", "quilt", "pillow",
"stove", "cookware", "mug", "utensils",
"water-filter", "water-bottle",
"headlamp", "bike-light", "lantern",
"gps", "bike-computer", "power-bank", "solar-panel",
"multi-tool", "pump", "repair-kit", "lock",
"rain-jacket", "base-layer", "gloves", "shoe",
"bikepacking",
"cycling",
"hiking",
"backpacking",
"camping",
"climbing",
"mountaineering",
"road-cycling",
"gravel",
"running",
"trail-running",
"handlebar-bag",
"framebag",
"saddlebag",
"top-tube-bag",
"stem-bag",
"fork-bag",
"feed-bag",
"dry-bag",
"stuff-sack",
"bike-bag",
"tent",
"bivy",
"tarp",
"hammock",
"sleeping-bag",
"sleeping-pad",
"quilt",
"pillow",
"stove",
"cookware",
"mug",
"utensils",
"water-filter",
"water-bottle",
"headlamp",
"bike-light",
"lantern",
"gps",
"bike-computer",
"power-bank",
"solar-panel",
"multi-tool",
"pump",
"repair-kit",
"lock",
"rain-jacket",
"base-layer",
"gloves",
"shoe",
];
export async function seedManufacturers(db: Db = prodDb) {
for (const m of SEED_MANUFACTURERS) {
await db
.insert(manufacturers)
.values(m)
.onConflictDoNothing();
await db.insert(manufacturers).values(m).onConflictDoNothing();
}
}