@@ -17,6 +17,8 @@ import { common_MediaFull } from 'api/proto-http/frontend';
17
17
import { ProductPickerModal } from 'components/common/productPickerModal' ;
18
18
import { SingleMediaViewAndSelect } from 'components/common/singleMediaViewAndSelect' ;
19
19
import { Layout } from 'components/login/layout' ;
20
+ import { calculateAspectRatio } from 'features/utilitty/calculateAspectRatio' ;
21
+ import { isValidUrlForHero as isValidUrl } from 'features/utilitty/isValidUrl' ;
20
22
import { FC , useEffect , useState } from 'react' ;
21
23
import { common_HeroItemInsert , common_Product } from '../../../api/proto-http/admin' ;
22
24
import { HeroProductTable } from './heroProductsTable' ;
@@ -37,14 +39,14 @@ export const Hero: FC = () => {
37
39
38
40
const [ secondAdContentLink , setSecondAdContentLink ] = useState < string | undefined > ( '' ) ;
39
41
const [ secondAdContentLinkId , setSecondAdContentLinkId ] = useState < number | undefined > ( ) ;
40
- const [ secondAdAspectRatio , setSecondAdAspectRatio ] = useState < string | undefined > ( ) ;
41
42
const [ secondAdExploreLink , setSecondAdExploreLink ] = useState < string | undefined > ( '' ) ;
42
43
const [ secondAdExploreLinkError , setSecondAdExploreLinkError ] = useState < boolean > ( false ) ;
43
44
const [ secondAdExploreText , setSecondAdExploreText ] = useState < string | undefined > ( '' ) ;
44
45
46
+ const [ allowedRatios , setAllowedRatios ] = useState < string [ ] > ( [ '4:5' , '1:1' ] ) ;
47
+ const [ isSecondAdEmpty , setIsSecondAdEmpty ] = useState ( false ) ;
45
48
const [ aspectRatioMismatch , setAspectRatioMismatch ] = useState < boolean > ( false ) ;
46
-
47
- const numberOfAds = [ firstAdContentLink , secondAdContentLink ] . filter ( Boolean ) . length ;
49
+ const [ secondAdVisible , setSecondAdVisible ] = useState < boolean > ( true ) ;
48
50
const [ deleteConfirmationOpen , setDeleteConfirmationOpen ] = useState < boolean > ( false ) ;
49
51
50
52
const [ products , setProducts ] = useState < common_Product [ ] > ( [ ] ) ;
@@ -63,6 +65,10 @@ export const Hero: FC = () => {
63
65
if ( response . hero ?. ads ) {
64
66
const mainAd = response . hero . ads . find ( ( ad ) => ad . isMain ) ;
65
67
const otherAds = response . hero . ads . filter ( ( ad ) => ! ad . isMain ) ;
68
+ const ratio = calculateAspectRatio (
69
+ otherAds [ 0 ] . media ?. media ?. thumbnail ?. width || 0 ,
70
+ otherAds [ 0 ] . media ?. media ?. thumbnail ?. height || 0 ,
71
+ ) ;
66
72
67
73
if ( mainAd ) {
68
74
setMainContentLink ( mainAd . media ?. media ?. thumbnail ?. mediaUrl ) ;
@@ -81,6 +87,16 @@ export const Hero: FC = () => {
81
87
setFirstAdContentLinkId ( otherAds [ 0 ] . media ?. id ) ;
82
88
setFirstAdExploreLink ( otherAds [ 0 ] . exploreLink ) ;
83
89
setFirstAdExploreText ( otherAds [ 0 ] . exploreText ) ;
90
+ if ( ratio === '16:9' ) {
91
+ setSecondAdVisible ( false ) ;
92
+ } else if ( ratio === '4:5' ) {
93
+ setAllowedRatios ( [ '4:5' ] ) ;
94
+ } else if ( ratio === '1:1' ) {
95
+ setAllowedRatios ( [ '1:1' ] ) ;
96
+ } else {
97
+ setSecondAdVisible ( true ) ;
98
+ setAllowedRatios ( [ '4:5' , '1:1' ] ) ;
99
+ }
84
100
} else {
85
101
setFirstAdContentLink ( undefined ) ;
86
102
setFirstAdContentLinkId ( undefined ) ;
@@ -99,6 +115,12 @@ export const Hero: FC = () => {
99
115
setSecondAdExploreLink ( undefined ) ;
100
116
setSecondAdExploreText ( undefined ) ;
101
117
}
118
+
119
+ if ( ( ratio === '4:5' || ratio === '1:1' ) && ! secondAdContentLink ) {
120
+ setIsSecondAdEmpty ( true ) ;
121
+ } else {
122
+ setIsSecondAdEmpty ( false ) ;
123
+ }
102
124
}
103
125
104
126
setProducts ( response . hero ?. productsFeatured ? response . hero ?. productsFeatured : [ ] ) ;
@@ -117,10 +139,6 @@ export const Hero: FC = () => {
117
139
validateAllLinks ( ) ;
118
140
} , [ mainContentLink , firstAdContentLink , secondAdContentLink ] ) ;
119
141
120
- const calculateAspectRatio = ( width : number , height : number ) => {
121
- return ( width / height ) . toFixed ( 2 ) ;
122
- } ;
123
-
124
142
const saveMainContentLink = ( mediaLink : common_MediaFull [ ] ) => {
125
143
if ( mediaLink [ 0 ] ) {
126
144
setMainContentLink ( mediaLink [ 0 ] . media ?. thumbnail ?. mediaUrl ) ;
@@ -140,7 +158,21 @@ export const Hero: FC = () => {
140
158
mediaLink [ 0 ] . media ?. thumbnail ?. height ! ,
141
159
) ;
142
160
setFirstAdAspectRatio ( ratio ) ;
143
- checkAspectRatioMismatch ( ratio , secondAdAspectRatio ) ;
161
+ if ( ratio === '16:9' ) {
162
+ setSecondAdVisible ( false ) ;
163
+ setSecondAdContentLink ( undefined ) ;
164
+ setIsSecondAdEmpty ( false ) ; // Reset the error since second ad is not required
165
+ } else if ( ratio === '4:5' || ratio === '1:1' ) {
166
+ setAllowedRatios ( [ ratio ] ) ;
167
+ setSecondAdVisible ( true ) ;
168
+ if ( ! secondAdContentLink ) {
169
+ setIsSecondAdEmpty ( true ) ; // Error when second ad is missing
170
+ }
171
+ } else {
172
+ setAllowedRatios ( [ '4:5' , '1:1' ] ) ;
173
+ setSecondAdVisible ( true ) ;
174
+ setIsSecondAdEmpty ( ! secondAdContentLink ) ;
175
+ }
144
176
return ;
145
177
}
146
178
setFirstAdContentLink ( undefined ) ;
@@ -156,13 +188,12 @@ export const Hero: FC = () => {
156
188
mediaLink [ 0 ] . media ?. thumbnail ?. width ! ,
157
189
mediaLink [ 0 ] . media ?. thumbnail ?. height ! ,
158
190
) ;
159
- setSecondAdAspectRatio ( ratio ) ;
160
191
checkAspectRatioMismatch ( firstAdAspectRatio , ratio ) ;
192
+ setIsSecondAdEmpty ( false ) ;
161
193
return ;
162
194
}
163
195
setSecondAdContentLink ( undefined ) ;
164
196
setSecondAdContentLinkId ( undefined ) ;
165
- setSecondAdAspectRatio ( undefined ) ;
166
197
} ;
167
198
168
199
const checkAspectRatioMismatch = ( ratio1 ?: string , ratio2 ?: string ) => {
@@ -194,6 +225,7 @@ export const Hero: FC = () => {
194
225
setSecondAdExploreLink ( undefined ) ;
195
226
setSecondAdExploreText ( undefined ) ;
196
227
setDeleteConfirmationOpen ( false ) ;
228
+ setSecondAdVisible ( true ) ;
197
229
} ;
198
230
199
231
const handleAdRemove = ( ) => {
@@ -242,16 +274,8 @@ export const Hero: FC = () => {
242
274
setProducts ( newSelection ) ;
243
275
} ;
244
276
245
- const isValidUrl = ( url : string | undefined ) => {
246
- if ( url === undefined ) {
247
- return false ;
248
- }
249
- const pattern = new RegExp ( 'https?://(?:[w-]+.)?grbpwr.com(?:/[^s]*)?' ) ; // fragment locator
250
- return ! ! pattern . test ( url ) ;
251
- } ;
252
-
253
277
const handleSaveClick = ( ) => {
254
- if ( aspectRatioMismatch ) {
278
+ if ( isSecondAdEmpty ) {
255
279
setDialogOpen ( true ) ;
256
280
} else if ( mainExploreLinkError || firstAdExploreLinkError || secondAdExploreLinkError ) {
257
281
setDialogOpen ( true ) ;
@@ -328,14 +352,9 @@ export const Hero: FC = () => {
328
352
</ Box >
329
353
< SingleMediaViewAndSelect
330
354
link = { firstAdContentLink }
331
- aspectRatio = { numberOfAds === 0 ? [ '9:16' ] : [ '4:5' ] }
355
+ aspectRatio = { [ '16:9' , '4:5' , '1:1 '] }
332
356
saveSelectedMedia = { saveFirstAdContentLink }
333
357
/>
334
- { aspectRatioMismatch && (
335
- < Typography variant = 'body2' textTransform = 'uppercase' color = 'red' >
336
- Select media with the appropriate aspect ratio
337
- </ Typography >
338
- ) }
339
358
</ Grid >
340
359
< Grid item xs = { 12 } >
341
360
< TextField
@@ -368,53 +387,55 @@ export const Hero: FC = () => {
368
387
</ Grid >
369
388
</ Grid >
370
389
< Grid item xs = { 12 } md = { 8 } >
371
- < Grid container justifyContent = 'center' spacing = { 2 } >
372
- < Grid item xs = { 12 } >
373
- < Box display = 'flex' alignItems = 'center' gap = '15px' >
374
- < Typography variant = 'h4' > Second Ad</ Typography >
375
- { secondAdContentLink && (
376
- < IconButton onClick = { handleAdRemove } >
377
- < DeleteIcon color = 'secondary' />
378
- </ IconButton >
379
- ) }
380
- </ Box >
381
- < SingleMediaViewAndSelect
382
- link = { secondAdContentLink }
383
- aspectRatio = { [ '4:5' ] }
384
- saveSelectedMedia = { saveSecondAdContentLink }
385
- />
386
- </ Grid >
387
- < Grid item xs = { 12 } >
388
- < Box display = 'flex' alignItems = 'center' gap = '15px' >
390
+ { secondAdVisible && (
391
+ < Grid container justifyContent = 'center' spacing = { 2 } >
392
+ < Grid item xs = { 12 } >
393
+ < Box display = 'flex' alignItems = 'center' gap = '15px' >
394
+ < Typography variant = 'h4' > Second Ad</ Typography >
395
+ { secondAdContentLink && (
396
+ < IconButton onClick = { handleAdRemove } >
397
+ < DeleteIcon color = 'secondary' />
398
+ </ IconButton >
399
+ ) }
400
+ </ Box >
401
+ < SingleMediaViewAndSelect
402
+ link = { secondAdContentLink }
403
+ aspectRatio = { allowedRatios }
404
+ saveSelectedMedia = { saveSecondAdContentLink }
405
+ />
406
+ </ Grid >
407
+ < Grid item xs = { 12 } >
408
+ < Box display = 'flex' alignItems = 'center' gap = '15px' >
409
+ < TextField
410
+ error = { secondAdExploreLinkError }
411
+ helperText = { secondAdExploreLinkError ? 'Not valid url.' : '' }
412
+ size = 'small'
413
+ label = 'Second ad explore link'
414
+ value = { secondAdExploreLink || '' }
415
+ fullWidth
416
+ onChange = { ( e ) => {
417
+ const { value } = e . target ;
418
+ setSecondAdExploreLink ( value ) ;
419
+ if ( ! isValidUrl ( value ) ) {
420
+ setSecondAdExploreLinkError ( true ) ;
421
+ } else {
422
+ setSecondAdExploreLinkError ( false ) ;
423
+ }
424
+ } }
425
+ />
426
+ </ Box >
427
+ </ Grid >
428
+ < Grid item xs = { 12 } >
389
429
< TextField
390
- error = { secondAdExploreLinkError }
391
- helperText = { secondAdExploreLinkError ? 'Not valid url.' : '' }
392
430
size = 'small'
393
- label = 'Second ad explore link '
394
- value = { secondAdExploreLink || '' }
431
+ label = 'Second ad explore text '
432
+ value = { secondAdExploreText || '' }
395
433
fullWidth
396
- onChange = { ( e ) => {
397
- const { value } = e . target ;
398
- setSecondAdExploreLink ( value ) ;
399
- if ( ! isValidUrl ( value ) ) {
400
- setSecondAdExploreLinkError ( true ) ;
401
- } else {
402
- setSecondAdExploreLinkError ( false ) ;
403
- }
404
- } }
434
+ onChange = { ( e ) => setSecondAdExploreText ( e . target . value ) }
405
435
/>
406
- </ Box >
436
+ </ Grid >
407
437
</ Grid >
408
- < Grid item xs = { 12 } >
409
- < TextField
410
- size = 'small'
411
- label = 'Second ad explore text'
412
- value = { secondAdExploreText || '' }
413
- fullWidth
414
- onChange = { ( e ) => setSecondAdExploreText ( e . target . value ) }
415
- />
416
- </ Grid >
417
- </ Grid >
438
+ ) }
418
439
</ Grid >
419
440
< Grid item xs = { 12 } md = { 8 } >
420
441
< Grid container spacing = { 2 } justifyContent = 'center' >
@@ -456,12 +477,12 @@ export const Hero: FC = () => {
456
477
aria-labelledby = 'alert-dialog-title'
457
478
>
458
479
< DialogTitle id = 'alert-dialog-title' >
459
- { aspectRatioMismatch
460
- ? 'The aspect ratios of the first and second ads do not match. Please select media with matching aspect ratios. '
480
+ { isSecondAdEmpty
481
+ ? 'Both ads need to be filled '
461
482
: 'There are errors. Are you sure you want to save?' }
462
483
</ DialogTitle >
463
484
< DialogActions >
464
- { aspectRatioMismatch ? (
485
+ { isSecondAdEmpty ? (
465
486
< Button onClick = { ( ) => setDialogOpen ( false ) } > ok</ Button >
466
487
) : (
467
488
< >
0 commit comments