adjust location detail response with reviews
This commit is contained in:
parent
cd680de68b
commit
00c8831dc9
@ -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() {
|
||||
</a>
|
||||
</div> */}
|
||||
<div className={'mb-2 best-locations-title'}>
|
||||
<a className={'text-xl'} href={`/location/${x.id}`} onClick={() => onNavigateToDetail(x.id, x.critic_count, x.critic_score, x.user_count, x.user_score)}>{x.row_number}.{x.name}</a>
|
||||
<a className={'text-xl'} href={`/location/${x.id}`}>{x.row_number}.{x.name}</a>
|
||||
</div>
|
||||
<div style={{ maxWidth: 200, maxHeight: 200, margin: '0 30px 30px 10px', float: 'left' }}>
|
||||
<a href={`/location/${x.id}`} onClick={() => onNavigateToDetail(x.id, x.critic_count, x.critic_score, x.user_count, x.user_score)}>
|
||||
<a href={`/location/${x.id}`} >
|
||||
<img src={x.thumbnail.String.toString()} loading={'lazy'} style={{ width: '100%', objectFit: 'cover', height: '100%', aspectRatio: '1/1' }} />
|
||||
</a>
|
||||
</div>
|
||||
|
@ -67,6 +67,11 @@ img {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.text-area-button {
|
||||
background-color: gray;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.criticSortFilter {
|
||||
float: right;
|
||||
}
|
||||
|
@ -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<LocationDetailResponse>(EmptyLocationDetailResponse)
|
||||
const [locationImages, setLocationImages] = useState<LocationResponse>(emptyLocationResponse())
|
||||
const [currentUserReview, setCurrentUserReview] = useState<CurrentUserLocationReviews>()
|
||||
const [lightboxOpen, setLightboxOpen] = useState<boolean>(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<boolean>(true)
|
||||
|
||||
const navigate = useNavigate();
|
||||
const user = useSelector((state: UserRootState) => state.auth)
|
||||
|
||||
|
||||
const textAreaRef = useRef<HTMLTextAreaElement>(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<void> {
|
||||
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<HTMLAnchorElement>) {
|
||||
async function handleSubmitReview(e: TargetedEvent<HTMLAnchorElement>) {
|
||||
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<HTMLAnchorElement>) {
|
||||
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, "<br>")
|
||||
|
||||
setPageState({ ...pageState, temp: temp })
|
||||
navigate('/login', { state: { from: `/location/${id}` } })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@ -162,36 +221,36 @@ function LocationDetail() {
|
||||
<div className={'p-4 bg-secondary mt-3'} style={{ width: '100%', height: 120, borderTopLeftRadius: 10, borderTopRightRadius: 10 }}>
|
||||
<div className={'font-bold ml-1 text-xs'}>CRITICS SCORE</div>
|
||||
<div className={'text-4xl text-center mt-2 mr-4'} style={{ width: 95, float: 'left' }}>
|
||||
{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"}
|
||||
<div className={"items-center p-2"}>
|
||||
<div className={'mr-3 users-score-bar'}>
|
||||
<div className={"mt-1"} style={{ height: 4, width: 80, backgroundColor: "#72767d" }}>
|
||||
<div style={{ height: 4, width: ` ${state.critic_count !== 0 ? Number(state.critic_score) / Number(state.critic_count) * 10 : 0}%`, backgroundColor: 'green' }} />
|
||||
<div style={{ height: 4, width: ` ${locationDetail.detail.critic_count !== 0 ? Number(locationDetail.detail.critic_score) : 0}%`, backgroundColor: 'green' }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{state.critic_count !== 0 &&
|
||||
{locationDetail.detail.critic_count !== 0 &&
|
||||
<div className={'ml-14 text-sm'}>
|
||||
Based on {state.critic_count} reviews
|
||||
Based on {locationDetail.detail.critic_count} reviews
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div className={'p-4 bg-secondary mt-1 inline-block'} style={{ width: '100%', height: 120, borderBottomLeftRadius: 10, borderBottomRightRadius: 10 }}>
|
||||
<div className={'font-bold ml-2 text-xs'}>USERS SCORE</div>
|
||||
<div className={'text-4xl text-center mt-2'} style={{ width: 95, float: 'left' }}>
|
||||
{state.user_count !== 0 ? state.user_score : "NR"}
|
||||
<div className={'text-4xl text-center mt-2 mr-4'} style={{ width: 95, float: 'left' }}>
|
||||
{locationDetail.detail.user_count !== 0 ? Math.floor(Number(locationDetail.detail.user_score) / Number(locationDetail.detail.user_count)) : "NR"}
|
||||
<div className={"items-center p-2"}>
|
||||
<div className={'mr-3 users-score-bar'}>
|
||||
<div className={"mt-1"} style={{ height: 4, width: 80, backgroundColor: "#72767d" }}>
|
||||
<div style={{ height: 4, width: ` ${state.user_count !== 0 ? Number(state.user_score) / Number(state.user_score) * 10 : 0}%`, backgroundColor: 'green' }} />
|
||||
<div style={{ height: 4, width: ` ${locationDetail.detail.user_count !== 0 ? Number(locationDetail.detail.user_score) / Number(locationDetail.detail.user_count) : 0}%`, backgroundColor: 'green' }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{state.user_count !== 0 &&
|
||||
<div className={'ml-4'}>
|
||||
Based on {state.user_count} reviews
|
||||
{locationDetail.detail.user_count !== 0 &&
|
||||
<div className={'ml-14 text-sm'}>
|
||||
Based on {locationDetail.detail.user_count} reviews
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@ -237,67 +296,87 @@ function LocationDetail() {
|
||||
<section name={'REVIEWS SECTION'}>
|
||||
<div className={'mt-5'} style={{ tableLayout: 'fixed', display: 'table', width: '100%' }}>
|
||||
<div className={'wideLeft'} style={{ textAlign: 'left', paddingRight: 20, maxWidth: 1096, minWidth: 680, display: 'table-cell', position: 'relative', verticalAlign: 'top', width: '100%', boxSizing: 'border-box' }}>
|
||||
{!user.username ?
|
||||
<div className={'bg-secondary text-center p-3'} style={{ width: '100%' }}><a href={'#'} onClick={handleSignInNavigation} style={{ borderBottom: '1px solid white' }}>SIGN IN</a> TO REVIEW</div>
|
||||
:
|
||||
<div name="REVIEW INPUT TEXTAREA" className={'reviewContainer p-4'} style={{ backgroundColor: '#2f3136' }}>
|
||||
<div className={'reviewBoxContent'} style={{ width: '75%', margin: '0 auto' }}>
|
||||
|
||||
{/* <div className={'bg-secondary text-center p-3'} style={{ width: '100%'}}><a href={'#'}>SIGN IN</a> TO REVIEW</div> */}
|
||||
<div name="REVIEW INPUT TEXTAREA" className={'reviewContainer p-4'} style={{ backgroundColor: '#2f3136' }}>
|
||||
<div className={'reviewBoxContent'} style={{ width: '75%', margin: '0 auto' }}>
|
||||
<div className={'userImage mr-3'} style={{ width: 55, float: 'left' }}>
|
||||
<a href={'#'}>
|
||||
<img loading={'lazy'} src={user.avatar_picture != '' ? user.avatar_picture.toString() : DEFAULT_AVATAR_IMG} style={{ aspectRatio: '1/1' }} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className={'userImage mr-3'} style={{ width: 55, float: 'left' }}>
|
||||
<a href={'#'}>
|
||||
<img loading={'lazy'} src={'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'} />
|
||||
</a>
|
||||
</div>
|
||||
<div style={{ display: 'block' }}>
|
||||
<a href={'#'}>{user.username}</a>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'block' }}>
|
||||
<a href={'#'}>user</a>
|
||||
</div>
|
||||
<div className={'ratingInput'} style={currentUserReview ? { margin: '0 0 10px' } : { margin: '5px 0 10px' }}>
|
||||
{currentUserReview ?
|
||||
<div style={{ display: 'inline-block' }}>
|
||||
{console.log(currentUserReview)}
|
||||
<p className={'ml-2'}>{currentUserReview.score}</p>
|
||||
<div style={{ height: 4, width: 35, backgroundColor: "#72767d" }}>
|
||||
<div style={{ height: 4, width: `${currentUserReview.score}%`, backgroundColor: 'green' }} />
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<>
|
||||
<input
|
||||
type={'text'}
|
||||
pattern={"\d*"}
|
||||
style={{ fontSize: 12, backgroundColor: '#40444b', textAlign: 'center', width: 40, height: 20, lineHeight: 18, border: '1px solid #38444d' }}
|
||||
maxLength={3}
|
||||
value={reviewValue.score_input}
|
||||
onChange={handleScoreInputChange}
|
||||
placeholder={"0-100"}
|
||||
autoComplete={'off'}
|
||||
/>
|
||||
<div className={'inline-block text-xs ml-2 text-tertiary'}>/ score</div>
|
||||
{pageState.is_score_rating_panic_msg &&
|
||||
<div className={'inline-block text-xs ml-2 text-error'}>{pageState.is_score_rating_panic_msg}</div>
|
||||
}
|
||||
</>
|
||||
|
||||
<div className={'ratingInput'} style={{ margin: '5px 0 10px' }}>
|
||||
<div style={{ float: 'left' }}>
|
||||
<input
|
||||
type={'text'}
|
||||
pattern={"\d*"}
|
||||
style={{ fontSize: 12, backgroundColor: '#40444b', textAlign: 'center', width: 40, height: 20, lineHeight: 18, border: '1px solid #38444d' }}
|
||||
maxLength={3}
|
||||
value={reviewValue.score_input}
|
||||
onChange={handleScoreInputChange}
|
||||
placeholder={"0-100"}
|
||||
autoComplete={'off'}
|
||||
/>
|
||||
<div className={'inline-block text-xs ml-2 text-tertiary'}>/ score</div>
|
||||
{pageState.is_score_rating_panic_msg &&
|
||||
<div className={'inline-block text-xs ml-2 text-error'}>{pageState.is_score_rating_panic_msg}</div>
|
||||
}
|
||||
<div style={{ clear: 'both' }} />
|
||||
</div>
|
||||
|
||||
<div className={'mt-3'} style={{ width: '100%' }}>
|
||||
{currentUserReview ?
|
||||
<CustomInterweave
|
||||
content={currentUserReview.comments}
|
||||
/>
|
||||
:
|
||||
<textarea
|
||||
onChange={handleTextAreaChange}
|
||||
ref={textAreaRef}
|
||||
className={'p-2'}
|
||||
value={reviewValue.review_textArea}
|
||||
style={{ border: 'none', overflow: 'auto', outline: 'none', boxShadow: 'none', backgroundColor: '#40444b', width: '100%', minHeight: 100, overflowY: 'hidden' }}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<div style={{ clear: 'both' }} />
|
||||
</div>
|
||||
|
||||
<div className={'mt-3'} style={{ width: '100%' }}>
|
||||
<textarea
|
||||
onChange={handleTextAreaChange}
|
||||
ref={textAreaRef}
|
||||
className={'p-2'}
|
||||
value={reviewValue.review_textArea}
|
||||
style={{ border: 'none', overflow: 'auto', outline: 'none', boxShadow: 'none', backgroundColor: '#40444b', width: '100%', minHeight: 100, overflowY: 'hidden' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ textAlign: 'right', width: "100%" }}>
|
||||
<div style={{ display: 'inline-block', fontSize: 11, verticalAlign: 'middle', margin: '0 10px 0 0', letterSpacing: .5 }}>
|
||||
<a>Review Guidelines</a>
|
||||
<div style={{ textAlign: 'right', width: "100%" }}>
|
||||
<div style={{ display: 'inline-block', fontSize: 11, verticalAlign: 'middle', margin: '0 10px 0 0', letterSpacing: .5 }}>
|
||||
<a>Review Guidelines</a>
|
||||
</div>
|
||||
{pageState.on_submit_loading ?
|
||||
<SpinnerLoading />
|
||||
:
|
||||
<span className={'text-xxs p-1 text-area-button'} style={pageState.enable_post ? '' : { display: 'none'}}>
|
||||
<a href={'#'} onClick={handleSubmitReview}>
|
||||
POST
|
||||
</a>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
<span className={'text-xxs p-1'} style={{ backgroundColor: 'gray', letterSpacing: 1 }}>
|
||||
<a href={'#'} onClick={handleSubmitReview}>
|
||||
POST
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<CustomInterweave
|
||||
content={pageState.temp}
|
||||
/>
|
||||
</div>
|
||||
|
||||
}
|
||||
<div name={'CRTICITS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
||||
<SeparatorWithAnchor pageName={"critic's review"} pageLink='#' />
|
||||
<div className={'criticSortFilter'}>
|
||||
@ -314,236 +393,121 @@ function LocationDetail() {
|
||||
</div>
|
||||
<div style={{ clear: 'both' }} />
|
||||
|
||||
<div className={''} style={{ padding: '15px 0' }}>
|
||||
<div style={{ float: 'left' }}>
|
||||
<div style={{ fontSize: 20, marginRight: 20, textAlign: 'center', width: 55, marginBottom: 3 }}>
|
||||
90
|
||||
{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 style={{ height: 4, width: 55, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
||||
<div style={{ height: 4, backgroundColor: '#85ce73', width: '90%' }} />
|
||||
<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>
|
||||
<div className={'mr-3'} style={{ display: 'inline-block', width: 40 }}>
|
||||
<a href="#">
|
||||
<img
|
||||
loading={'lazy'}
|
||||
style={{ width: '100%' }}
|
||||
src={'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'}
|
||||
<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}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div style={{ display: 'inline-block', verticalAlign: 'top' }}>
|
||||
<div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
|
||||
<a>
|
||||
<span>Benito Mussolini</span>
|
||||
</a>
|
||||
</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={{ fontSize: 15, lineHeight: '24px', margin: '5px 75px 1px', wordWrap: 'break-word' }}>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro nihil dolor delectus ex minima aliquid quidem veniam officiis temporibus ipsum ea incidunt voluptatum a, repellat illum, cumque consequatur saepe assumenda.</p>
|
||||
</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 className={''} style={{ padding: '15px 0', borderTop: '1px solid #38444d' }}>
|
||||
<div style={{ float: 'left' }}>
|
||||
<div style={{ fontSize: 20, marginRight: 20, textAlign: 'center', width: 55, marginBottom: 3 }}>
|
||||
90
|
||||
</div>
|
||||
<div style={{ height: 4, width: 55, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
||||
<div style={{ height: 4, backgroundColor: '#85ce73', width: '90%' }} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={'mr-3'} style={{ display: 'inline-block', width: 40 }}>
|
||||
<a href="#">
|
||||
<img
|
||||
loading={'lazy'}
|
||||
style={{ width: '100%' }}
|
||||
src={'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>Benito Mussolini</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ fontSize: 15, lineHeight: '24px', margin: '5px 75px 1px', wordWrap: 'break-word' }}>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro nihil dolor delectus ex minima aliquid quidem veniam officiis temporibus ipsum ea incidunt voluptatum a, repellat illum, cumque consequatur saepe assumenda.</p>
|
||||
</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 className={''} style={{ padding: '15px 0', borderTop: '1px solid #38444d' }}>
|
||||
<div style={{ float: 'left' }}>
|
||||
<div style={{ fontSize: 20, marginRight: 20, textAlign: 'center', width: 55, marginBottom: 3 }}>
|
||||
90
|
||||
</div>
|
||||
<div style={{ height: 4, width: 55, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
||||
<div style={{ height: 4, backgroundColor: '#85ce73', width: '90%' }} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={'mr-3'} style={{ display: 'inline-block', width: 40 }}>
|
||||
<a href="#">
|
||||
<img
|
||||
loading={'lazy'}
|
||||
style={{ width: '100%' }}
|
||||
src={'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>Benito Mussolini</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ fontSize: 15, lineHeight: '24px', margin: '5px 75px 1px', wordWrap: 'break-word' }}>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro nihil dolor delectus ex minima aliquid quidem veniam officiis temporibus ipsum ea incidunt voluptatum a, repellat illum, cumque consequatur saepe assumenda.</p>
|
||||
</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>
|
||||
|
||||
<div name={'USERS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
||||
<SeparatorWithAnchor pageName={"Popular User's review"} pageLink='#' secondLink='#'/>
|
||||
<SeparatorWithAnchor pageName={"User's review"} pageLink='#' secondLink={locationDetail.users_review.length > 0 ? '#' : ''} />
|
||||
{ locationDetail.users_review.length > 0 ?
|
||||
<>
|
||||
{locationDetail.users_review.map(x => (
|
||||
<div style={{ padding: '15px 0' }}>
|
||||
<div className={'mr-5'} style={{ width: 45, float: 'left' }}>
|
||||
<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>
|
||||
<div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
|
||||
<a>
|
||||
<span>{x.username}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'inline-block'}>
|
||||
<div className={'text-sm text-center'} >{x.score}</div>
|
||||
<div style={{ height: 4, width: 25, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
||||
<div style={{ height: 4, backgroundColor: '#85ce73', width: `${x.score}%` }} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ fontSize: 15, lineHeight: '24px', margin: '10px 65px 1px', wordWrap: 'break-word' }}>
|
||||
<CustomInterweave
|
||||
content={x.comments}
|
||||
/>
|
||||
</div>
|
||||
<div className={'reviewLinks'} style={{ marginLeft: 63 }}>
|
||||
<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 className={''} style={{ padding: '15px 0' }}>
|
||||
<div className={'mr-5'} style={{ width: 45, float: 'left' }}>
|
||||
<a href="#">
|
||||
<img
|
||||
loading={'lazy'}
|
||||
style={{ width: '100%' }}
|
||||
src={'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
|
||||
<a>
|
||||
<span>Benito Mussolini</span>
|
||||
<div className={'review-more-button text-center text-sm mt-5'}>
|
||||
<a style={{ borderRadius: 15, padding: '8px 32px', border: '1px solid #d8d8d8' }}>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'inline-block'}>
|
||||
<div className={'text-sm text-center'} >80</div>
|
||||
<div style={{ height: 4, width: 25, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
||||
<div style={{ height: 4, backgroundColor: '#85ce73', width: '90%' }} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ fontSize: 15, lineHeight: '24px', margin: '10px 65px 1px', wordWrap: 'break-word' }}>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro nihil dolor delectus ex minima aliquid quidem veniam officiis temporibus ipsum ea incidunt voluptatum a, repellat illum, cumque consequatur saepe assumenda.</p>
|
||||
</div>
|
||||
<div className={'reviewLinks'} style={{ marginLeft: 63 }}>
|
||||
<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 className={''} style={{ padding: '15px 0', borderTop: '1px solid #38444d' }}>
|
||||
<div className={'mr-5'} style={{ width: 45, float: 'left' }}>
|
||||
<a href="#">
|
||||
<img
|
||||
loading={'lazy'}
|
||||
style={{ width: '100%' }}
|
||||
src={'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
|
||||
<a>
|
||||
<span>Benito Mussolini</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'inline-block'}>
|
||||
<div className={'text-sm text-center'} >80</div>
|
||||
<div style={{ height: 4, width: 25, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
||||
<div style={{ height: 4, backgroundColor: '#85ce73', width: '90%' }} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ fontSize: 15, lineHeight: '24px', margin: '10px 65px 1px', wordWrap: 'break-word' }}>
|
||||
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro nihil dolor delectus ex minima aliquid quidem veniam officiis temporibus ipsum ea incidunt voluptatum a, repellat illum, cumque consequatur saepe assumenda.</p>
|
||||
</div>
|
||||
<div className={'reviewLinks'} style={{ marginLeft: 63 }}>
|
||||
<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 className={'review-more-button text-center text-sm mt-5'}>
|
||||
<a style={{ borderRadius: 15, padding: '8px 32px', border: '1px solid #d8d8d8'}}>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
:
|
||||
<>
|
||||
<span className={'text-sm italic'}>No users review to display</span>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
<div name={'USERS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
||||
<SeparatorWithAnchor pageName={"Recent User's review"} pageLink='#' secondLink='#'/>
|
||||
{/* <div name={'USERS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
||||
<SeparatorWithAnchor pageName={"Popular User's review"} pageLink='#' secondLink='#' />
|
||||
<div className={''} style={{ padding: '15px 0' }}>
|
||||
<div className={'mr-5'} style={{ width: 45, float: 'left' }}>
|
||||
<a href="#">
|
||||
@ -628,11 +592,11 @@ function LocationDetail() {
|
||||
</div>
|
||||
</div>
|
||||
<div className={'review-more-button text-center text-sm mt-5'}>
|
||||
<a style={{ borderRadius: 15, padding: '8px 32px', border: '1px solid #d8d8d8'}}>
|
||||
<a style={{ borderRadius: 15, padding: '8px 32px', border: '1px solid #d8d8d8' }}>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className={'mb-5'}>
|
||||
CONTRUBITION
|
||||
<DefaultSeparator />
|
||||
@ -645,7 +609,7 @@ function LocationDetail() {
|
||||
</div>
|
||||
} */}
|
||||
</div>
|
||||
<div style={{ clear: 'both'}} />
|
||||
<div style={{ clear: 'both' }} />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
@ -4,13 +4,16 @@ export interface ILocationDetail {
|
||||
id: Number,
|
||||
name: String,
|
||||
address: String,
|
||||
regency_name: String,
|
||||
province_name: String,
|
||||
region_name: String,
|
||||
google_maps_link: String,
|
||||
thumbnail: NullValueRes<"String", String>,
|
||||
submitted_by: Number,
|
||||
regency_name: String,
|
||||
province_name: String,
|
||||
region_name: String,
|
||||
submitted_by_user: String
|
||||
critic_score: Number,
|
||||
critic_count: Number,
|
||||
user_score: Number,
|
||||
user_count: Number
|
||||
}
|
||||
|
||||
export function emptyLocationDetail(): ILocationDetail {
|
||||
@ -24,19 +27,38 @@ export function emptyLocationDetail(): ILocationDetail {
|
||||
regency_name: '',
|
||||
region_name: '',
|
||||
submitted_by: 0,
|
||||
submitted_by_user: ''
|
||||
critic_score: 0,
|
||||
critic_count: 0,
|
||||
user_score: 0,
|
||||
user_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
export interface LocationReviewsResponse {
|
||||
id: number,
|
||||
score: number,
|
||||
comments: string,
|
||||
user_id: number,
|
||||
username: string,
|
||||
user_avatar: NullValueRes<"String", string>,
|
||||
created_at: string,
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface LocationDetailResponse {
|
||||
detail: ILocationDetail,
|
||||
tags: Array<String>
|
||||
users_review: Array<LocationReviewsResponse>,
|
||||
critics_review: Array<LocationReviewsResponse>
|
||||
}
|
||||
|
||||
|
||||
export function EmptyLocationDetailResponse(): LocationDetailResponse {
|
||||
return {
|
||||
detail: emptyLocationDetail(),
|
||||
tags: []
|
||||
tags: [],
|
||||
critics_review: Array<LocationReviewsResponse>(),
|
||||
users_review: Array<LocationReviewsResponse>()
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,15 +69,6 @@ export interface LocationImage extends SlideImage {
|
||||
uploaded_by: String
|
||||
}
|
||||
|
||||
export function emptyLocationImage(): LocationImage {
|
||||
return {
|
||||
id: 0,
|
||||
src: '',
|
||||
created_at: '',
|
||||
uploaded_by: ''
|
||||
}
|
||||
}
|
||||
|
||||
export interface LocationResponse {
|
||||
total_image: Number,
|
||||
images: Array<LocationImage>
|
||||
@ -64,6 +77,18 @@ export interface LocationResponse {
|
||||
export function emptyLocationResponse(): LocationResponse {
|
||||
return {
|
||||
total_image: 0,
|
||||
images: [emptyLocationImage()]
|
||||
images: Array<LocationImage>()
|
||||
}
|
||||
}
|
||||
|
||||
export type CurrentUserLocationReviews = {
|
||||
id: Number,
|
||||
comments: string,
|
||||
is_from_critic: boolean,
|
||||
is_hided: boolean,
|
||||
location_id: Number,
|
||||
score: Number,
|
||||
submitted_by: Number,
|
||||
created_at: NullValueRes<"Time", string>,
|
||||
updated_at: NullValueRes<"Time", string>,
|
||||
}
|
@ -80,7 +80,7 @@ async function getLocationService(id: Number) {
|
||||
return newState;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
throw(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
34
src/services/review.ts
Normal file
34
src/services/review.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { AxiosError } from "axios"
|
||||
import { client } from "./config";
|
||||
import { POST_REVIEW_LOCATION_URI } from "../constants/api";
|
||||
|
||||
const initialState: IEmptyResponseState = {
|
||||
data: null,
|
||||
error: AxiosError
|
||||
}
|
||||
|
||||
interface postReviewLocationReq {
|
||||
submitted_by: number,
|
||||
comments: string,
|
||||
score: number,
|
||||
is_from_critic: boolean,
|
||||
is_hided: boolean,
|
||||
location_id: number
|
||||
}
|
||||
|
||||
async function postReviewLocation(req: postReviewLocationReq) {
|
||||
const newState = { ...initialState };
|
||||
try {
|
||||
const response = await client({ method: 'POST', url: POST_REVIEW_LOCATION_URI, data: req, withCredentials: true})
|
||||
newState.data = response.data
|
||||
newState.error = null
|
||||
return newState
|
||||
} catch (error) {
|
||||
newState.error = error
|
||||
throw(error)
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
postReviewLocation
|
||||
}
|
@ -8,6 +8,6 @@ interface GetRequestPagination {
|
||||
|
||||
|
||||
interface IEmptyResponseState {
|
||||
data: unknown,
|
||||
data: any,
|
||||
error: any,
|
||||
};
|
Loading…
Reference in New Issue
Block a user