1
- import { useState , useEffect } from 'react' ;
1
+ import React , { useState , useEffect } from 'react' ;
2
2
import { filteredVariantPrice , paddedPrice } from '@/utils/functions/functions' ;
3
3
import AddToCart , { IProductRootObject } from './AddToCart.component' ;
4
4
import LoadingSpinner from '@/components/LoadingSpinner/LoadingSpinner.component' ;
@@ -45,28 +45,11 @@ interface IVariations {
45
45
nodes : IVariationNodes [ ] ;
46
46
}
47
47
48
- interface IProduct {
49
- __typename : string ;
50
- id : string ;
51
- databaseId : number ;
52
- averageRating : number ;
53
- slug : string ;
54
- description : string ;
55
- onSale : boolean ;
56
- image : IImage ;
57
- name : string ;
58
- salePrice ?: string ;
59
- regularPrice : string ;
60
- price : string ;
61
- stockQuantity : number ;
62
- allPaColors ?: IAllPaColors ;
63
- allPaSizes ?: IAllPaSizes ;
64
- variations ?: IVariations ;
65
- }
66
-
67
48
const SingleProduct : React . FC < IProductRootObject > = ( { product } ) => {
68
49
const [ isLoading , setIsLoading ] = useState < boolean > ( true ) ;
69
- const [ selectedVariation , setSelectedVariation ] = useState < number | undefined > ( ) ;
50
+ const [ selectedVariation , setSelectedVariation ] = useState <
51
+ number | undefined
52
+ > ( ) ;
70
53
71
54
const placeholderFallBack = 'https://via.placeholder.com/600' ;
72
55
@@ -80,14 +63,18 @@ const SingleProduct: React.FC<IProductRootObject> = ({ product }) => {
80
63
}
81
64
} , [ product . variations ] ) ;
82
65
83
- let { description, image, name, onSale, price, regularPrice, salePrice } = product ;
66
+ let { description, image, name, onSale, price, regularPrice, salePrice } =
67
+ product ;
84
68
85
69
if ( price ) price = paddedPrice ( price , 'kr' ) ;
86
70
if ( regularPrice ) regularPrice = paddedPrice ( regularPrice , 'kr' ) ;
87
71
if ( salePrice ) salePrice = paddedPrice ( salePrice , 'kr' ) ;
88
72
89
- if ( process . browser ) {
90
- DESCRIPTION_WITHOUT_HTML = new DOMParser ( ) . parseFromString ( description , 'text/html' ) . body . textContent ;
73
+ if ( typeof window !== 'undefined' ) {
74
+ DESCRIPTION_WITHOUT_HTML = new DOMParser ( ) . parseFromString (
75
+ description ,
76
+ 'text/html' ,
77
+ ) . body . textContent ;
91
78
}
92
79
93
80
return (
@@ -112,59 +99,80 @@ const SingleProduct: React.FC<IProductRootObject> = ({ product }) => {
112
99
) : (
113
100
< img
114
101
id = "product-image"
115
- src = { process . env . NEXT_PUBLIC_PLACEHOLDER_LARGE_IMAGE_URL ?? placeholderFallBack }
102
+ src = {
103
+ process . env . NEXT_PUBLIC_PLACEHOLDER_LARGE_IMAGE_URL ??
104
+ placeholderFallBack
105
+ }
116
106
alt = { name }
117
107
className = "w-full h-auto object-cover rounded-lg shadow-md"
118
108
/>
119
109
) }
120
110
</ div >
121
111
< div className = "flex flex-col space-y-4" >
122
- < h1 className = "text-3xl font-bold text-center md:text-left" > { name } </ h1 >
112
+ < h1 className = "text-3xl font-bold text-center md:text-left" >
113
+ { name }
114
+ </ h1 >
123
115
< div className = "text-center md:text-left" >
124
116
{ onSale ? (
125
117
< div className = "flex flex-col md:flex-row items-center md:items-start space-y-2 md:space-y-0 md:space-x-4" >
126
118
< p className = "text-3xl font-bold text-red-600" >
127
- { product . variations ? filteredVariantPrice ( price , '' ) : salePrice }
119
+ { product . variations
120
+ ? filteredVariantPrice ( price , '' )
121
+ : salePrice }
128
122
</ p >
129
123
< p className = "text-xl text-gray-500 line-through" >
130
- { product . variations ? filteredVariantPrice ( price , 'right' ) : regularPrice }
124
+ { product . variations
125
+ ? filteredVariantPrice ( price , 'right' )
126
+ : regularPrice }
131
127
</ p >
132
128
</ div >
133
129
) : (
134
130
< p className = "text-2xl font-bold" > { price } </ p >
135
131
) }
136
132
</ div >
137
- < p className = "text-gray-600 text-center md:text-left" > { DESCRIPTION_WITHOUT_HTML } </ p >
133
+ < p className = "text-gray-600 text-center md:text-left" >
134
+ { DESCRIPTION_WITHOUT_HTML }
135
+ </ p >
138
136
{ Boolean ( product . stockQuantity ) && (
139
137
< p className = "text-sm font-semibold text-center md:text-left" >
140
138
{ product . stockQuantity } på lager
141
139
</ p >
142
140
) }
143
141
{ product . variations && (
144
142
< div className = "w-full" >
145
- < label htmlFor = "variant" className = "block text-sm font-medium text-gray-700 mb-2" >
143
+ < label
144
+ htmlFor = "variant"
145
+ className = "block text-sm font-medium text-gray-700 mb-2"
146
+ >
146
147
Varianter
147
148
</ label >
148
149
< select
149
150
id = "variant"
150
151
name = "variant"
151
152
className = "w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
152
- onChange = { ( e ) => setSelectedVariation ( Number ( e . target . value ) ) }
153
+ onChange = { ( e ) =>
154
+ setSelectedVariation ( Number ( e . target . value ) )
155
+ }
153
156
>
154
- { product . variations . nodes . map ( ( { id, name, databaseId, stockQuantity } ) => {
155
- const filteredName = name . split ( '- ' ) . pop ( ) ;
156
- return (
157
- < option key = { id } value = { databaseId } >
158
- { filteredName } - ({ stockQuantity } på lager)
159
- </ option >
160
- ) ;
161
- } ) }
157
+ { product . variations . nodes . map (
158
+ ( { id, name, databaseId, stockQuantity } ) => {
159
+ const filteredName = name . split ( '- ' ) . pop ( ) ;
160
+ return (
161
+ < option key = { id } value = { databaseId } >
162
+ { filteredName } - ({ stockQuantity } på lager)
163
+ </ option >
164
+ ) ;
165
+ } ,
166
+ ) }
162
167
</ select >
163
168
</ div >
164
169
) }
165
170
< div className = "flex justify-center md:justify-start" >
166
171
{ product . variations ? (
167
- < AddToCart product = { product } variationId = { selectedVariation } />
172
+ < AddToCart
173
+ product = { product }
174
+ variationId = { selectedVariation }
175
+ />
168
176
) : (
169
177
< AddToCart product = { product } />
170
178
) }
0 commit comments