From 788610292e0e287a27f8ceadc2082b171493a058 Mon Sep 17 00:00:00 2001
From: NCanggoro <ansianggoro@gmail.com>
Date: Thu, 28 Sep 2023 10:29:31 +0700
Subject: [PATCH] handling erorr response and empty reviews

---
 src/pages/LocationDetail/index.tsx | 131 ++++++++++++++++-------------
 src/services/auth.ts               |   2 +-
 src/services/review.ts             |  12 ++-
 src/types/common.ts                |   3 +-
 4 files changed, 84 insertions(+), 64 deletions(-)

diff --git a/src/pages/LocationDetail/index.tsx b/src/pages/LocationDetail/index.tsx
index 9862b94..9c15187 100644
--- a/src/pages/LocationDetail/index.tsx
+++ b/src/pages/LocationDetail/index.tsx
@@ -86,7 +86,12 @@ function LocationDetail() {
     setCurrentUserReview(res.data)
     setPageState({ ...pageState, enable_post: false})
    } catch (error) {
-    alert(error)
+     console.log(error)
+    let err = error as IHttpResponse;
+    if(err.status == 404) {
+      return
+    }
+    alert(err.error.response.data.message)
    }
   }
 
@@ -390,67 +395,77 @@ function LocationDetail() {
               }
               <div name={'CRTICITS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
                 <SeparatorWithAnchor pageName={"critic's review"} pageLink='#' />
-                <div className={'criticSortFilter'}>
-                  <div className={'inline-block text-sm'}>Sort by: </div>
-                  <a className={'dropdownLabel'} onClick={() => setPageState({ ...pageState, show_sort: !pageState.show_sort })}>
-                    <p className={'ml-2 inline-block capitalize text-sm'}>{pageState.critic_filter_name}</p>
-                    <svg style={{ display: 'inline-block' }} fill={"currentColor"} xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-345 240-585l56-56 184 184 184-184 56 56-240 240Z" /></svg>
-                  </a>
-                  <div className={'dropdown-content text-sm bg-secondary'} style={pageState.show_sort ? { display: 'block' } : ''}>
-                    {SORT_TYPE.map((x, index) => (
-                      <a onClick={(e) => onChangeCriticsSort(e, x, index)} className={'block pt-1 capitalize'}>{x}</a>
-                    ))}
-                  </div>
-                </div>
-                <div style={{ clear: 'both' }} />
-
-                {locationDetail.critics_review.map(x => (
-                  <div className={''} style={{ padding: '15px 0' }}>
-                    <div style={{ float: 'left' }}>
-                      <div style={{ fontSize: 20, marginRight: 20, textAlign: 'center', width: 55, marginBottom: 3 }}>
-                        {x.score}
-                      </div>
-                      <div style={{ height: 4, width: 55, position: 'relative', backgroundColor: '#d8d8d8' }}>
-                        <div style={{ height: 4, backgroundColor: '#85ce73', width: `${x.score}%` }} />
-                      </div>
-                    </div>
-                    <div className={'mr-3'} style={{ display: 'inline-block', width: 40 }}>
-                      <a href="#">
-                        <img
-                          loading={'lazy'}
-                          style={{ width: '100%' }}
-                          src={x.user_avatar.Valid ? x.user_avatar.String.toString() : 'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'}
-                        />
+                {locationDetail.critics_review.length > 0 ? 
+                <>
+                    <div className={'criticSortFilter'}>
+                      <div className={'inline-block text-sm'}>Sort by: </div>
+                      <a className={'dropdownLabel'} onClick={() => setPageState({ ...pageState, show_sort: !pageState.show_sort })}>
+                        <p className={'ml-2 inline-block capitalize text-sm'}>{pageState.critic_filter_name}</p>
+                        <svg style={{ display: 'inline-block' }} fill={"currentColor"} xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-345 240-585l56-56 184 184 184-184 56 56-240 240Z" /></svg>
                       </a>
-                    </div>
-                    <div style={{ display: 'inline-block', verticalAlign: 'top' }}>
-                      <div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
-                        <a>
-                          <span>{x.username}</span>
-                        </a>
+                      <div className={'dropdown-content text-sm bg-secondary'} style={pageState.show_sort ? { display: 'block' } : ''}>
+                        {SORT_TYPE.map((x, index) => (
+                          <a onClick={(e) => onChangeCriticsSort(e, x, index)} className={'block pt-1 capitalize'}>{x}</a>
+                        ))}
                       </div>
                     </div>
-                    <div style={{ fontSize: 15, lineHeight: '24px', margin: '5px 75px 1px' }}>
-                      <CustomInterweave 
-                        content={x.comments}
-                      />
-                    </div>
-                    <div className={'reviewLinks'} style={{ marginLeft: 72 }}>
-                      <div className={'mr-2'} style={{ minWidth: 55, display: 'inline-block', verticalAlign: 'middle' }}>
-                        <a className={'text-sm'} href={'#'}>
-                          <svg className={'inline-block mr-1'} fill={'currentColor'} xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 -960 960 960"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z" /></svg>
-                          <div className={'inline-block'}>Video</div>
-                        </a>
+                    <div style={{ clear: 'both' }} />
+
+                    {locationDetail.critics_review.map(x => (
+                      <div className={''} style={{ padding: '15px 0' }}>
+                        <div style={{ float: 'left' }}>
+                          <div style={{ fontSize: 20, marginRight: 20, textAlign: 'center', width: 55, marginBottom: 3 }}>
+                            {x.score}
+                          </div>
+                          <div style={{ height: 4, width: 55, position: 'relative', backgroundColor: '#d8d8d8' }}>
+                            <div style={{ height: 4, backgroundColor: '#85ce73', width: `${x.score}%` }} />
+                          </div>
+                        </div>
+                        <div className={'mr-3'} style={{ display: 'inline-block', width: 40 }}>
+                          <a href="#">
+                            <img
+                              loading={'lazy'}
+                              style={{ width: '100%' }}
+                              src={x.user_avatar.Valid ? x.user_avatar.String.toString() : 'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'}
+                            />
+                          </a>
+                        </div>
+                        <div style={{ display: 'inline-block', verticalAlign: 'top' }}>
+                          <div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
+                            <a>
+                              <span>{x.username}</span>
+                            </a>
+                          </div>
+                        </div>
+                        <div style={{ fontSize: 15, lineHeight: '24px', margin: '5px 75px 1px' }}>
+                          <CustomInterweave
+                            content={x.comments}
+                          />
+                        </div>
+                        <div className={'reviewLinks'} style={{ marginLeft: 72 }}>
+                          <div className={'mr-2'} style={{ minWidth: 55, display: 'inline-block', verticalAlign: 'middle' }}>
+                            <a className={'text-sm'} href={'#'}>
+                              <svg className={'inline-block mr-1'} fill={'currentColor'} xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 -960 960 960"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z" /></svg>
+                              <div className={'inline-block'}>Video</div>
+                            </a>
+                          </div>
+                          <div style={{ minWidth: 55, display: 'inline-block', verticalAlign: 'middle' }}>
+                            <a className={'text-sm'} href={'#'}>
+                              <svg className={'inline-block mr-1'} fill={'currentColor'} xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 -960 960 960"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z" /></svg>
+                              <div className={'inline-block'}>Instagram</div>
+                            </a>
+                          </div>
+                        </div>
                       </div>
-                      <div style={{ minWidth: 55, display: 'inline-block', verticalAlign: 'middle' }}>
-                        <a className={'text-sm'} href={'#'}>
-                          <svg className={'inline-block mr-1'} fill={'currentColor'} xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 -960 960 960"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z" /></svg>
-                          <div className={'inline-block'}>Instagram</div>
-                        </a>
-                      </div>
-                    </div>
-                  </div>
-                ))}
+                    ))}
+                </>
+
+                :
+                <>
+                  <span className={'text-sm italic'}>No Critics review to display</span>
+                </>
+
+                }
               </div>
 
               <div name={'USERS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
diff --git a/src/services/auth.ts b/src/services/auth.ts
index c678ac2..9221e5a 100644
--- a/src/services/auth.ts
+++ b/src/services/auth.ts
@@ -2,7 +2,7 @@ import { AxiosError } from "axios";
 import { LOGIN_URI, SIGNUP_URI } from "../constants/api";
 import { client } from "./config";
 
-const initialState: IEmptyResponseState = {
+const initialState: IHttpResponse = {
   data: null,
   error: AxiosError
 }
diff --git a/src/services/review.ts b/src/services/review.ts
index 7102a49..5810f3e 100644
--- a/src/services/review.ts
+++ b/src/services/review.ts
@@ -2,9 +2,10 @@ import { AxiosError } from "axios"
 import { client } from "./config";
 import { GET_CURRENT_USER_REVIEW_LOCATION_URI, POST_REVIEW_LOCATION_URI } from "../constants/api";
 
-const initialState: IEmptyResponseState = {
+const initialState: IHttpResponse = {
   data: null,
-  error: AxiosError
+  error: AxiosError,
+  status: 0,
 }
 
 interface postReviewLocationReq {
@@ -29,7 +30,7 @@ async function postReviewLocation(req: postReviewLocationReq) {
   }
 }
 
-async function getCurrentUserLocationReviewService(location_id: number) {
+async function getCurrentUserLocationReviewService(location_id: number): Promise<IHttpResponse> {
   const newState = { ...initialState };
   try {
     const response = await client({ method: 'GET', url: `${GET_CURRENT_USER_REVIEW_LOCATION_URI}/${location_id}`, withCredentials: true})
@@ -37,7 +38,10 @@ async function getCurrentUserLocationReviewService(location_id: number) {
     newState.error = null
     return newState
   } catch (err) {
-    throw err;
+    let error = err as AxiosError;
+    newState.error = error
+    newState.status = error.response?.status;
+    throw(newState)
   }
 }
 
diff --git a/src/types/common.ts b/src/types/common.ts
index 9d0fc2e..1ae1d49 100644
--- a/src/types/common.ts
+++ b/src/types/common.ts
@@ -7,7 +7,8 @@ interface GetRequestPagination {
 }
 
 
-interface IEmptyResponseState {
+interface IHttpResponse {
   data: any,
   error: any,
+  status?: number,
 };
\ No newline at end of file