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 { DefaultSeparator } from "../../components";
|
||||||
import { TargetedEvent } from "preact/compat";
|
import { TargetedEvent } from "preact/compat";
|
||||||
import './style.css';
|
import './style.css';
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
|
|
||||||
|
|
||||||
interface TopLocation {
|
interface TopLocation {
|
||||||
row_number: Number,
|
row_number: Number,
|
||||||
@ -57,8 +55,6 @@ function BestLocation() {
|
|||||||
filterRegionType: 0,
|
filterRegionType: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
const navigate = useNavigate()
|
|
||||||
|
|
||||||
async function getTopLocations() {
|
async function getTopLocations() {
|
||||||
try {
|
try {
|
||||||
const res = await getListTopLocationsService({ page: page, page_size: 20, order_by: pageState.filterScoreTypeidx, region_type: pageState.filterRegionType })
|
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})
|
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(() => {
|
useEffect(() => {
|
||||||
getTopLocations()
|
getTopLocations()
|
||||||
}, [pageState])
|
}, [pageState])
|
||||||
@ -152,10 +136,10 @@ function BestLocation() {
|
|||||||
</a>
|
</a>
|
||||||
</div> */}
|
</div> */}
|
||||||
<div className={'mb-2 best-locations-title'}>
|
<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>
|
||||||
<div style={{ maxWidth: 200, maxHeight: 200, margin: '0 30px 30px 10px', float: 'left' }}>
|
<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' }} />
|
<img src={x.thumbnail.String.toString()} loading={'lazy'} style={{ width: '100%', objectFit: 'cover', height: '100%', aspectRatio: '1/1' }} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -67,6 +67,11 @@ img {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-area-button {
|
||||||
|
background-color: gray;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.criticSortFilter {
|
.criticSortFilter {
|
||||||
float: right;
|
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 { ChangeEvent, TargetedEvent } from 'preact/compat';
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import './index.css';
|
|
||||||
import Lightbox from 'yet-another-react-lightbox';
|
import Lightbox from 'yet-another-react-lightbox';
|
||||||
import useCallbackState from '../../types/state-callback';
|
import useCallbackState from '../../types/state-callback';
|
||||||
import { EmptyLocationDetailResponse, LocationDetailResponse, LocationResponse, emptyLocationResponse } from './types';
|
import {
|
||||||
import { useAutosizeTextArea } from '../../utils';
|
EmptyLocationDetailResponse,
|
||||||
import { getImagesByLocationService, getLocationService } from "../../services";
|
LocationDetailResponse,
|
||||||
import { DefaultSeparator, SeparatorWithAnchor, CustomInterweave } from '../../components';
|
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() {
|
function LocationDetail() {
|
||||||
const [locationDetail, setLocationDetail] = useCallbackState<LocationDetailResponse>(EmptyLocationDetailResponse)
|
const [locationDetail, setLocationDetail] = useCallbackState<LocationDetailResponse>(EmptyLocationDetailResponse)
|
||||||
const [locationImages, setLocationImages] = useState<LocationResponse>(emptyLocationResponse())
|
const [locationImages, setLocationImages] = useState<LocationResponse>(emptyLocationResponse())
|
||||||
|
const [currentUserReview, setCurrentUserReview] = useState<CurrentUserLocationReviews>()
|
||||||
const [lightboxOpen, setLightboxOpen] = useState<boolean>(false)
|
const [lightboxOpen, setLightboxOpen] = useState<boolean>(false)
|
||||||
const [pageState, setPageState] = useState({
|
const [pageState, setPageState] = useState({
|
||||||
critic_filter_name: 'highest rated',
|
critic_filter_name: 'highest rated',
|
||||||
critic_filter_type: 0,
|
critic_filter_type: 0,
|
||||||
show_sort: false,
|
show_sort: false,
|
||||||
|
enable_post: true,
|
||||||
|
on_submit_loading: false,
|
||||||
is_score_rating_panic_msg: '',
|
is_score_rating_panic_msg: '',
|
||||||
temp: ''
|
|
||||||
})
|
})
|
||||||
const [reviewValue, setReviewValue] = useState({
|
const [reviewValue, setReviewValue] = useState({
|
||||||
review_textArea: '',
|
review_textArea: '',
|
||||||
@ -26,28 +45,27 @@ function LocationDetail() {
|
|||||||
})
|
})
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(true)
|
const [isLoading, setIsLoading] = useState<boolean>(true)
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const user = useSelector((state: UserRootState) => state.auth)
|
||||||
|
|
||||||
|
|
||||||
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
useAutosizeTextArea(textAreaRef.current, reviewValue.review_textArea);
|
useAutosizeTextArea(textAreaRef.current, reviewValue.review_textArea);
|
||||||
|
|
||||||
const { state } = useLocation();
|
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
|
|
||||||
const SORT_TYPE = [
|
|
||||||
'highest rated',
|
|
||||||
'lowest rated',
|
|
||||||
'newest',
|
|
||||||
'oldest'
|
|
||||||
]
|
|
||||||
|
|
||||||
async function getLocationDetail(): Promise<void> {
|
async function getLocationDetail(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const res = await getLocationService(Number(id))
|
const res = await getLocationService(Number(id))
|
||||||
setLocationDetail(res.data, (val) => {
|
setLocationDetail(res.data, (val) => {
|
||||||
getImage(val.detail.thumbnail.String.toString())
|
getImage(val.detail.thumbnail.String.toString())
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
console.log(err)
|
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 })
|
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();
|
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>")
|
navigate('/login', { state: { from: `/location/${id}` } })
|
||||||
|
|
||||||
setPageState({ ...pageState, temp: temp })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
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={'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={'font-bold ml-1 text-xs'}>CRITICS SCORE</div>
|
||||||
<div className={'text-4xl text-center mt-2 mr-4'} style={{ width: 95, float: 'left' }}>
|
<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={"items-center p-2"}>
|
||||||
<div className={'mr-3 users-score-bar'}>
|
<div className={'mr-3 users-score-bar'}>
|
||||||
<div className={"mt-1"} style={{ height: 4, width: 80, backgroundColor: "#72767d" }}>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{state.critic_count !== 0 &&
|
{locationDetail.detail.critic_count !== 0 &&
|
||||||
<div className={'ml-14 text-sm'}>
|
<div className={'ml-14 text-sm'}>
|
||||||
Based on {state.critic_count} reviews
|
Based on {locationDetail.detail.critic_count} reviews
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={'p-4 bg-secondary mt-1 inline-block'} style={{ width: '100%', height: 120, borderBottomLeftRadius: 10, borderBottomRightRadius: 10 }}>
|
<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={'font-bold ml-2 text-xs'}>USERS SCORE</div>
|
||||||
<div className={'text-4xl text-center mt-2'} style={{ width: 95, float: 'left' }}>
|
<div className={'text-4xl text-center mt-2 mr-4'} style={{ width: 95, float: 'left' }}>
|
||||||
{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"}
|
||||||
<div className={"items-center p-2"}>
|
<div className={"items-center p-2"}>
|
||||||
<div className={'mr-3 users-score-bar'}>
|
<div className={'mr-3 users-score-bar'}>
|
||||||
<div className={"mt-1"} style={{ height: 4, width: 80, backgroundColor: "#72767d" }}>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{state.user_count !== 0 &&
|
{locationDetail.detail.user_count !== 0 &&
|
||||||
<div className={'ml-4'}>
|
<div className={'ml-14 text-sm'}>
|
||||||
Based on {state.user_count} reviews
|
Based on {locationDetail.detail.user_count} reviews
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -237,67 +296,87 @@ function LocationDetail() {
|
|||||||
<section name={'REVIEWS SECTION'}>
|
<section name={'REVIEWS SECTION'}>
|
||||||
<div className={'mt-5'} style={{ tableLayout: 'fixed', display: 'table', width: '100%' }}>
|
<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' }}>
|
<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 className={'userImage mr-3'} style={{ width: 55, float: 'left' }}>
|
||||||
<div name="REVIEW INPUT TEXTAREA" className={'reviewContainer p-4'} style={{ backgroundColor: '#2f3136' }}>
|
<a href={'#'}>
|
||||||
<div className={'reviewBoxContent'} style={{ width: '75%', margin: '0 auto' }}>
|
<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' }}>
|
<div style={{ display: 'block' }}>
|
||||||
<a href={'#'}>
|
<a href={'#'}>{user.username}</a>
|
||||||
<img loading={'lazy'} src={'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'} />
|
</div>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style={{ display: 'block' }}>
|
<div className={'ratingInput'} style={currentUserReview ? { margin: '0 0 10px' } : { margin: '5px 0 10px' }}>
|
||||||
<a href={'#'}>user</a>
|
{currentUserReview ?
|
||||||
</div>
|
<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' }}>
|
<div style={{ clear: 'both' }} />
|
||||||
<input
|
</div>
|
||||||
type={'text'}
|
|
||||||
pattern={"\d*"}
|
<div className={'mt-3'} style={{ width: '100%' }}>
|
||||||
style={{ fontSize: 12, backgroundColor: '#40444b', textAlign: 'center', width: 40, height: 20, lineHeight: 18, border: '1px solid #38444d' }}
|
{currentUserReview ?
|
||||||
maxLength={3}
|
<CustomInterweave
|
||||||
value={reviewValue.score_input}
|
content={currentUserReview.comments}
|
||||||
onChange={handleScoreInputChange}
|
/>
|
||||||
placeholder={"0-100"}
|
:
|
||||||
autoComplete={'off'}
|
<textarea
|
||||||
/>
|
onChange={handleTextAreaChange}
|
||||||
<div className={'inline-block text-xs ml-2 text-tertiary'}>/ score</div>
|
ref={textAreaRef}
|
||||||
{pageState.is_score_rating_panic_msg &&
|
className={'p-2'}
|
||||||
<div className={'inline-block text-xs ml-2 text-error'}>{pageState.is_score_rating_panic_msg}</div>
|
value={reviewValue.review_textArea}
|
||||||
|
style={{ border: 'none', overflow: 'auto', outline: 'none', boxShadow: 'none', backgroundColor: '#40444b', width: '100%', minHeight: 100, overflowY: 'hidden' }}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ clear: 'both' }} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={'mt-3'} style={{ width: '100%' }}>
|
<div style={{ textAlign: 'right', width: "100%" }}>
|
||||||
<textarea
|
<div style={{ display: 'inline-block', fontSize: 11, verticalAlign: 'middle', margin: '0 10px 0 0', letterSpacing: .5 }}>
|
||||||
onChange={handleTextAreaChange}
|
<a>Review Guidelines</a>
|
||||||
ref={textAreaRef}
|
</div>
|
||||||
className={'p-2'}
|
{pageState.on_submit_loading ?
|
||||||
value={reviewValue.review_textArea}
|
<SpinnerLoading />
|
||||||
style={{ border: 'none', overflow: 'auto', outline: 'none', boxShadow: 'none', backgroundColor: '#40444b', width: '100%', minHeight: 100, overflowY: 'hidden' }}
|
:
|
||||||
/>
|
<span className={'text-xxs p-1 text-area-button'} style={pageState.enable_post ? '' : { display: 'none'}}>
|
||||||
</div>
|
<a href={'#'} onClick={handleSubmitReview}>
|
||||||
|
POST
|
||||||
<div style={{ textAlign: 'right', width: "100%" }}>
|
</a>
|
||||||
<div style={{ display: 'inline-block', fontSize: 11, verticalAlign: 'middle', margin: '0 10px 0 0', letterSpacing: .5 }}>
|
</span>
|
||||||
<a>Review Guidelines</a>
|
}
|
||||||
</div>
|
</div>
|
||||||
<span className={'text-xxs p-1'} style={{ backgroundColor: 'gray', letterSpacing: 1 }}>
|
|
||||||
<a href={'#'} onClick={handleSubmitReview}>
|
|
||||||
POST
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CustomInterweave
|
|
||||||
content={pageState.temp}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
}
|
||||||
<div name={'CRTICITS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
<div name={'CRTICITS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
||||||
<SeparatorWithAnchor pageName={"critic's review"} pageLink='#' />
|
<SeparatorWithAnchor pageName={"critic's review"} pageLink='#' />
|
||||||
<div className={'criticSortFilter'}>
|
<div className={'criticSortFilter'}>
|
||||||
@ -314,236 +393,121 @@ function LocationDetail() {
|
|||||||
</div>
|
</div>
|
||||||
<div style={{ clear: 'both' }} />
|
<div style={{ clear: 'both' }} />
|
||||||
|
|
||||||
<div className={''} style={{ padding: '15px 0' }}>
|
{locationDetail.critics_review.map(x => (
|
||||||
<div style={{ float: 'left' }}>
|
<div className={''} style={{ padding: '15px 0' }}>
|
||||||
<div style={{ fontSize: 20, marginRight: 20, textAlign: 'center', width: 55, marginBottom: 3 }}>
|
<div style={{ float: 'left' }}>
|
||||||
90
|
<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>
|
||||||
<div style={{ height: 4, width: 55, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
<div className={'mr-3'} style={{ display: 'inline-block', width: 40 }}>
|
||||||
<div style={{ height: 4, backgroundColor: '#85ce73', width: '90%' }} />
|
<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>
|
<div style={{ display: 'inline-block', verticalAlign: 'top' }}>
|
||||||
<div className={'mr-3'} style={{ display: 'inline-block', width: 40 }}>
|
<div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
|
||||||
<a href="#">
|
<a>
|
||||||
<img
|
<span>{x.username}</span>
|
||||||
loading={'lazy'}
|
</a>
|
||||||
style={{ width: '100%' }}
|
</div>
|
||||||
src={'https://cdn.discordapp.com/attachments/743422487882104837/1153985664849805392/421-4212617_person-placeholder-image-transparent-hd-png-download.png'}
|
</div>
|
||||||
|
<div style={{ fontSize: 15, lineHeight: '24px', margin: '5px 75px 1px' }}>
|
||||||
|
<CustomInterweave
|
||||||
|
content={x.comments}
|
||||||
/>
|
/>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
<div className={'reviewLinks'} style={{ marginLeft: 72 }}>
|
||||||
<div style={{ display: 'inline-block', verticalAlign: 'top' }}>
|
<div className={'mr-2'} style={{ minWidth: 55, display: 'inline-block', verticalAlign: 'middle' }}>
|
||||||
<div style={{ fontWeight: 700, fontSize: 16, lineHeight: 'initial' }}>
|
<a className={'text-sm'} href={'#'}>
|
||||||
<a>
|
<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>
|
||||||
<span>Benito Mussolini</span>
|
<div className={'inline-block'}>Video</div>
|
||||||
</a>
|
</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>
|
||||||
<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>
|
||||||
|
|
||||||
<div name={'USERS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
<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={'review-more-button text-center text-sm mt-5'}>
|
||||||
<div className={'mr-5'} style={{ width: 45, float: 'left' }}>
|
<a style={{ borderRadius: 15, padding: '8px 32px', border: '1px solid #d8d8d8' }}>
|
||||||
<a href="#">
|
More
|
||||||
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
<div className={'inline-block'}>
|
:
|
||||||
<div className={'text-sm text-center'} >80</div>
|
<>
|
||||||
<div style={{ height: 4, width: 25, position: 'relative', backgroundColor: '#d8d8d8' }}>
|
<span className={'text-sm italic'}>No users review to display</span>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div name={'USERS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
{/* <div name={'USERS REVIEW'} style={{ margin: '50px 0', textAlign: 'left' }}>
|
||||||
<SeparatorWithAnchor pageName={"Recent User's review"} pageLink='#' secondLink='#'/>
|
<SeparatorWithAnchor pageName={"Popular User's review"} pageLink='#' secondLink='#' />
|
||||||
<div className={''} style={{ padding: '15px 0' }}>
|
<div className={''} style={{ padding: '15px 0' }}>
|
||||||
<div className={'mr-5'} style={{ width: 45, float: 'left' }}>
|
<div className={'mr-5'} style={{ width: 45, float: 'left' }}>
|
||||||
<a href="#">
|
<a href="#">
|
||||||
@ -628,11 +592,11 @@ function LocationDetail() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'review-more-button text-center text-sm mt-5'}>
|
<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
|
More
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
<div className={'mb-5'}>
|
<div className={'mb-5'}>
|
||||||
CONTRUBITION
|
CONTRUBITION
|
||||||
<DefaultSeparator />
|
<DefaultSeparator />
|
||||||
@ -645,7 +609,7 @@ function LocationDetail() {
|
|||||||
</div>
|
</div>
|
||||||
} */}
|
} */}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ clear: 'both'}} />
|
<div style={{ clear: 'both' }} />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
@ -4,13 +4,16 @@ export interface ILocationDetail {
|
|||||||
id: Number,
|
id: Number,
|
||||||
name: String,
|
name: String,
|
||||||
address: String,
|
address: String,
|
||||||
|
regency_name: String,
|
||||||
|
province_name: String,
|
||||||
|
region_name: String,
|
||||||
google_maps_link: String,
|
google_maps_link: String,
|
||||||
thumbnail: NullValueRes<"String", String>,
|
thumbnail: NullValueRes<"String", String>,
|
||||||
submitted_by: Number,
|
submitted_by: Number,
|
||||||
regency_name: String,
|
critic_score: Number,
|
||||||
province_name: String,
|
critic_count: Number,
|
||||||
region_name: String,
|
user_score: Number,
|
||||||
submitted_by_user: String
|
user_count: Number
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emptyLocationDetail(): ILocationDetail {
|
export function emptyLocationDetail(): ILocationDetail {
|
||||||
@ -24,19 +27,38 @@ export function emptyLocationDetail(): ILocationDetail {
|
|||||||
regency_name: '',
|
regency_name: '',
|
||||||
region_name: '',
|
region_name: '',
|
||||||
submitted_by: 0,
|
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 {
|
export interface LocationDetailResponse {
|
||||||
detail: ILocationDetail,
|
detail: ILocationDetail,
|
||||||
tags: Array<String>
|
tags: Array<String>
|
||||||
|
users_review: Array<LocationReviewsResponse>,
|
||||||
|
critics_review: Array<LocationReviewsResponse>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function EmptyLocationDetailResponse(): LocationDetailResponse {
|
export function EmptyLocationDetailResponse(): LocationDetailResponse {
|
||||||
return {
|
return {
|
||||||
detail: emptyLocationDetail(),
|
detail: emptyLocationDetail(),
|
||||||
tags: []
|
tags: [],
|
||||||
|
critics_review: Array<LocationReviewsResponse>(),
|
||||||
|
users_review: Array<LocationReviewsResponse>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,15 +69,6 @@ export interface LocationImage extends SlideImage {
|
|||||||
uploaded_by: String
|
uploaded_by: String
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emptyLocationImage(): LocationImage {
|
|
||||||
return {
|
|
||||||
id: 0,
|
|
||||||
src: '',
|
|
||||||
created_at: '',
|
|
||||||
uploaded_by: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LocationResponse {
|
export interface LocationResponse {
|
||||||
total_image: Number,
|
total_image: Number,
|
||||||
images: Array<LocationImage>
|
images: Array<LocationImage>
|
||||||
@ -64,6 +77,18 @@ export interface LocationResponse {
|
|||||||
export function emptyLocationResponse(): LocationResponse {
|
export function emptyLocationResponse(): LocationResponse {
|
||||||
return {
|
return {
|
||||||
total_image: 0,
|
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;
|
return newState;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} 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 {
|
interface IEmptyResponseState {
|
||||||
data: unknown,
|
data: any,
|
||||||
error: any,
|
error: any,
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user