@@ -123,16 +123,14 @@ interface FormData {
123123}
124124
125125const defaultReview : FormData = {
126- bedrooms : 0 ,
127- price : 0 ,
126+ bedrooms : - 1 ,
127+ price : - 1 ,
128128 overallRating : 0 ,
129129 address : '' ,
130130 ratings : {
131131 location : 0 ,
132132 safety : 0 ,
133- value : 0 ,
134133 maintenance : 0 ,
135- communication : 0 ,
136134 conditions : 0 ,
137135 } ,
138136 localPhotos : [ ] ,
@@ -177,8 +175,7 @@ const reducer = (state: FormData, action: Action): FormData => {
177175 *
178176 * This component displays a modal for users to input information for their review about a specific apartment.
179177 * This includes the bedroom(s), price per person, overall rating, detailed ratings (location, safety, maintenance,
180- * conditions), review text/body, pictures (up to 3 pictures). The information that is required are: overall experience
181- * and review text/body, all other information are optional.
178+ * conditions), review text/body, pictures (up to 3 pictures). All fields are required.
182179 * The submit button will add the review to the database and set the status as PENDING until an admin approves it.
183180 * The modal is responsive for all screen sizes and mobile display.
184181 *
@@ -217,9 +214,7 @@ const ReviewModal = ({
217214 ratings : {
218215 location : review . detailedRatings . location ,
219216 safety : review . detailedRatings . safety ,
220- value : review . detailedRatings . value ,
221217 maintenance : review . detailedRatings . maintenance ,
222- communication : review . detailedRatings . communication ,
223218 conditions : review . detailedRatings . conditions ,
224219 } ,
225220 localPhotos : review . photos . map ( ( photo ) => new File ( [ ] , photo ) ) ,
@@ -235,6 +230,12 @@ const ReviewModal = ({
235230 const [ showError , setShowError ] = useState ( false ) ;
236231 const [ emptyTextError , setEmptyTextError ] = useState ( false ) ;
237232 const [ ratingError , setRatingError ] = useState ( false ) ;
233+ const [ bedroomError , setBedroomError ] = useState ( false ) ;
234+ const [ priceError , setPriceError ] = useState ( false ) ;
235+ const [ locationError , setLocationError ] = useState ( false ) ;
236+ const [ maintenanceError , setMaintenanceError ] = useState ( false ) ;
237+ const [ safetyError , setSafetyError ] = useState ( false ) ;
238+ const [ conditionsError , setConditionsError ] = useState ( false ) ;
238239 const [ includesProfanityError , setIncludesProfanityError ] = useState ( false ) ;
239240 const [ addedPhoto , setAddedPhoto ] = useState ( false ) ;
240241 const modalRef = useRef < HTMLDivElement > ( null ) ;
@@ -332,10 +333,26 @@ const ReviewModal = ({
332333 if (
333334 data . reviewText === '' ||
334335 data . overallRating === 0 ||
336+ data . price < 0 ||
337+ data . bedrooms < 0 ||
338+ data . detailedRatings . location === 0 ||
339+ data . detailedRatings . conditions === 0 ||
340+ data . detailedRatings . maintenance === 0 ||
341+ data . detailedRatings . safety === 0 ||
335342 includesProfanity ( data . reviewText )
336343 ) {
337344 data . overallRating === 0 ? setRatingError ( true ) : setRatingError ( false ) ;
338- data . reviewText === '' ? setEmptyTextError ( true ) : setEmptyTextError ( false ) ;
345+ data . reviewText . length < 15 ? setEmptyTextError ( true ) : setEmptyTextError ( false ) ;
346+ data . price < 0 ? setPriceError ( true ) : setPriceError ( false ) ;
347+ data . bedrooms < 0 ? setBedroomError ( true ) : setBedroomError ( false ) ;
348+ data . detailedRatings . conditions === 0
349+ ? setConditionsError ( true )
350+ : setConditionsError ( false ) ;
351+ data . detailedRatings . location === 0 ? setLocationError ( true ) : setLocationError ( false ) ;
352+ data . detailedRatings . maintenance === 0
353+ ? setMaintenanceError ( true )
354+ : setMaintenanceError ( false ) ;
355+ data . detailedRatings . safety === 0 ? setSafetyError ( true ) : setSafetyError ( false ) ;
339356 includesProfanity ( data . reviewText )
340357 ? setIncludesProfanityError ( true )
341358 : setIncludesProfanityError ( false ) ;
@@ -356,7 +373,8 @@ const ReviewModal = ({
356373 if ( ! initialReview ) {
357374 dispatch ( { type : 'reset' } ) ;
358375 }
359- onSuccess ( ) ;
376+ sessionStorage . setItem ( 'showModifiedReviewSuccessToast' , 'true' ) ;
377+ window . location . reload ( ) ;
360378 } catch ( err ) {
361379 console . log ( err ) ;
362380 console . log ( 'Failed to submit form' ) ;
@@ -374,6 +392,18 @@ const ReviewModal = ({
374392 onClose ( ) ;
375393 } ;
376394
395+ const resetErrors = ( ) => {
396+ setEmptyTextError ( false ) ;
397+ setRatingError ( false ) ;
398+ setBedroomError ( false ) ;
399+ setPriceError ( false ) ;
400+ setPriceError ( false ) ;
401+ setLocationError ( false ) ;
402+ setMaintenanceError ( false ) ;
403+ setConditionsError ( false ) ;
404+ setSafetyError ( false ) ;
405+ } ;
406+
377407 const removePhoto = ( index : number ) => {
378408 const newPhotos = review . localPhotos . filter ( ( _ , photoIndex ) => index !== photoIndex ) ;
379409 dispatch ( { type : 'updatePhotos' , photos : newPhotos } ) ;
@@ -391,6 +421,13 @@ const ReviewModal = ({
391421 return ( ) => clearTimeout ( timer ) ;
392422 } , [ addedPhoto ] ) ;
393423
424+ useEffect ( ( ) => {
425+ if ( sessionStorage . getItem ( 'showModifiedReviewSuccessToast' ) === 'true' ) {
426+ onSuccess ( ) ; // Call the toast notification function
427+ sessionStorage . removeItem ( 'showModifiedReviewSuccessToast' ) ; // Clean up so it doesn't trigger again
428+ }
429+ } , [ ] ) ;
430+
394431 /**
395432 * Returns the "Things to consider in your review:" prompt box. Function serves to help mobile display.
396433 */
@@ -455,7 +492,7 @@ const ReviewModal = ({
455492 justifyContent = "flex-start"
456493 >
457494 < Grid item style = { { marginRight : '10px' , paddingLeft : '0' } } >
458- < Typography > Bedroom(s)</ Typography >
495+ < Typography color = { ! bedroomError ? 'initial' : 'error' } > Bedroom(s) * </ Typography >
459496 </ Grid >
460497 < Grid
461498 item
@@ -477,6 +514,11 @@ const ReviewModal = ({
477514 />
478515 < ExpandMoreIcon className = { expandMoreIcon } />
479516 </ Grid >
517+ { bedroomError && (
518+ < Typography color = "error" style = { { fontSize : '12px' , minWidth : '200px' } } >
519+ * Required
520+ </ Typography >
521+ ) }
480522 </ Grid >
481523
482524 < Grid
@@ -495,7 +537,9 @@ const ReviewModal = ({
495537 ! isMobile ? { marginRight : '10px' , marginLeft : 'auto' } : { marginRight : '10px' }
496538 }
497539 >
498- < Typography > Price Per Person</ Typography >
540+ < Typography color = { ! priceError ? 'initial' : 'error' } >
541+ Price Per Person *
542+ </ Typography >
499543 </ Grid >
500544 < Grid
501545 item
@@ -513,18 +557,34 @@ const ReviewModal = ({
513557 />
514558 < ExpandMoreIcon className = { expandMoreIcon } />
515559 </ Grid >
560+ { priceError && (
561+ < Typography
562+ color = "error"
563+ style = { { fontSize : '12px' , justifyItems : 'flex-start' , minWidth : '180px' } }
564+ >
565+ * Required
566+ </ Typography >
567+ ) }
516568 </ Grid >
517569 </ Grid >
518570 < Grid container direction = "column" justifyContent = "space-evenly" spacing = { 4 } >
519- < Grid container item >
520- < ReviewRating
521- name = "overall"
522- label = "Overall Experience"
523- onChange = { updateOverall ( ) }
524- defaultValue = { initialReview ?. overallRating || 0 }
525- > </ ReviewRating >
526- { ratingError && < Typography color = "error" > *This field is required</ Typography > }
571+ < Grid container item xs = { 12 } >
572+ < Grid container item >
573+ < ReviewRating
574+ name = "overall"
575+ label = "Overall Experience *"
576+ onChange = { updateOverall ( ) }
577+ defaultValue = { initialReview ?. overallRating || 0 }
578+ error = { ratingError }
579+ > </ ReviewRating >
580+ </ Grid >
581+ { ratingError && (
582+ < Typography color = "error" style = { { fontSize : '12px' } } >
583+ * Required
584+ </ Typography >
585+ ) }
527586 </ Grid >
587+
528588 < div className = { styles . div } > </ div >
529589 { /* <Grid container item justifyContent="space-between" xs={12} sm={6}>
530590 <TextField
@@ -539,29 +599,38 @@ const ReviewModal = ({
539599 < Grid container spacing = { 1 } justifyContent = "center" >
540600 < ReviewRating
541601 name = "location"
542- label = "Location"
602+ label = "Location * "
543603 onChange = { updateRating ( 'location' ) }
544604 defaultValue = { initialReview ?. detailedRatings . location || 0 }
605+ error = { locationError }
545606 > </ ReviewRating >
546607 < ReviewRating
547608 name = "safety"
548- label = "Safety"
609+ label = "Safety * "
549610 onChange = { updateRating ( 'safety' ) }
550611 defaultValue = { initialReview ?. detailedRatings . safety || 0 }
612+ error = { safetyError }
551613 > </ ReviewRating >
552614 < ReviewRating
553615 name = "maintenance"
554- label = "Maintenance"
616+ label = "Maintenance * "
555617 onChange = { updateRating ( 'maintenance' ) }
556618 defaultValue = { initialReview ?. detailedRatings . maintenance || 0 }
619+ error = { maintenanceError }
557620 > </ ReviewRating >
558621 < ReviewRating
559622 name = "conditions"
560- label = "Conditions"
623+ label = "Conditions * "
561624 onChange = { updateRating ( 'conditions' ) }
562625 defaultValue = { initialReview ?. detailedRatings . conditions || 0 }
626+ error = { conditionsError }
563627 > </ ReviewRating >
564628 </ Grid >
629+ { ( conditionsError || safetyError || maintenanceError || locationError ) && (
630+ < Typography color = "error" style = { { fontSize : '12px' , marginTop : '5px' } } >
631+ * These fields are required
632+ </ Typography >
633+ ) }
565634 </ Grid >
566635
567636 < div className = { styles . div } > </ div >
@@ -597,7 +666,7 @@ const ReviewModal = ({
597666 } }
598667 placeholder = "Write your review here"
599668 helperText = { `${ review . body . length } /${ REVIEW_CHARACTER_LIMIT } ${
600- emptyTextError ? ' This field is required' : ''
669+ emptyTextError ? ' A minimum of 15 characters is required' : ''
601670 } ${
602671 includesProfanityError
603672 ? ' This review contains profanity. Please edit it and try again.'
@@ -640,7 +709,10 @@ const ReviewModal = ({
640709 < Button
641710 variant = "contained"
642711 disableElevation
643- onClick = { initialReview ? onClose : onCloseClearPhotos }
712+ onClick = { ( ) => {
713+ ( initialReview ? onClose : onCloseClearPhotos ) ( ) ;
714+ resetErrors ( ) ;
715+ } }
644716 className = { hollowRedButton }
645717 style = { { marginLeft : '15px' } }
646718 >
0 commit comments