'use client'; import { useState } from 'react'; import Link from 'next/link'; import React from 'react'; // AR-15 Build Requirements grouped by main categories const buildGroups = [ { name: 'Upper Parts', description: 'Components that make up the upper receiver assembly', components: [ { id: 'upper-receiver', name: 'Upper Receiver', category: 'Upper', description: 'The upper receiver houses the barrel, bolt carrier group, and charging handle', required: true, status: 'pending', estimatedPrice: 150, notes: 'Can be purchased as complete upper or stripped' }, { id: 'barrel', name: 'Barrel', category: 'Upper', description: 'The barrel determines accuracy and caliber compatibility', required: true, status: 'pending', estimatedPrice: 200, notes: 'Common lengths: 16", 18", 20"' }, { id: 'bolt-carrier-group', name: 'Bolt Carrier Group (BCG)', category: 'Upper', description: 'Handles the firing, extraction, and ejection of rounds', required: true, status: 'pending', estimatedPrice: 150, notes: 'Mil-spec or enhanced options available' }, { id: 'charging-handle', name: 'Charging Handle', category: 'Upper', description: 'Allows manual operation of the bolt carrier group', required: true, status: 'pending', estimatedPrice: 50, notes: 'Standard or ambidextrous options' }, { id: 'gas-block', name: 'Gas Block', category: 'Upper', description: 'Controls gas flow from barrel to BCG', required: true, status: 'pending', estimatedPrice: 30, notes: 'Low-profile for free-float handguards' }, { id: 'gas-tube', name: 'Gas Tube', category: 'Upper', description: 'Transfers gas from barrel to BCG', required: true, status: 'pending', estimatedPrice: 15, notes: 'Carbine, mid-length, or rifle length' }, { id: 'handguard', name: 'Handguard', category: 'Upper', description: 'Provides grip and mounting points for accessories', required: true, status: 'pending', estimatedPrice: 100, notes: 'Free-float or drop-in options' }, { id: 'muzzle-device', name: 'Muzzle Device', category: 'Upper', description: 'Flash hider, compensator, or suppressor mount', required: true, status: 'pending', estimatedPrice: 80, notes: 'A2 flash hider is standard' } ] }, { name: 'Lower Parts', description: 'Components that make up the lower receiver assembly', components: [ { id: 'lower-receiver', name: 'Lower Receiver', category: 'Lower', description: 'The lower receiver contains the trigger group and magazine well', required: true, status: 'pending', estimatedPrice: 100, notes: 'Must be purchased through FFL dealer' }, { id: 'trigger', name: 'Trigger', category: 'Lower', description: 'Controls firing mechanism', required: true, status: 'pending', estimatedPrice: 60, notes: 'Mil-spec or enhanced triggers available' }, { id: 'trigger-guard', name: 'Trigger Guard', category: 'Lower', description: 'Protects trigger from accidental discharge', required: true, status: 'pending', estimatedPrice: 10, notes: 'Often included with lower receiver' }, { id: 'pistol-grip', name: 'Pistol Grip', category: 'Lower', description: 'Provides grip for firing hand', required: true, status: 'pending', estimatedPrice: 25, notes: 'Various ergonomic options available' }, { id: 'buffer-tube', name: 'Buffer Tube', category: 'Lower', description: 'Houses buffer and spring for recoil management', required: true, status: 'pending', estimatedPrice: 40, notes: 'Carbine, A5, or rifle length' }, { id: 'buffer', name: 'Buffer', category: 'Lower', description: 'Absorbs recoil energy', required: true, status: 'pending', estimatedPrice: 20, notes: 'H1, H2, H3 weights available' }, { id: 'buffer-spring', name: 'Buffer Spring', category: 'Lower', description: 'Returns BCG to battery position', required: true, status: 'pending', estimatedPrice: 15, notes: 'Standard or enhanced springs' }, { id: 'stock', name: 'Stock', category: 'Lower', description: 'Provides shoulder support and cheek weld', required: true, status: 'pending', estimatedPrice: 60, notes: 'Fixed or adjustable options' } ] }, { name: 'Accessories', description: 'Additional components needed for a complete build', components: [ { id: 'magazine', name: 'Magazine', category: 'Accessory', description: 'Holds and feeds ammunition', required: true, status: 'pending', estimatedPrice: 15, notes: '30-round capacity is standard' }, { id: 'sights', name: 'Sights', category: 'Accessory', description: 'Iron sights or optic for aiming', required: true, status: 'pending', estimatedPrice: 100, notes: 'Backup iron sights recommended' } ] } ]; // Flatten all components for filtering and sorting const allComponents = buildGroups.flatMap(group => group.components); const categories = ["All", "Upper", "Lower", "Accessory"]; type SortField = 'name' | 'category' | 'estimatedPrice' | 'status'; type SortDirection = 'asc' | 'desc'; export default function BuildPage() { const [sortField, setSortField] = useState('name'); const [sortDirection, setSortDirection] = useState('asc'); const [selectedCategory, setSelectedCategory] = useState('All'); const [searchTerm, setSearchTerm] = useState(''); // Filter components const filteredComponents = allComponents.filter(component => { if (selectedCategory !== 'All' && component.category !== selectedCategory) { return false; } if (searchTerm && !component.name.toLowerCase().includes(searchTerm.toLowerCase()) && !component.description.toLowerCase().includes(searchTerm.toLowerCase())) { return false; } return true; }); // Sort components const sortedComponents = [...filteredComponents].sort((a, b) => { let aValue: any, bValue: any; if (sortField === 'estimatedPrice') { aValue = a.estimatedPrice; bValue = b.estimatedPrice; } else if (sortField === 'category') { aValue = a.category.toLowerCase(); bValue = b.category.toLowerCase(); } else if (sortField === 'status') { aValue = a.status.toLowerCase(); bValue = b.status.toLowerCase(); } else { aValue = a.name.toLowerCase(); bValue = b.name.toLowerCase(); } if (sortDirection === 'asc') { return aValue > bValue ? 1 : -1; } else { return aValue < bValue ? 1 : -1; } }); const handleSort = (field: SortField) => { if (sortField === field) { setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc'); } else { setSortField(field); setSortDirection('asc'); } }; const getSortIcon = (field: SortField) => { if (sortField !== field) { return '↕️'; } return sortDirection === 'asc' ? '↑' : '↓'; }; const getStatusColor = (status: string) => { switch (status) { case 'completed': return 'bg-green-100 text-green-800'; case 'pending': return 'bg-yellow-100 text-yellow-800'; case 'in-progress': return 'bg-blue-100 text-blue-800'; default: return 'bg-gray-100 text-gray-800'; } }; const totalEstimatedCost = sortedComponents.reduce((sum, component) => sum + component.estimatedPrice, 0); const completedCount = sortedComponents.filter(component => component.status === 'completed').length; const hasActiveFilters = selectedCategory !== 'All' || searchTerm; return (
{/* Page Title */}

