diff --git a/src/app/my-builds/page.tsx b/src/app/my-builds/page.tsx
new file mode 100644
index 0000000..57e380c
--- /dev/null
+++ b/src/app/my-builds/page.tsx
@@ -0,0 +1,417 @@
+'use client';
+
+import { useState } from 'react';
+import SearchInput from '@/components/SearchInput';
+
+// Sample build data
+const sampleMyBuilds = [
+ {
+ id: '1',
+ name: 'Budget AR-15 Build',
+ description: 'A cost-effective AR-15 build using quality budget components',
+ status: 'completed' as const,
+ totalCost: 847.50,
+ completedDate: '2024-01-15',
+ components: {
+ total: 18,
+ completed: 18,
+ categories: {
+ 'Upper': 8,
+ 'Lower': 7,
+ 'Accessory': 3
+ }
+ },
+ tags: ['Budget', '5.56 NATO', '16" Barrel'],
+ image: 'https://picsum.photos/400/250?random=1'
+ },
+ {
+ id: '2',
+ name: 'Precision Long Range',
+ description: 'High-end precision build optimized for long-range accuracy',
+ status: 'in-progress' as const,
+ totalCost: 2847.99,
+ startedDate: '2024-02-01',
+ components: {
+ total: 18,
+ completed: 12,
+ categories: {
+ 'Upper': 6,
+ 'Lower': 4,
+ 'Accessory': 2
+ }
+ },
+ tags: ['Precision', '6.5 Creedmoor', '20" Barrel'],
+ image: 'https://picsum.photos/400/250?random=2'
+ },
+ {
+ id: '3',
+ name: 'Home Defense Setup',
+ description: 'Compact AR-15 configured for home defense scenarios',
+ status: 'planning' as const,
+ totalCost: 0,
+ plannedDate: '2024-03-01',
+ components: {
+ total: 18,
+ completed: 0,
+ categories: {
+ 'Upper': 0,
+ 'Lower': 0,
+ 'Accessory': 0
+ }
+ },
+ tags: ['Home Defense', '5.56 NATO', '10.5" Barrel'],
+ image: 'https://picsum.photos/400/250?random=3'
+ },
+ {
+ id: '4',
+ name: 'Competition Rifle',
+ description: 'Lightweight competition build for 3-gun matches',
+ status: 'completed' as const,
+ totalCost: 1650.75,
+ completedDate: '2023-12-10',
+ components: {
+ total: 18,
+ completed: 18,
+ categories: {
+ 'Upper': 8,
+ 'Lower': 7,
+ 'Accessory': 3
+ }
+ },
+ tags: ['Competition', '5.56 NATO', '18" Barrel'],
+ image: 'https://picsum.photos/400/250?random=4'
+ },
+ {
+ id: '5',
+ name: 'Suppressed SBR',
+ description: 'Short-barreled rifle build with suppressor integration',
+ status: 'in-progress' as const,
+ totalCost: 1895.25,
+ startedDate: '2024-01-20',
+ components: {
+ total: 18,
+ completed: 8,
+ categories: {
+ 'Upper': 4,
+ 'Lower': 3,
+ 'Accessory': 1
+ }
+ },
+ tags: ['SBR', 'Suppressed', '300 BLK'],
+ image: 'https://picsum.photos/400/250?random=5'
+ },
+ {
+ id: '6',
+ name: 'Retro M16A1 Clone',
+ description: 'Faithful reproduction of the classic M16A1 rifle',
+ status: 'planning' as const,
+ totalCost: 0,
+ plannedDate: '2024-04-01',
+ components: {
+ total: 18,
+ completed: 0,
+ categories: {
+ 'Upper': 0,
+ 'Lower': 0,
+ 'Accessory': 0
+ }
+ },
+ tags: ['Retro', '5.56 NATO', '20" Barrel'],
+ image: 'https://picsum.photos/400/250?random=6'
+ }
+];
+
+type MyBuildStatus = 'completed' | 'in-progress' | 'planning';
+type SortField = 'name' | 'status' | 'totalCost' | 'completedDate';
+type SortDirection = 'asc' | 'desc';
+
+export default function MyBuildsPage() {
+ const [sortField, setSortField] = useState
('completedDate');
+ const [sortDirection, setSortDirection] = useState('desc');
+ const [selectedStatus, setSelectedStatus] = useState('all');
+ const [searchTerm, setSearchTerm] = useState('');
+
+ // Filter builds
+ const filteredMyBuilds = sampleMyBuilds.filter(build => {
+ if (selectedStatus !== 'all' && build.status !== selectedStatus) {
+ return false;
+ }
+
+ if (searchTerm && !build.name.toLowerCase().includes(searchTerm.toLowerCase()) &&
+ !build.description.toLowerCase().includes(searchTerm.toLowerCase())) {
+ return false;
+ }
+
+ return true;
+ });
+
+ // Sort builds
+ const sortedMyBuilds = [...filteredMyBuilds].sort((a, b) => {
+ let aValue: any, bValue: any;
+
+ if (sortField === 'totalCost') {
+ aValue = a.totalCost;
+ bValue = b.totalCost;
+ } else if (sortField === 'status') {
+ aValue = a.status;
+ bValue = b.status;
+ } else if (sortField === 'completedDate') {
+ aValue = a.completedDate || a.startedDate || a.plannedDate || '';
+ bValue = b.completedDate || b.startedDate || b.plannedDate || '';
+ } else {
+ aValue = a.name.toLowerCase();
+ bValue = b.name.toLowerCase();
+ }
+
+ if (sortDirection === 'asc') {
+ return aValue > bValue ? 1 : -1;
+ } else {
+ return aValue < bValue ? 1 : -1;
+ }
+ });
+
+ const getStatusColor = (status: MyBuildStatus) => {
+ switch (status) {
+ case 'completed':
+ return 'bg-green-100 text-green-800';
+ case 'in-progress':
+ return 'bg-blue-100 text-blue-800';
+ case 'planning':
+ return 'bg-yellow-100 text-yellow-800';
+ default:
+ return 'bg-gray-100 text-gray-800';
+ }
+ };
+
+ const getStatusIcon = (status: MyBuildStatus) => {
+ switch (status) {
+ case 'completed':
+ return '✓';
+ case 'in-progress':
+ return '🔄';
+ case 'planning':
+ return '📋';
+ default:
+ return '❓';
+ }
+ };
+
+ const formatDate = (dateString: string) => {
+ return new Date(dateString).toLocaleDateString('en-US', {
+ year: 'numeric',
+ month: 'short',
+ day: 'numeric'
+ });
+ };
+
+ const getProgressPercentage = (build: typeof sampleMyBuilds[0]) => {
+ return Math.round((build.components.completed / build.components.total) * 100);
+ };
+
+ const totalMyBuilds = sampleMyBuilds.length;
+ const completedMyBuilds = sampleMyBuilds.filter(build => build.status === 'completed').length;
+ const inProgressMyBuilds = sampleMyBuilds.filter(build => build.status === 'in-progress').length;
+ const totalValue = sampleMyBuilds.reduce((sum, build) => sum + build.totalCost, 0);
+
+ return (
+
+ {/* Page Title */}
+
+
+
My Builds
+
Track and manage your firearm builds
+
+
+
+ {/* Build Summary */}
+
+
+
+
+
{totalMyBuilds}
+
Total Builds
+
+
+
{completedMyBuilds}
+
Completed
+
+
+
{inProgressMyBuilds}
+
In Progress
+
+
+
${totalValue.toFixed(2)}
+
Total Value
+
+
+
+
+
+ {/* Search and Filters */}
+
+
+ {/* Filters Row */}
+
+ {/* Status Filter */}
+
+
+
+
+
+ {/* Sort by */}
+
+
+
+
+
+ {/* Sort Direction */}
+
+
+
+
+
+ {/* New Build Button */}
+
+
+
+
+
+
+
+ {/* Builds Grid */}
+
+ {sortedMyBuilds.length > 0 ? (
+
+ {sortedMyBuilds.map((build) => (
+
+ {/* Build Image */}
+
+

{
+ const target = e.target as HTMLImageElement;
+ target.style.display = 'none';
+ target.nextElementSibling?.classList.remove('hidden');
+ }}
+ />
+
+
+
+ {getStatusIcon(build.status)} {build.status}
+
+
+
+
+ {/* Build Content */}
+
+ {/* Build Title and Date */}
+
+
{build.name}
+
{build.description}
+
+ {build.status === 'completed' && build.completedDate && `Completed ${formatDate(build.completedDate)}`}
+ {build.status === 'in-progress' && build.startedDate && `Started ${formatDate(build.startedDate)}`}
+ {build.status === 'planning' && build.plannedDate && `Planned for ${formatDate(build.plannedDate)}`}
+
+
+
+ {/* Progress Bar */}
+
+
+ Progress
+ {build.components.completed}/{build.components.total} components
+
+
+
+
+ {/* Component Categories */}
+
+
+ {Object.entries(build.components.categories).map(([category, count]) => (
+
+ {category}: {count}
+
+ ))}
+
+
+
+ {/* Tags */}
+
+
+ {build.tags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+ {/* Cost and Actions */}
+
+
+ ${build.totalCost.toFixed(2)}
+
+
+
+
+
+
+
+
+ ))}
+
+ ) : (
+
+
+
No builds found
+
Try adjusting your filters or create a new build
+
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/parts/page.tsx b/src/app/parts/page.tsx
index 57bb679..8246ec1 100644
--- a/src/app/parts/page.tsx
+++ b/src/app/parts/page.tsx
@@ -3,7 +3,7 @@
import { useState, useEffect } from 'react';
import { useSearchParams } from 'next/navigation';
import { Listbox, Transition } from '@headlessui/react';
-import { ChevronUpDownIcon, CheckIcon, XMarkIcon } from '@heroicons/react/20/solid';
+import { ChevronUpDownIcon, CheckIcon, XMarkIcon, TableCellsIcon, Squares2X2Icon } from '@heroicons/react/20/solid';
import SearchInput from '@/components/SearchInput';
import ProductCard from '@/components/ProductCard';
import RestrictionAlert from '@/components/RestrictionAlert';
@@ -11,6 +11,7 @@ import Tooltip from '@/components/Tooltip';
import Link from 'next/link';
import { mockProducts } from '@/mock/product';
import type { Product } from '@/mock/product';
+import Image from 'next/image';
// Extract unique values for dropdowns
const categories = ['All', ...Array.from(new Set(mockProducts.map(part => part.category.name)))];
@@ -464,14 +465,16 @@ export default function Home() {