@@ -24,6 +24,24 @@ interface Variations {
24
24
nodes : Node [ ] ;
25
25
}
26
26
27
+ interface ProductCategory {
28
+ name : string ;
29
+ slug : string ;
30
+ }
31
+
32
+ interface ColorNode {
33
+ name : string ;
34
+ }
35
+
36
+ interface SizeNode {
37
+ name : string ;
38
+ }
39
+
40
+ interface AttributeNode {
41
+ name : string ;
42
+ value : string ;
43
+ }
44
+
27
45
interface Product {
28
46
__typename : string ;
29
47
databaseId : number ;
@@ -34,7 +52,31 @@ interface Product {
34
52
price : string ;
35
53
regularPrice : string ;
36
54
salePrice ?: string ;
37
- variations : Variations ;
55
+ productCategories ?: {
56
+ nodes : ProductCategory [ ] ;
57
+ } ;
58
+ allPaColors ?: {
59
+ nodes : ColorNode [ ] ;
60
+ } ;
61
+ allPaSizes ?: {
62
+ nodes : SizeNode [ ] ;
63
+ } ;
64
+ variations : {
65
+ nodes : Array < {
66
+ price : string ;
67
+ regularPrice : string ;
68
+ salePrice ?: string ;
69
+ attributes ?: {
70
+ nodes : AttributeNode [ ] ;
71
+ } ;
72
+ } > ;
73
+ } ;
74
+ }
75
+
76
+ interface ProductType {
77
+ id : string ;
78
+ name : string ;
79
+ checked : boolean ;
38
80
}
39
81
40
82
const Products2 : NextPage = ( {
@@ -45,6 +87,64 @@ const Products2: NextPage = ({
45
87
const [ selectedSizes , setSelectedSizes ] = useState < string [ ] > ( [ ] ) ;
46
88
const [ selectedColors , setSelectedColors ] = useState < string [ ] > ( [ ] ) ;
47
89
const [ priceRange , setPriceRange ] = useState < [ number , number ] > ( [ 0 , 1000 ] ) ;
90
+ const [ productTypes , setProductTypes ] = useState < ProductType [ ] > ( [
91
+ { id : 't-shirts' , name : 'T-Shirts' , checked : false } ,
92
+ { id : 'gensere' , name : 'Gensere' , checked : false } ,
93
+ { id : 'singlet' , name : 'Singlet' , checked : false } ,
94
+ { id : 'skjorter' , name : 'Skjorter' , checked : false }
95
+ ] ) ;
96
+
97
+ const toggleProductType = ( id : string ) => {
98
+ setProductTypes ( prev => prev . map ( type =>
99
+ type . id === id ? { ...type , checked : ! type . checked } : type
100
+ ) ) ;
101
+ } ;
102
+
103
+ // Filter products based on selected filters
104
+ const filteredProducts = products ?. filter ( ( product : Product ) => {
105
+ // Filter by price
106
+ const productPrice = parseFloat ( product . price . replace ( / [ ^ 0 - 9 . ] / g, '' ) ) ;
107
+ const withinPriceRange = productPrice >= priceRange [ 0 ] && productPrice <= priceRange [ 1 ] ;
108
+ if ( ! withinPriceRange ) return false ;
109
+
110
+ // Filter by product type
111
+ const selectedTypes = productTypes . filter ( t => t . checked ) . map ( t => t . name . toLowerCase ( ) ) ;
112
+ if ( selectedTypes . length > 0 ) {
113
+ const productCategories = product . productCategories ?. nodes . map ( ( cat : ProductCategory ) => cat . name . toLowerCase ( ) ) || [ ] ;
114
+ if ( ! selectedTypes . some ( type => productCategories . includes ( type ) ) ) return false ;
115
+ }
116
+
117
+ // Filter by size
118
+ if ( selectedSizes . length > 0 ) {
119
+ const productSizes = product . allPaSizes ?. nodes . map ( ( node : SizeNode ) => node . name ) || [ ] ;
120
+ if ( ! selectedSizes . some ( size => productSizes . includes ( size ) ) ) return false ;
121
+ }
122
+
123
+ // Filter by color
124
+ if ( selectedColors . length > 0 ) {
125
+ const productColors = product . allPaColors ?. nodes . map ( ( node : ColorNode ) => node . name ) || [ ] ;
126
+ if ( ! selectedColors . some ( color => productColors . includes ( color ) ) ) return false ;
127
+ }
128
+
129
+ return true ;
130
+ } ) ;
131
+
132
+ // Sort products
133
+ const sortedProducts = [ ...( filteredProducts || [ ] ) ] . sort ( ( a , b ) => {
134
+ const priceA = parseFloat ( a . price . replace ( / [ ^ 0 - 9 . ] / g, '' ) ) ;
135
+ const priceB = parseFloat ( b . price . replace ( / [ ^ 0 - 9 . ] / g, '' ) ) ;
136
+
137
+ switch ( sortBy ) {
138
+ case 'price-low' :
139
+ return priceA - priceB ;
140
+ case 'price-high' :
141
+ return priceB - priceA ;
142
+ case 'newest' :
143
+ return b . databaseId - a . databaseId ;
144
+ default : // 'popular'
145
+ return 0 ;
146
+ }
147
+ } ) ;
48
148
49
149
if ( loading ) return (
50
150
< Layout title = "Produkter" >
@@ -77,6 +177,9 @@ const Products2: NextPage = ({
77
177
setSelectedColors = { setSelectedColors }
78
178
priceRange = { priceRange }
79
179
setPriceRange = { setPriceRange }
180
+ productTypes = { productTypes }
181
+ toggleProductType = { toggleProductType }
182
+ products = { products }
80
183
/>
81
184
82
185
{ /* Main Content */ }
@@ -102,7 +205,7 @@ const Products2: NextPage = ({
102
205
</ div >
103
206
104
207
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" >
105
- { products . map ( ( product : Product ) => (
208
+ { sortedProducts . map ( ( product : Product ) => (
106
209
< ProductCard
107
210
key = { product . databaseId }
108
211
databaseId = { product . databaseId }
0 commit comments