AR-15 Build Checklist

Track your build progress and find required components

{/* Build Summary */}
{allComponents.length}
Total Components
{completedCount}
Completed
{allComponents.length - completedCount}
Remaining
${totalEstimatedCost}
Estimated Cost
{/* Search and Filters */}
{/* Search Row */}
setSearchTerm(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" />
{/* Filters Row */}
{/* Category Dropdown */}
{/* Status Filter */}
{/* Sort by */}
{/* Clear Filters */}
{/* Build Components Table */}
{sortedComponents.length > 0 ? ( buildGroups.map((group) => { // Filter components in this group that match current filters const groupComponents = group.components.filter(component => sortedComponents.some(sorted => sorted.id === component.id) ); if (groupComponents.length === 0) return null; return ( {/* Group Header */} {/* Group Components */} {groupComponents.map((component) => ( ))} ); }) ) : ( )}
Status handleSort('name')} >
Component {getSortIcon('name')}
handleSort('category')} >
Category {getSortIcon('category')}
Description handleSort('estimatedPrice')} >
Est. Price {getSortIcon('estimatedPrice')}
Notes Actions
{group.name === 'Upper Parts' ? '🔫' : group.name === 'Lower Parts' ? '🔧' : '📦'}

{group.name}

{group.description}

{groupComponents.length} components
{component.status}
{component.name}
{component.required ? 'Required' : 'Optional'}
{component.category}
{component.description}
${component.estimatedPrice}
{component.notes}
Find Parts
No components found
Try adjusting your filters or search terms
{/* Table Footer */}
Showing {sortedComponents.length} of {allComponents.length} components {hasActiveFilters && ( (filtered) )}
Total Value: ${sortedComponents.reduce((sum, component) => sum + component.estimatedPrice, 0).toFixed(2)}
); }