From 5c046874a8b3eff87eed8267d47c75633bf4acd1 Mon Sep 17 00:00:00 2001 From: Sean S Date: Mon, 30 Jun 2025 13:34:27 -0400 Subject: [PATCH] most working data fetch. --- src/app/globals.css | 55 ++++++++++ src/app/parts/categoryMapping.ts | 122 ++++----------------- src/app/parts/page.tsx | 86 +++++++-------- src/app/products/{[id] => [slug]}/page.tsx | 0 src/components/Providers.tsx | 2 +- src/components/ThemeProvider.tsx | 8 +- src/components/ThemeSwitcher.tsx | 4 +- 7 files changed, 128 insertions(+), 149 deletions(-) rename src/app/products/{[id] => [slug]}/page.tsx (100%) diff --git a/src/app/globals.css b/src/app/globals.css index b5c61c9..f5396c5 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,3 +1,58 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@layer base { + html { + scroll-behavior: smooth; + } + + body { + @apply transition-colors duration-200; + } + } + + @layer components { + /* Custom scrollbar for webkit browsers */ + ::-webkit-scrollbar { + width: 8px; + } + + ::-webkit-scrollbar-track { + @apply bg-zinc-100 dark:bg-zinc-800; + } + + ::-webkit-scrollbar-thumb { + @apply bg-zinc-300 dark:bg-zinc-600 rounded-full; + } + + ::-webkit-scrollbar-thumb:hover { + @apply bg-zinc-400 dark:bg-zinc-500; + } + + /* Focus styles for better accessibility */ + .focus-ring { + @apply focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 dark:focus:ring-offset-zinc-900; + } + + /* Card styles */ + .card { + @apply bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200; + } + + /* Button styles */ + /* Removed custom .btn-primary to avoid DaisyUI conflict */ + + /* Input styles */ + .input-field { + @apply w-full px-3 py-2 border border-zinc-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white placeholder-zinc-500 dark:placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-colors duration-200; + } + } + + @keyframes float { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-8px); } + } + .animate-float { + animation: float 4s ease-in-out infinite; + } \ No newline at end of file diff --git a/src/app/parts/categoryMapping.ts b/src/app/parts/categoryMapping.ts index 8653504..cf51313 100644 --- a/src/app/parts/categoryMapping.ts +++ b/src/app/parts/categoryMapping.ts @@ -1,93 +1,30 @@ -// Auto-generated mapping from product feed categories (all_categories.csv) -// to standardized builder component types (component_type.csv) -// Refine as needed for your builder logic +// Minimal, future-proof category mapping for builder logic export const categoryToComponentType: Record = { - "Sporting Bolt Action Centerfire Rifles": "N/A", - "HANDGUN SIGHTS": "N/A", - "Synthetic Holsters": "N/A", - "Scope Mounts": "Accessories", - "Short Barrel Shotguns": "N/A", - "Polymer Centerfire Conceal Carry Pistols": "N/A", - "LESS LETHAL AMMO": "N/A", - "LESS LETHAL PISTOL": "N/A", - "Rifle/Shotgun Combos": "N/A", - "Leveraction Shotguns": "N/A", - "Specialty Pistols": "N/A", - "Miscellaneous Accessories": "N/A", - "LESS LETHAL ACCESSORIES": "N/A", - "Tactical Rimfire Semi-Auto Rifles": "N/A", - "Sporting Semi-Auto Rimfire Rifles": "N/A", - "Lower Receivers": "Lower Receiver", - "Handgun Magazines": "Magazine", - "Non-Magnified Optic Mounts": "Accessories", - "Magnified Tactical Optics": "Accessories", - "BOLT ACTION SHOTGUN": "N/A", - "Sporting Semi-Auto Shotguns": "N/A", - "Metal Frame Centerfire Pistols": "N/A", - "THERMAL OPTICS": "Accessories", - "Sporting Leveraction Rimfire Rifles": "N/A", - "Pump Rimfire Rifles": "N/A", - "TACTICAL CENTERFIRE SEMI-AUTO PISTOLS": "N/A", - "Single Action Centerfire Revolvers": "N/A", - "Range Finders": "N/A", - "Metal Frame Rimfire Pistols": "N/A", - "Sporting Bolt Action Rimfire Rifles": "N/A", - "Side by Side Shotguns": "N/A", - "Lasers and Lights": "N/A", - "Tactical Pump Shotguns": "N/A", - "Binoculars": "N/A", - "Double Action Centerfire Revolvers": "N/A", - "Tactical Semi-Auto Shotguns": "N/A", - "Scopes": "Accessories", - "Silencer Mounts": "N/A", - "Double Action Centrfire Conceal Revolver": "N/A", - "Sporting Semi-Auto Centerfire Rifles": "N/A", - "FIRE CONTROL UNIT": "N/A", - "Spotting Scopes": "N/A", - "Single Shot Centerfire Rifles": "N/A", - "Derringers": "N/A", - "Pump Centerfire Rifles": "N/A", - "Double Action Rimfire Revolvers": "N/A", - "Tactical Centerfire Semi-Auto Rifles": "N/A", - "Handgun Accessories": "N/A", - "Sporting Leveraction Centerfire Rifles": "N/A", - "Single Shot Shotguns": "N/A", - "Polymer Rimfire Pistols": "N/A", - "LESS LETHAL RIFLE": "N/A", - "Short Barrel Rifles": "N/A", - "Black Powder Guns": "N/A", - "Over/Under Shotguns": "N/A", - "TACTICAL RIMFIRE SEMI-AUTO PISTOL": "N/A", - "Non-Magnified Optic Accessories": "N/A", - "Scope Accessories": "N/A", - "Scope Rings": "N/A", - "Rimfire Silencers": "N/A", - "Non-Magnified Optics": "N/A", - "Metal Frame Centerfire Conceal Pistols": "N/A", - "LONG GUN SIGHTS": "N/A", - "UPPER RECEIVERS": "Upper Receiver", - "Double Action Rimfire Conceal Revolvers": "N/A", - "Rifle Magazines": "Magazine", - "Rifle Accessories": "N/A", - "Silencer Pistons": "N/A", - "Shotgun Silencers": "N/A", - "Tactical Bolt Action Rifles": "N/A", - "Centerfire Ammo": "N/A", - "Single Action Rimfire Revolvers": "N/A", - "Leather Holsters": "N/A", - "AR Style Centerfire Rifles": "N/A", - "Centerfire Pistol Silencers": "N/A", - "Single Shot Rimfire Rifles": "N/A", - "Silencer Accessories": "N/A", - "Sporting Pump Shotguns": "N/A", - "Single Shot Handguns": "N/A", - "Centerfire Rifle Silencers": "N/A", - "Polymer Centerfire Pistols": "N/A", - "Magnified Tactical Optic Mounts": "N/A", - "SHOTGUN MAGAZINES": "Magazine", - "BLACK POWDER FIREARMS (ATF CONTROLLED)": "N/A" + "Muzzle Devices": "Muzzle Device", + "Receiver Parts": "Lower Receiver", + "Barrel Parts": "Barrel", + "Stock Parts": "Stock", + "Bolt Parts": "Bolt Carrier Group", + "Triggers Parts": "Trigger", + "Sights": "Accessories" }; +// Map category to builder component type, with fallback heuristics +export function mapToBuilderType(category: string): string { + if (categoryToComponentType[category]) { + return categoryToComponentType[category]; + } + // Fallback: guess based on keywords + if (category?.toLowerCase().includes('barrel')) return 'Barrel'; + if (category?.toLowerCase().includes('stock')) return 'Stock'; + if (category?.toLowerCase().includes('bolt')) return 'Bolt Carrier Group'; + if (category?.toLowerCase().includes('trigger')) return 'Trigger'; + if (category?.toLowerCase().includes('sight') || category?.toLowerCase().includes('optic')) return 'Accessories'; + // Log for future mapping + console.warn('Unmapped category:', category); + return 'Accessories'; +} + // List of standardized builder component types (from component_type.csv) export const standardizedComponentTypes = [ "Upper Receiver", @@ -110,17 +47,6 @@ export const standardizedComponentTypes = [ "Accessories" ]; -// Hybrid mapping function: prefer subcategory, fallback to category -export function mapToBuilderType(category: string, subcategory: string): string { - if (standardizedComponentTypes.includes(subcategory)) { - return subcategory; - } - if (standardizedComponentTypes.includes(category)) { - return category; - } - return "N/A"; -} - // Builder category hierarchy for filters export const builderCategories = [ { diff --git a/src/app/parts/page.tsx b/src/app/parts/page.tsx index 305f8f1..b083ccf 100644 --- a/src/app/parts/page.tsx +++ b/src/app/parts/page.tsx @@ -132,11 +132,11 @@ const Dropdown = ({
- + {label} - - + + {value || placeholder} @@ -151,7 +151,7 @@ const Dropdown = ({ leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0" - className="absolute z-20 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white dark:bg-zinc-800 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" + className="absolute z-20 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" > {options.map((option, optionIdx) => ( @@ -159,7 +159,7 @@ const Dropdown = ({ key={optionIdx} className={({ active }) => `relative cursor-default select-none py-2 pl-10 pr-4 ${ - active ? 'bg-primary-100 dark:bg-primary-900 text-primary-900 dark:text-primary-100' : 'text-zinc-900 dark:text-white' + active ? 'bg-primary-100 text-primary-900' : 'text-zinc-900' }` } value={option.value} @@ -170,7 +170,7 @@ const Dropdown = ({ {option.label} {selected ? ( - + ) : null} @@ -439,19 +439,19 @@ export default function Home() { }, [products]); return ( -
+
{/* Page Title */} -
+
-

+

Parts Catalog {selectedCategory && selectedCategoryId !== 'all' && ( - + - {selectedCategory.name} )}

-

+

{selectedCategory && selectedCategoryId !== 'all' ? `Showing ${selectedCategory.name} parts for your build` : 'Browse and filter firearm parts for your build' @@ -461,7 +461,7 @@ export default function Home() {

{/* Search and Filters */} -
+
{/* Search Row */}
@@ -481,7 +481,7 @@ export default function Home() { setIsSearchExpanded(false); setSearchTerm(''); }} - className="p-2 text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200 transition-colors flex-shrink-0" + className="p-2 text-zinc-500 hover:text-zinc-700 transition-colors flex-shrink-0" aria-label="Close search" > @@ -490,7 +490,7 @@ export default function Home() { ) : (