1
- import { useState } from 'react' ;
2
1
import Head from 'next/head' ;
3
2
import Layout from '@/components/Layout/Layout.component' ;
4
- import ProductCard from '@/components/Product/ProductCard.component' ;
5
- import ProductFilters from '@/components/Product/ProductFilters.component' ;
3
+ import ProductList from '@/components/Product/ProductList.component' ;
6
4
import client from '@/utils/apollo/ApolloClient' ;
7
5
import { FETCH_ALL_PRODUCTS_QUERY } from '@/utils/gql/GQL_QUERIES' ;
8
6
import type { NextPage , GetStaticProps , InferGetStaticPropsType } from 'next' ;
9
-
10
- import { Product , ProductCategory , ProductType , SizeNode , ColorNode } from '@/types/product' ;
11
- import { getUniqueProductTypes } from '@/utils/functions/productUtils' ;
7
+ import { Product } from '@/types/product' ;
12
8
13
9
const Products2 : NextPage = ( {
14
10
products,
15
11
loading,
16
12
} : InferGetStaticPropsType < typeof getStaticProps > ) => {
17
- const [ sortBy , setSortBy ] = useState ( 'popular' ) ;
18
- const [ selectedSizes , setSelectedSizes ] = useState < string [ ] > ( [ ] ) ;
19
- const [ selectedColors , setSelectedColors ] = useState < string [ ] > ( [ ] ) ;
20
- const [ priceRange , setPriceRange ] = useState < [ number , number ] > ( [ 0 , 1000 ] ) ;
21
- const [ productTypes , setProductTypes ] = useState < ProductType [ ] > ( ( ) =>
22
- products ? getUniqueProductTypes ( products ) : [ ]
23
- ) ;
24
-
25
- const toggleProductType = ( id : string ) => {
26
- setProductTypes ( prev => prev . map ( type =>
27
- type . id === id ? { ...type , checked : ! type . checked } : type
28
- ) ) ;
29
- } ;
30
-
31
- const resetFilters = ( ) => {
32
- setSelectedSizes ( [ ] ) ;
33
- setSelectedColors ( [ ] ) ;
34
- setPriceRange ( [ 0 , 1000 ] ) ;
35
- setProductTypes ( prev => prev . map ( type => ( { ...type , checked : false } ) ) ) ;
36
- } ;
37
-
38
- // Filter products based on selected filters
39
- const filteredProducts = products ?. filter ( ( product : Product ) => {
40
- // Filter by price
41
- const productPrice = parseFloat ( product . price . replace ( / [ ^ 0 - 9 . ] / g, '' ) ) ;
42
- const withinPriceRange = productPrice >= priceRange [ 0 ] && productPrice <= priceRange [ 1 ] ;
43
- if ( ! withinPriceRange ) return false ;
44
-
45
- // Filter by product type
46
- const selectedTypes = productTypes . filter ( t => t . checked ) . map ( t => t . name . toLowerCase ( ) ) ;
47
- if ( selectedTypes . length > 0 ) {
48
- const productCategories = product . productCategories ?. nodes . map ( ( cat : ProductCategory ) => cat . name . toLowerCase ( ) ) || [ ] ;
49
- if ( ! selectedTypes . some ( type => productCategories . includes ( type ) ) ) return false ;
50
- }
51
-
52
- // Filter by size
53
- if ( selectedSizes . length > 0 ) {
54
- const productSizes = product . allPaSizes ?. nodes . map ( ( node : SizeNode ) => node . name ) || [ ] ;
55
- if ( ! selectedSizes . some ( size => productSizes . includes ( size ) ) ) return false ;
56
- }
57
-
58
- // Filter by color
59
- if ( selectedColors . length > 0 ) {
60
- const productColors = product . allPaColors ?. nodes . map ( ( node : ColorNode ) => node . name ) || [ ] ;
61
- if ( ! selectedColors . some ( color => productColors . includes ( color ) ) ) return false ;
62
- }
63
-
64
- return true ;
65
- } ) ;
66
-
67
- // Sort products
68
- const sortedProducts = [ ...( filteredProducts || [ ] ) ] . sort ( ( a , b ) => {
69
- const priceA = parseFloat ( a . price . replace ( / [ ^ 0 - 9 . ] / g, '' ) ) ;
70
- const priceB = parseFloat ( b . price . replace ( / [ ^ 0 - 9 . ] / g, '' ) ) ;
71
-
72
- switch ( sortBy ) {
73
- case 'price-low' :
74
- return priceA - priceB ;
75
- case 'price-high' :
76
- return priceB - priceA ;
77
- case 'newest' :
78
- return b . databaseId - a . databaseId ;
79
- default : // 'popular'
80
- return 0 ;
81
- }
82
- } ) ;
83
-
84
- if ( loading ) return (
85
- < Layout title = "Produkter" >
86
- < div className = "flex justify-center items-center min-h-screen" >
87
- < div className = "animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900" > </ div >
88
- </ div >
89
- </ Layout >
90
- ) ;
91
-
92
- if ( ! products ) return (
93
- < Layout title = "Produkter" >
94
- < div className = "flex justify-center items-center min-h-screen" >
95
- < p className = "text-red-500" > Ingen produkter funnet</ p >
96
- </ div >
97
- </ Layout >
98
- ) ;
13
+ if ( loading )
14
+ return (
15
+ < Layout title = "Produkter" >
16
+ < div className = "flex justify-center items-center min-h-screen" >
17
+ < div className = "animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-gray-900" > </ div >
18
+ </ div >
19
+ </ Layout >
20
+ ) ;
21
+
22
+ if ( ! products )
23
+ return (
24
+ < Layout title = "Produkter" >
25
+ < div className = "flex justify-center items-center min-h-screen" >
26
+ < p className = "text-red-500" > Ingen produkter funnet</ p >
27
+ </ div >
28
+ </ Layout >
29
+ ) ;
99
30
100
31
return (
101
32
< Layout title = "Produkter" >
@@ -104,56 +35,7 @@ const Products2: NextPage = ({
104
35
</ Head >
105
36
106
37
< div className = "container mx-auto px-4 py-8" >
107
- < div className = "flex flex-col md:flex-row gap-8" >
108
- < ProductFilters
109
- selectedSizes = { selectedSizes }
110
- setSelectedSizes = { setSelectedSizes }
111
- selectedColors = { selectedColors }
112
- setSelectedColors = { setSelectedColors }
113
- priceRange = { priceRange }
114
- setPriceRange = { setPriceRange }
115
- productTypes = { productTypes }
116
- toggleProductType = { toggleProductType }
117
- products = { products }
118
- resetFilters = { resetFilters }
119
- />
120
-
121
- { /* Main Content */ }
122
- < div className = "flex-1" >
123
- < div className = "flex justify-between items-center mb-8" >
124
- < h1 className = "text-2xl font-medium" >
125
- Herreklær < span className = "text-gray-500" > ({ sortedProducts . length } )</ span >
126
- </ h1 >
127
-
128
- < div className = "flex items-center gap-4" >
129
- < label className = "text-sm" > Vis produkter:</ label >
130
- < select
131
- value = { sortBy }
132
- onChange = { ( e ) => setSortBy ( e . target . value ) }
133
- className = "border rounded-md px-3 py-1"
134
- >
135
- < option value = "popular" > Populær</ option >
136
- < option value = "price-low" > Pris: Lav til Høy</ option >
137
- < option value = "price-high" > Pris: Høy til Lav</ option >
138
- < option value = "newest" > Nyeste</ option >
139
- </ select >
140
- </ div >
141
- </ div >
142
-
143
- < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" >
144
- { sortedProducts . map ( ( product : Product ) => (
145
- < ProductCard
146
- key = { product . databaseId }
147
- databaseId = { product . databaseId }
148
- name = { product . name }
149
- price = { product . price }
150
- slug = { product . slug }
151
- image = { product . image }
152
- />
153
- ) ) }
154
- </ div >
155
- </ div >
156
- </ div >
38
+ < ProductList products = { products } title = "Herreklær" />
157
39
</ div >
158
40
</ Layout >
159
41
) ;
0 commit comments