diff --git a/src/pages/BestLocations/index.tsx b/src/pages/BestLocations/index.tsx index 979a618..30b8c37 100644 --- a/src/pages/BestLocations/index.tsx +++ b/src/pages/BestLocations/index.tsx @@ -3,8 +3,6 @@ import { getListTopLocationsService } from "../../services"; import { DefaultSeparator } from "../../components"; import { TargetedEvent } from "preact/compat"; import './style.css'; -import { useNavigate } from "react-router-dom"; - interface TopLocation { row_number: Number, @@ -57,8 +55,6 @@ function BestLocation() { filterRegionType: 0, }) - const navigate = useNavigate() - async function getTopLocations() { try { const res = await getListTopLocationsService({ page: page, page_size: 20, order_by: pageState.filterScoreTypeidx, region_type: pageState.filterRegionType }) @@ -79,18 +75,6 @@ function BestLocation() { setPageState({ ...pageState, filterRegionTypeName: region_name, filterRegionType: type}) } - function onNavigateToDetail( - id: Number, - critic_count: Number, - critic_score: Number, - user_count: Number, - user_score: Number, - ) { - - navigate(`/location/${id}`, { state: { user_score: user_score, user_count: user_count, critic_score: critic_score, critic_count: critic_count }}) - - } - useEffect(() => { getTopLocations() }, [pageState]) @@ -152,10 +136,10 @@ function BestLocation() { */}
- onNavigateToDetail(x.id, x.critic_count, x.critic_score, x.user_count, x.user_score)}>{x.row_number}.{x.name} + {x.row_number}.{x.name}
- onNavigateToDetail(x.id, x.critic_count, x.critic_score, x.user_count, x.user_score)}> +
diff --git a/src/pages/LocationDetail/index.css b/src/pages/LocationDetail/index.css index d0d80c5..de75f8b 100644 --- a/src/pages/LocationDetail/index.css +++ b/src/pages/LocationDetail/index.css @@ -67,6 +67,11 @@ img { outline: none; } +.text-area-button { + background-color: gray; + letter-spacing: 1px; +} + .criticSortFilter { float: right; } diff --git a/src/pages/LocationDetail/index.tsx b/src/pages/LocationDetail/index.tsx index a9413ed..a5f73ff 100644 --- a/src/pages/LocationDetail/index.tsx +++ b/src/pages/LocationDetail/index.tsx @@ -1,24 +1,43 @@ -import { useLocation, useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { ChangeEvent, TargetedEvent } from 'preact/compat'; import { useEffect, useRef, useState } from 'preact/hooks'; -import './index.css'; import Lightbox from 'yet-another-react-lightbox'; import useCallbackState from '../../types/state-callback'; -import { EmptyLocationDetailResponse, LocationDetailResponse, LocationResponse, emptyLocationResponse } from './types'; -import { useAutosizeTextArea } from '../../utils'; -import { getImagesByLocationService, getLocationService } from "../../services"; -import { DefaultSeparator, SeparatorWithAnchor, CustomInterweave } from '../../components'; +import { + EmptyLocationDetailResponse, + LocationDetailResponse, + LocationResponse, + emptyLocationResponse, + CurrentUserLocationReviews, +} from './types'; +import { handleAxiosError, useAutosizeTextArea } from '../../utils'; +import { getImagesByLocationService, getLocationService, postReviewLocation } from "../../services"; +import { DefaultSeparator, SeparatorWithAnchor, CustomInterweave, SpinnerLoading } from '../../components'; +import { useSelector } from 'react-redux'; +import { UserRootState } from '../../store/type'; +import { DEFAULT_AVATAR_IMG } from '../../constants/default'; +import './index.css'; +import { AxiosError } from 'axios'; + +const SORT_TYPE = [ + 'highest rated', + 'lowest rated', + 'newest', + 'oldest' +] function LocationDetail() { const [locationDetail, setLocationDetail] = useCallbackState(EmptyLocationDetailResponse) const [locationImages, setLocationImages] = useState(emptyLocationResponse()) + const [currentUserReview, setCurrentUserReview] = useState() const [lightboxOpen, setLightboxOpen] = useState(false) const [pageState, setPageState] = useState({ critic_filter_name: 'highest rated', critic_filter_type: 0, show_sort: false, + enable_post: true, + on_submit_loading: false, is_score_rating_panic_msg: '', - temp: '' }) const [reviewValue, setReviewValue] = useState({ review_textArea: '', @@ -26,28 +45,27 @@ function LocationDetail() { }) const [isLoading, setIsLoading] = useState(true) + const navigate = useNavigate(); + const user = useSelector((state: UserRootState) => state.auth) + const textAreaRef = useRef(null); useAutosizeTextArea(textAreaRef.current, reviewValue.review_textArea); - const { state } = useLocation(); const { id } = useParams() - const SORT_TYPE = [ - 'highest rated', - 'lowest rated', - 'newest', - 'oldest' - ] - async function getLocationDetail(): Promise { try { const res = await getLocationService(Number(id)) setLocationDetail(res.data, (val) => { getImage(val.detail.thumbnail.String.toString()) }) - } catch (err) { - console.log(err) + } catch (error) { + let err = error as AxiosError; + if (err.response?.status == 404) { + navigate("/") + } + alert(error) } } @@ -90,22 +108,63 @@ function LocationDetail() { setPageState({ ...pageState, show_sort: false, critic_filter_name: sort_name, critic_filter_type: sort_type }) } - function handleSubmitReview(e: TargetedEvent) { + async function handleSubmitReview(e: TargetedEvent) { + e.preventDefault(); + setPageState({ ...pageState, on_submit_loading: true }) + + if (isNaN(Number(reviewValue.score_input))) { + setPageState({ ...pageState, is_score_rating_panic_msg: "SCORE MUST BE A NUMBER" }) + return + } + + if (Number(reviewValue.score_input) > 100) { + setPageState({ ...pageState, is_score_rating_panic_msg: "SCORE MUST BE LESS OR EQUAL THAN 100" }) + return + } + + if (reviewValue.score_input === '') { + setPageState({ ...pageState, is_score_rating_panic_msg: "SCORE MUSTN'T BE EMPTY" }) + return + } + + try { + const { data } = await postReviewLocation({ + is_hided: false, + location_id: Number(id), + score: Number(reviewValue.score_input), + submitted_by: Number(user.id), + is_from_critic: user.is_critics, + comments: reviewValue.review_textArea, + }) + + setPageState({ ...pageState, enable_post: false, on_submit_loading: false }) + setReviewValue({ review_textArea: '', score_input: '' }) + setCurrentUserReview({ + id: data.id, + comments: data.comments, + is_from_critic: data.is_from_critic, + is_hided: data.is_hided, + location_id: data.location_id, + score: data.score, + submitted_by: data.submitted_by, + created_at: data.created_at, + updated_at: data.updated_at + }) + } catch (error) { + let err = error as AxiosError; + console.log(err) + const str = handleAxiosError(err) + alert(str) + setPageState({ ...pageState, on_submit_loading: false }) + } + + } + + function handleSignInNavigation(e: TargetedEvent) { e.preventDefault(); - if(Number(reviewValue.score_input) > 100) { - setPageState({ ...pageState, is_score_rating_panic_msg: "SCORE MUST BE LESS OR EQUAL THAN 100"}) - return - } - - if(reviewValue.score_input === '') { - setPageState({ ...pageState, is_score_rating_panic_msg: "SCORE MUSTN'T BE EMPTY"}) - return - } - const temp = reviewValue.review_textArea.replace(/\n/g, "
") - - setPageState({ ...pageState, temp: temp }) + navigate('/login', { state: { from: `/location/${id}` } }) } useEffect(() => { @@ -162,36 +221,36 @@ function LocationDetail() {
CRITICS SCORE
- {state.critic_count !== 0 ? state.critic_score : "NR"} + {locationDetail.detail.critic_count !== 0 ? Math.floor(Number(locationDetail.detail.critic_score) / Number(locationDetail.detail.critic_count)) : "NR"}
-
+
- {state.critic_count !== 0 && + {locationDetail.detail.critic_count !== 0 &&
- Based on {state.critic_count} reviews + Based on {locationDetail.detail.critic_count} reviews
}
USERS SCORE
-
- {state.user_count !== 0 ? state.user_score : "NR"} +
+ {locationDetail.detail.user_count !== 0 ? Math.floor(Number(locationDetail.detail.user_score) / Number(locationDetail.detail.user_count)) : "NR"}
-
+
- {state.user_count !== 0 && -
- Based on {state.user_count} reviews + {locationDetail.detail.user_count !== 0 && +
+ Based on {locationDetail.detail.user_count} reviews
}
@@ -237,67 +296,87 @@ function LocationDetail() {
+ {!user.username ? +
SIGN IN TO REVIEW
+ : +
+
- {/*
SIGN IN TO REVIEW
*/} -
-
+
+ + + +
-
- - - -
+ -
- user -
+
+ {currentUserReview ? +
+ {console.log(currentUserReview)} +

{currentUserReview.score}

+
+
+
+
+ : + <> + +
/ score
+ {pageState.is_score_rating_panic_msg && +
{pageState.is_score_rating_panic_msg}
+ } + -
-
- -
/ score
- {pageState.is_score_rating_panic_msg && -
{pageState.is_score_rating_panic_msg}
+ } +
+
+ +
+ {currentUserReview ? + + : +