Compare commits
No commits in common. "dev" and "master" have entirely different histories.
0
.gitignore
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
0
index.html
Executable file → Normal file
0
index.html
Executable file → Normal file
2
package.json
Executable file → Normal file
2
package.json
Executable file → Normal file
@ -9,8 +9,8 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/react": "^0.26.9",
|
|
||||||
"@reduxjs/toolkit": "^1.9.5",
|
"@reduxjs/toolkit": "^1.9.5",
|
||||||
|
"@types/react-redux": "^7.1.26",
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
"emojibase": "^15.0.0",
|
"emojibase": "^15.0.0",
|
||||||
"interweave": "^13.1.0",
|
"interweave": "^13.1.0",
|
||||||
|
2769
pnpm-lock.yaml
Executable file → Normal file
2769
pnpm-lock.yaml
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
0
postcss.config.js
Executable file → Normal file
0
postcss.config.js
Executable file → Normal file
0
public/vite.svg
Executable file → Normal file
0
public/vite.svg
Executable file → Normal file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
src/actions/LogoutAction.ts
Executable file → Normal file
0
src/actions/LogoutAction.ts
Executable file → Normal file
0
src/actions/index.ts
Executable file → Normal file
0
src/actions/index.ts
Executable file → Normal file
4
src/app.css
Executable file → Normal file
4
src/app.css
Executable file → Normal file
@ -60,10 +60,6 @@
|
|||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-checkbox:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and(max-width: 425px) {
|
@media screen and(max-width: 425px) {
|
||||||
.users-score {
|
.users-score {
|
||||||
font-size: .75rem;
|
font-size: .75rem;
|
||||||
|
10
src/app.tsx
Executable file → Normal file
10
src/app.tsx
Executable file → Normal file
@ -14,6 +14,7 @@ import { getRoutes } from './routes';
|
|||||||
export function App() {
|
export function App() {
|
||||||
const { routes } = getRoutes();
|
const { routes } = getRoutes();
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate persistor={persistore}>
|
<PersistGate persistor={persistore}>
|
||||||
<Router>
|
<Router>
|
||||||
@ -24,6 +25,7 @@ export function App() {
|
|||||||
let Element = element as any
|
let Element = element as any
|
||||||
if (protectedRoute === "user") {
|
if (protectedRoute === "user") {
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<Route
|
<Route
|
||||||
path={path}
|
path={path}
|
||||||
id={name}
|
id={name}
|
||||||
@ -33,11 +35,14 @@ export function App() {
|
|||||||
</UserProtectedRoute>
|
</UserProtectedRoute>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protectedRoute === "admin") {
|
if (protectedRoute === "admin") {
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<>
|
||||||
<Route
|
<Route
|
||||||
path={path}
|
path={path}
|
||||||
id={name}
|
id={name}
|
||||||
@ -47,14 +52,18 @@ export function App() {
|
|||||||
</AdminProtectedRoute>
|
</AdminProtectedRoute>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<Route
|
<Route
|
||||||
path={path}
|
path={path}
|
||||||
id={name}
|
id={name}
|
||||||
element={element}
|
element={element}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
@ -63,5 +72,6 @@ export function App() {
|
|||||||
</Router>
|
</Router>
|
||||||
</PersistGate>
|
</PersistGate>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
0
src/assets/preact.svg
Executable file → Normal file
0
src/assets/preact.svg
Executable file → Normal file
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
0
src/components/Button/DefaultButton/index.tsx
Executable file → Normal file
0
src/components/Button/DefaultButton/index.tsx
Executable file → Normal file
0
src/components/Button/DefaultButton/style.css
Executable file → Normal file
0
src/components/Button/DefaultButton/style.css
Executable file → Normal file
@ -1,14 +0,0 @@
|
|||||||
import "./style.css";
|
|
||||||
|
|
||||||
interface ComponentProps {
|
|
||||||
label: string
|
|
||||||
onClick: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FilterButton = (props: ComponentProps) => (
|
|
||||||
<button onClick={props.onClick} className="button-container">
|
|
||||||
<div className="button-label">{props.label}</div>
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default FilterButton;
|
|
@ -1,20 +0,0 @@
|
|||||||
.button-label {
|
|
||||||
text-align: center;
|
|
||||||
/* color: #85CE73; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-container {
|
|
||||||
align-self: stretch;
|
|
||||||
padding-left: 12px;
|
|
||||||
padding-right: 12px;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
border-radius: 6px;
|
|
||||||
border: 1px #58874d solid;
|
|
||||||
color: #85CE73;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-container:hover {
|
|
||||||
background-color: #58874d;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
0
src/components/Button/WarningButton/index.tsx
Executable file → Normal file
0
src/components/Button/WarningButton/index.tsx
Executable file → Normal file
0
src/components/Button/WarningButton/style.css
Executable file → Normal file
0
src/components/Button/WarningButton/style.css
Executable file → Normal file
@ -1,47 +0,0 @@
|
|||||||
import { JSXInternal } from "node_modules/preact/src/jsx";
|
|
||||||
import { LocationInfo } from "../../../domains";
|
|
||||||
|
|
||||||
interface ComponentProps {
|
|
||||||
onCardClick: (id: Number) => void,
|
|
||||||
data: LocationInfo,
|
|
||||||
containerClass?: string,
|
|
||||||
containerStyle?: JSXInternal.CSSProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
const LocationCard = (props: ComponentProps) => (
|
|
||||||
<div className={props.containerClass} style={props.containerStyle}>
|
|
||||||
<a onClick={() => props.onCardClick(props.data.id)}>
|
|
||||||
<div className={'border-secondary recently-img-container'}>
|
|
||||||
<img alt={props.data.name} src={props.data.thumbnail ? props.data.thumbnail : ''} loading="lazy" style={{ width: '100%', height: '100%' }} />
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<div className={"border-primary pb-2 location-container text-sm mb-2 mt-2"}>
|
|
||||||
<p className={'location-title'}>{props.data.name}</p>
|
|
||||||
<p className={'text-xs mt-1'}>{props.data.regency_name}, {props.data.province_name}</p>
|
|
||||||
</div>
|
|
||||||
{props.data.critic_count !== 0 &&
|
|
||||||
<div className={"flex flex-row items-center mb-3"}>
|
|
||||||
<div className={'mr-3 users-score-bar'}>
|
|
||||||
<p className={'text-sm text-center'}>{props.data.critic_score}</p>
|
|
||||||
<div style={{ height: 4, width: 30, backgroundColor: "#72767d" }}>
|
|
||||||
<div style={{ height: 4, width: `${props.data.critic_score}%`, backgroundColor: 'green' }} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p className={"users-score"}>critic score ({props.data.critic_count})</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{props.data.user_score !== 0 &&
|
|
||||||
<div className={"flex flex-row items-center"}>
|
|
||||||
<div className={'mr-3 users-score-bar'}>
|
|
||||||
<p className={'text-sm text-center'}>{props.data.user_score}</p>
|
|
||||||
<div style={{ height: 4, width: 30, backgroundColor: "#72767d" }}>
|
|
||||||
<div style={{ height: 4, width: ` ${props.data.user_score}%`, backgroundColor: 'green' }} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p className={'users-score'}>user score ({props.data.user_count})</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default LocationCard;
|
|
0
src/components/CustomInterweave/index.tsx
Executable file → Normal file
0
src/components/CustomInterweave/index.tsx
Executable file → Normal file
0
src/components/DropdownInput/index.tsx
Executable file → Normal file
0
src/components/DropdownInput/index.tsx
Executable file → Normal file
0
src/components/DropdownInput/style.css
Executable file → Normal file
0
src/components/DropdownInput/style.css
Executable file → Normal file
0
src/components/Footer/index.tsx
Executable file → Normal file
0
src/components/Footer/index.tsx
Executable file → Normal file
0
src/components/Footer/style.css
Executable file → Normal file
0
src/components/Footer/style.css
Executable file → Normal file
6
src/components/Header/index.tsx
Executable file → Normal file
6
src/components/Header/index.tsx
Executable file → Normal file
@ -8,7 +8,6 @@ import './style.css';
|
|||||||
import { logoutService } from "../../services";
|
import { logoutService } from "../../services";
|
||||||
import { getSearchLocationService } from "../../services/locations";
|
import { getSearchLocationService } from "../../services/locations";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { ReactSelectData } from "src/types/common";
|
|
||||||
|
|
||||||
|
|
||||||
function Header() {
|
function Header() {
|
||||||
@ -41,8 +40,7 @@ function Header() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSelectedSearchOption = (v: ReactSelectData | unknown) => {
|
const onSelectedSearchOption = (val: any) => {
|
||||||
const val = v as ReactSelectData
|
|
||||||
navigate(`/location/${val.value}`)
|
navigate(`/location/${val.value}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +149,7 @@ function Header() {
|
|||||||
// color: "white"
|
// color: "white"
|
||||||
// })
|
// })
|
||||||
}}
|
}}
|
||||||
onChange={(v: ReactSelectData | unknown, _) => onSelectedSearchOption(v)}
|
onChange={onSelectedSearchOption}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
<button onClick={onDropdown} className={`dropdown-menu bg-secondary ${dropdown ? 'ml-auto' : ''}`} style={{ padding: 5, borderRadius: 10 }}>
|
<button onClick={onDropdown} className={`dropdown-menu bg-secondary ${dropdown ? 'ml-auto' : ''}`} style={{ padding: 5, borderRadius: 10 }}>
|
||||||
|
0
src/components/Header/style.css
Executable file → Normal file
0
src/components/Header/style.css
Executable file → Normal file
@ -1,24 +0,0 @@
|
|||||||
import { capitalize } from "../../../types/common"
|
|
||||||
|
|
||||||
interface ComponentProps {
|
|
||||||
value: string,
|
|
||||||
isSelected?: boolean
|
|
||||||
onChange: () => void,
|
|
||||||
inputName: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const CheckboxInput = (props: ComponentProps) => (
|
|
||||||
<div style="align-self: stretch; justify-content: flex-start; align-items: center; gap: 12px; display: inline-flex">
|
|
||||||
<input checked={props.isSelected}
|
|
||||||
type={"checkbox"}
|
|
||||||
style={{ width: 16, height: 16 }}
|
|
||||||
className={"input-checkbox"}
|
|
||||||
value={props.value}
|
|
||||||
name={props.inputName}
|
|
||||||
onChange={props.onChange}
|
|
||||||
/>
|
|
||||||
<div style="color: white; font-size: 14px; line-height: 21px; letter-spacing: 0.56px; word-wrap: break-word">{capitalize(props.value)}</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default CheckboxInput
|
|
0
src/components/Loading/Spinner/index.tsx
Executable file → Normal file
0
src/components/Loading/Spinner/index.tsx
Executable file → Normal file
0
src/components/Loading/Spinner/style.css
Executable file → Normal file
0
src/components/Loading/Spinner/style.css
Executable file → Normal file
0
src/components/RefOutsideClick/index.tsx
Executable file → Normal file
0
src/components/RefOutsideClick/index.tsx
Executable file → Normal file
0
src/components/Separator/Default/index.tsx
Executable file → Normal file
0
src/components/Separator/Default/index.tsx
Executable file → Normal file
0
src/components/Separator/NavigationSeparator/index.tsx
Executable file → Normal file
0
src/components/Separator/NavigationSeparator/index.tsx
Executable file → Normal file
0
src/components/Separator/NavigationSeparator/style.css
Executable file → Normal file
0
src/components/Separator/NavigationSeparator/style.css
Executable file → Normal file
0
src/components/Separator/TitleSeparator/index.tsx
Executable file → Normal file
0
src/components/Separator/TitleSeparator/index.tsx
Executable file → Normal file
0
src/components/Separator/WithAnchor/index.tsx
Executable file → Normal file
0
src/components/Separator/WithAnchor/index.tsx
Executable file → Normal file
0
src/components/Separator/WithAnchor/style.css
Executable file → Normal file
0
src/components/Separator/WithAnchor/style.css
Executable file → Normal file
12
src/components/index.ts
Executable file → Normal file
12
src/components/index.ts
Executable file → Normal file
@ -15,12 +15,6 @@ import DropdownInput from "./DropdownInput";
|
|||||||
|
|
||||||
import SpinnerLoading from "./Loading/Spinner";
|
import SpinnerLoading from "./Loading/Spinner";
|
||||||
|
|
||||||
import FilterButton from "./Button/FilterButton";
|
|
||||||
|
|
||||||
import LocationCard from "./Card/LocationCard";
|
|
||||||
|
|
||||||
import CheckboxInput from "./Input/CheckboxInput";
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Header,
|
Header,
|
||||||
WarningButton,
|
WarningButton,
|
||||||
@ -36,11 +30,5 @@ export {
|
|||||||
CustomInterweave,
|
CustomInterweave,
|
||||||
DropdownInput,
|
DropdownInput,
|
||||||
|
|
||||||
CheckboxInput,
|
|
||||||
|
|
||||||
SpinnerLoading,
|
SpinnerLoading,
|
||||||
|
|
||||||
LocationCard,
|
|
||||||
|
|
||||||
FilterButton,
|
|
||||||
}
|
}
|
0
src/constants/actions.ts
Executable file → Normal file
0
src/constants/actions.ts
Executable file → Normal file
0
src/constants/api.ts
Executable file → Normal file
0
src/constants/api.ts
Executable file → Normal file
0
src/constants/default.ts
Executable file → Normal file
0
src/constants/default.ts
Executable file → Normal file
0
src/datas/critics_users_best_pick.json
Executable file → Normal file
0
src/datas/critics_users_best_pick.json
Executable file → Normal file
0
src/datas/home.json
Executable file → Normal file
0
src/datas/home.json
Executable file → Normal file
0
src/datas/popular.json
Executable file → Normal file
0
src/datas/popular.json
Executable file → Normal file
0
src/datas/popular_user_reviews.json
Executable file → Normal file
0
src/datas/popular_user_reviews.json
Executable file → Normal file
0
src/datas/recent_news_event.json
Executable file → Normal file
0
src/datas/recent_news_event.json
Executable file → Normal file
0
src/domains/LocationInfo.ts
Executable file → Normal file
0
src/domains/LocationInfo.ts
Executable file → Normal file
0
src/domains/NewsEvent.ts
Executable file → Normal file
0
src/domains/NewsEvent.ts
Executable file → Normal file
0
src/domains/Province.ts
Executable file → Normal file
0
src/domains/Province.ts
Executable file → Normal file
0
src/domains/Regency.ts
Executable file → Normal file
0
src/domains/Regency.ts
Executable file → Normal file
0
src/domains/Region.ts
Executable file → Normal file
0
src/domains/Region.ts
Executable file → Normal file
0
src/domains/User.ts
Executable file → Normal file
0
src/domains/User.ts
Executable file → Normal file
0
src/domains/index.ts
Executable file → Normal file
0
src/domains/index.ts
Executable file → Normal file
0
src/features/auth/authSlice/authSlice.ts
Executable file → Normal file
0
src/features/auth/authSlice/authSlice.ts
Executable file → Normal file
0
src/features/index.ts
Executable file → Normal file
0
src/features/index.ts
Executable file → Normal file
0
src/fonts/Lato-Black.ttf
Executable file → Normal file
0
src/fonts/Lato-Black.ttf
Executable file → Normal file
0
src/fonts/Lato-BlackItalic.ttf
Executable file → Normal file
0
src/fonts/Lato-BlackItalic.ttf
Executable file → Normal file
0
src/fonts/Lato-Bold.ttf
Executable file → Normal file
0
src/fonts/Lato-Bold.ttf
Executable file → Normal file
0
src/fonts/Lato-BoldItalic.ttf
Executable file → Normal file
0
src/fonts/Lato-BoldItalic.ttf
Executable file → Normal file
0
src/fonts/Lato-Italic.ttf
Executable file → Normal file
0
src/fonts/Lato-Italic.ttf
Executable file → Normal file
0
src/fonts/Lato-Light.ttf
Executable file → Normal file
0
src/fonts/Lato-Light.ttf
Executable file → Normal file
0
src/fonts/Lato-LightItalic.ttf
Executable file → Normal file
0
src/fonts/Lato-LightItalic.ttf
Executable file → Normal file
0
src/fonts/Lato-Regular.ttf
Executable file → Normal file
0
src/fonts/Lato-Regular.ttf
Executable file → Normal file
0
src/fonts/Lato-Thin.ttf
Executable file → Normal file
0
src/fonts/Lato-Thin.ttf
Executable file → Normal file
0
src/fonts/Lato-ThinItalic.ttf
Executable file → Normal file
0
src/fonts/Lato-ThinItalic.ttf
Executable file → Normal file
0
src/index.css
Executable file → Normal file
0
src/index.css
Executable file → Normal file
0
src/lato.css
Executable file → Normal file
0
src/lato.css
Executable file → Normal file
0
src/layouts/Default/Default.tsx
Executable file → Normal file
0
src/layouts/Default/Default.tsx
Executable file → Normal file
0
src/layouts/index.ts
Executable file → Normal file
0
src/layouts/index.ts
Executable file → Normal file
0
src/main.tsx
Executable file → Normal file
0
src/main.tsx
Executable file → Normal file
0
src/pages/AddLocation/index.tsx
Executable file → Normal file
0
src/pages/AddLocation/index.tsx
Executable file → Normal file
0
src/pages/AddLocation/style.css
Executable file → Normal file
0
src/pages/AddLocation/style.css
Executable file → Normal file
0
src/pages/AddLocation/types.ts
Executable file → Normal file
0
src/pages/AddLocation/types.ts
Executable file → Normal file
7
src/pages/BestLocations/index.tsx
Executable file → Normal file
7
src/pages/BestLocations/index.tsx
Executable file → Normal file
@ -2,8 +2,8 @@ import { TargetedEvent } from "preact/compat";
|
|||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { getListTopLocationsService } from "../../services";
|
import { getListTopLocationsService } from "../../services";
|
||||||
import { DefaultSeparator } from "../../components";
|
import { DefaultSeparator } from "../../components";
|
||||||
|
import { NullValueRes } from "../../types/common";
|
||||||
import './style.css';
|
import './style.css';
|
||||||
import { useClick, useFloating, useInteractions } from "@floating-ui/react";
|
|
||||||
|
|
||||||
interface TopLocation {
|
interface TopLocation {
|
||||||
row_number: Number,
|
row_number: Number,
|
||||||
@ -47,7 +47,7 @@ const MIN_REVIEWS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
function BestLocation() {
|
function BestLocation() {
|
||||||
const [page, _setPage] = useState<number>(1);
|
const [page, setPage] = useState<number>(1);
|
||||||
const [topLocations, setTopLocations] = useState<Array<TopLocation>>([])
|
const [topLocations, setTopLocations] = useState<Array<TopLocation>>([])
|
||||||
const [pageState, setPageState] = useState({
|
const [pageState, setPageState] = useState({
|
||||||
filterScoreType: 'all',
|
filterScoreType: 'all',
|
||||||
@ -84,7 +84,9 @@ function BestLocation() {
|
|||||||
getTopLocations()
|
getTopLocations()
|
||||||
}, [pageState])
|
}, [pageState])
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<div className={'content main-content mt-3'}>
|
<div className={'content main-content mt-3'}>
|
||||||
<section name={"Top locations header"}>
|
<section name={"Top locations header"}>
|
||||||
<h1 className={'text-3xl mb-5 font-bold'}>Top Locations</h1>
|
<h1 className={'text-3xl mb-5 font-bold'}>Top Locations</h1>
|
||||||
@ -196,6 +198,7 @@ function BestLocation() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
0
src/pages/BestLocations/style.css
Executable file → Normal file
0
src/pages/BestLocations/style.css
Executable file → Normal file
302
src/pages/Discovery/index.tsx
Executable file → Normal file
302
src/pages/Discovery/index.tsx
Executable file → Normal file
@ -1,304 +1,8 @@
|
|||||||
import { useEffect, useState } from "preact/hooks";
|
|
||||||
import { CheckboxInput, DefaultSeparator, FilterButton, LocationCard } from "../../components";
|
|
||||||
import { useClick, useFloating, useInteractions, Side, AlignedPlacement, flip, shift, useDismiss } from "@floating-ui/react";
|
|
||||||
import { JSXInternal } from "node_modules/preact/src/jsx";
|
|
||||||
import { getListRecentLocationsRatingsService, getRegenciesService, } from "../../services";
|
|
||||||
import { LocationInfo, Regency } from "../../domains";
|
|
||||||
import { ChangeEvent, TargetedEvent } from "preact/compat";
|
|
||||||
import { LocationType, capitalize } from "../../types/common";
|
|
||||||
import './style.css';
|
|
||||||
import { enumKeys } from "../../utils";
|
|
||||||
import { getSearchLocationService } from "../../services/locations";
|
|
||||||
|
|
||||||
|
|
||||||
interface floatFilterArgs<T> {
|
|
||||||
isOpen: boolean,
|
|
||||||
placement: Side | AlignedPlacement,
|
|
||||||
outsidePress?: () => void,
|
|
||||||
onChecked: (e: TargetedEvent<HTMLInputElement, Event>, id: number) => void,
|
|
||||||
onClearFilter?: () => void,
|
|
||||||
onInputChange: (val: string) => void,
|
|
||||||
listData?: T[];
|
|
||||||
}
|
|
||||||
|
|
||||||
function FloatFilter(props: floatFilterArgs<Regency & { isSelected?: boolean }>) {
|
|
||||||
const [floatState, setFloatState] = useState({
|
|
||||||
searchValue: "",
|
|
||||||
})
|
|
||||||
|
|
||||||
const { refs, floatingStyles, context } = useFloating({
|
|
||||||
placement: props.placement,
|
|
||||||
open: props.isOpen,
|
|
||||||
middleware: [
|
|
||||||
flip({ fallbackAxisSideDirection: "end" }),
|
|
||||||
shift()
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const click = useClick(context);
|
|
||||||
const dismiss = useDismiss(context, {
|
|
||||||
outsidePress: () => {
|
|
||||||
props.outsidePress && props.outsidePress()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const { getReferenceProps, getFloatingProps } = useInteractions([
|
|
||||||
click,
|
|
||||||
dismiss
|
|
||||||
]);
|
|
||||||
|
|
||||||
const style: JSXInternal.CSSProperties = {
|
|
||||||
...floatingStyles,
|
|
||||||
top: 210,
|
|
||||||
left: 'none',
|
|
||||||
marginLeft: 150,
|
|
||||||
width: 355,
|
|
||||||
zIndex: 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
function onInputChange(e: ChangeEvent<HTMLInputElement>): void {
|
|
||||||
const input = e.target as HTMLInputElement;
|
|
||||||
setFloatState({ searchValue: input.value.toLowerCase() })
|
|
||||||
props.onInputChange(input.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.isOpen) return (
|
|
||||||
<div
|
|
||||||
ref={refs.setFloating} {...getReferenceProps()}
|
|
||||||
style={style}
|
|
||||||
className={'bg-secondary float-filter-scroll'}
|
|
||||||
{...getFloatingProps()}
|
|
||||||
>
|
|
||||||
<div style={{ padding: 10 }}>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={floatState.searchValue}
|
|
||||||
onChange={onInputChange}
|
|
||||||
placeholder={"Search ..."}
|
|
||||||
className={'bg-quartenary text-sm input-text mb-3'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ overflowY: 'scroll', height: 315, padding: 10 }} className={'float-filter-scroll'}>
|
|
||||||
{props.listData ?
|
|
||||||
<ul>
|
|
||||||
{props.listData.map(x => (
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 5 }}>
|
|
||||||
<input
|
|
||||||
type={"checkbox"}
|
|
||||||
id={x.id.toString()}
|
|
||||||
checked={x.isSelected}
|
|
||||||
value={x.id}
|
|
||||||
name={x.regency_name}
|
|
||||||
className={'input-checkbox'}
|
|
||||||
style={{ marginRight: 10, width: 18, height: 18 }}
|
|
||||||
onChange={(e) => props.onChecked(e, x.id)}
|
|
||||||
/>
|
|
||||||
<label htmlFor={x.id.toString()}>{x.regency_name}</label>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
: null}
|
|
||||||
</div>
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-around', paddingBottom: 10, paddingTop: 10 }}>
|
|
||||||
<button onClick={props.onClearFilter}>Clear</button>
|
|
||||||
<button onClick={props.outsidePress} >Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function Discovery() {
|
function Discovery() {
|
||||||
|
|
||||||
interface DiscoveryState {
|
|
||||||
filterQ: string,
|
|
||||||
regencies: any[],
|
|
||||||
searchRegencies: any[],
|
|
||||||
locations: LocationInfo[],
|
|
||||||
locationType: Array<{value: string, isSelected?: boolean}>
|
|
||||||
}
|
|
||||||
|
|
||||||
const [data, setData] = useState<DiscoveryState>({
|
|
||||||
filterQ: '',
|
|
||||||
regencies: [],
|
|
||||||
searchRegencies: [],
|
|
||||||
locations: [],
|
|
||||||
locationType: []
|
|
||||||
});
|
|
||||||
const [isFloatFilterOpen, setFloatFilterOpen] = useState(false)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getLocationType()
|
|
||||||
getRecentLocations()
|
|
||||||
getRegion()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
async function getRegion() {
|
|
||||||
try {
|
|
||||||
const res = await getRegenciesService();
|
|
||||||
setData((prevState) => ({ ...prevState, regencies: res.data, searchRegencies: res.data }))
|
|
||||||
} catch (err) {
|
|
||||||
alert(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getRecentLocations() {
|
|
||||||
try {
|
|
||||||
const locations = await getListRecentLocationsRatingsService(15)
|
|
||||||
setData((prevState) => ({ ...prevState, locations: locations.data.locations }))
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCheckedRegencyFilter(_val: any, id: number) {
|
|
||||||
// const value = val as HTMLInputElement;
|
|
||||||
const dataRegencies = data.searchRegencies as (Regency & { isSelected?: boolean })[];
|
|
||||||
const regencyIdx = dataRegencies.findIndex(x => x.id == id);
|
|
||||||
dataRegencies[regencyIdx].isSelected = !dataRegencies[regencyIdx].isSelected
|
|
||||||
setData({
|
|
||||||
...data,
|
|
||||||
regencies: dataRegencies,
|
|
||||||
searchRegencies: dataRegencies
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function onClearFilter() {
|
|
||||||
const dataRegencies = data.searchRegencies as (Regency & { isSelected?: boolean })[];
|
|
||||||
const regencies = dataRegencies.map(x => ({ ...x, isSelected: false }))
|
|
||||||
|
|
||||||
setData({
|
|
||||||
...data,
|
|
||||||
regencies: regencies,
|
|
||||||
searchRegencies: regencies
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function onInputChange(search: string) {
|
|
||||||
const dataRegencies = data.regencies as (Regency & { isSelected?: boolean })[];
|
|
||||||
// console.log(dataRegencies.filter(x => x.regency_name.toLowerCase().includes(search)))
|
|
||||||
setData({
|
|
||||||
...data,
|
|
||||||
searchRegencies: dataRegencies.filter(x => x.regency_name.toLowerCase().includes(search))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function onClickedTypeLocations(idx: number) {
|
|
||||||
const locType = data.locationType
|
|
||||||
locType[idx].isSelected = !locType[idx].isSelected
|
|
||||||
setData({
|
|
||||||
...data,
|
|
||||||
locationType: locType
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function onApplyFilter() {
|
|
||||||
const dataRegencies = data.regencies as (Regency & { isSelected?: boolean})[];
|
|
||||||
const selectedRegencies = dataRegencies.filter(x => x.isSelected)
|
|
||||||
const selectedLocType = data.locationType.filter(x => x.isSelected)
|
|
||||||
let regenciesQ = "";
|
|
||||||
let locTypeQ = ""
|
|
||||||
|
|
||||||
if(selectedRegencies.length > 0) {
|
|
||||||
regenciesQ = selectedRegencies.map(x => x.id).join(" OR ").replace(/\s+/g, '%20')
|
|
||||||
|
|
||||||
}
|
|
||||||
if(selectedLocType.length > 0) {
|
|
||||||
const onJoin = selectedRegencies.length > 0 ? " AND " : " OR "
|
|
||||||
locTypeQ = selectedLocType.map(x => x.value).join(onJoin).replace(/\s+/g, '%20')
|
|
||||||
|
|
||||||
if(selectedRegencies.length > 0) locTypeQ = `%20AND%20${locTypeQ}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchQ = `${regenciesQ}${locTypeQ}`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLocationType() {
|
|
||||||
const type: Array<{value: string, isSelected?: boolean}> = []
|
|
||||||
for (const lt of enumKeys(LocationType)) {
|
|
||||||
type.push({value: LocationType[lt]});
|
|
||||||
}
|
|
||||||
|
|
||||||
setData((prevState) => ({ ...prevState, locationType: type }))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="content main-content mt-3">
|
<>
|
||||||
<section name="header">
|
<h1>Discovery</h1>
|
||||||
<h1 className={'text-3xl mb-5 font-bold'}>Discovery</h1>
|
</>
|
||||||
<DefaultSeparator />
|
|
||||||
</section>
|
|
||||||
<section name="content">
|
|
||||||
<div style="padding-bottom: 24px; justify-content: flex-start; align-items: flex-start; display: inline-flex">
|
|
||||||
{/* FILTER */}
|
|
||||||
<section name="discovery filter">
|
|
||||||
<div className="filter-container">
|
|
||||||
<div style="align-self: stretch; padding-left: 12px; padding-right: 12px; padding-top: 8px; padding-bottom: 8px; background: #36383B; border-radius: 8px; justify-content: flex-start; align-items: center; gap: 10px; display: inline-flex">
|
|
||||||
<div style="flex: 1 1 0; color: white; font-size: 16px; line-height: 24px; letter-spacing: 0.64px; word-wrap: break-word">Filter</div>
|
|
||||||
</div>
|
|
||||||
<div style="align-self: stretch; padding-left: 12px; padding-right: 12px; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 16px; display: flex">
|
|
||||||
<div style="align-self: stretch; color: white; font-size: 14px; font-weight: 700; line-height: 21px; letter-spacing: 0.56px; word-wrap: break-word">Kota / Kabupaten </div>
|
|
||||||
<div style="align-self: stretch; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 12px; display: flex">
|
|
||||||
{data.regencies.filter(x => x.isSelected).map(x => (
|
|
||||||
<div style="align-self: stretch; justify-content: flex-start; align-items: center; gap: 12px; display: inline-flex">
|
|
||||||
<div style="flex: 1 1 0; color: white; font-size: 14px; font-family: Poppins; font-weight: 500; line-height: 21px; letter-spacing: 0.56px; word-wrap: break-word">{x.regency_name}</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div style="align-self: stretch; padding: 8px; border-radius: 6px; justify-content: center; align-items: center; gap: 4px; display: inline-flex">
|
|
||||||
<button onClick={() => setFloatFilterOpen(!isFloatFilterOpen)} style="text-align: center; color: #85CE73; font-size: 14px; font-weight: 600; line-height: 21px; letter-spacing: 0.10px; word-wrap: break-word">Lihat Selengkapnya</button>
|
|
||||||
<FloatFilter
|
|
||||||
isOpen={isFloatFilterOpen}
|
|
||||||
placement="right"
|
|
||||||
listData={data.searchRegencies}
|
|
||||||
outsidePress={() => setFloatFilterOpen(false)}
|
|
||||||
onClearFilter={onClearFilter}
|
|
||||||
onChecked={onCheckedRegencyFilter}
|
|
||||||
onInputChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="align-self: stretch; height: 2px; background: #36383B; border-radius: 2px"></div>
|
|
||||||
<div style="align-self: stretch; height: 190px; padding-left: 12px; padding-right: 12px; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 16px; display: flex">
|
|
||||||
<div style="align-self: stretch; color: white; font-size: 14px; font-family: Poppins; font-weight: 700; line-height: 21px; letter-spacing: 0.56px; word-wrap: break-word">Tipe</div>
|
|
||||||
<div style="align-self: stretch; height: 153px; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 12px; display: flex">
|
|
||||||
{data.locationType.map((x, i) => (
|
|
||||||
<CheckboxInput
|
|
||||||
inputName="location_type"
|
|
||||||
onChange={() => onClickedTypeLocations(i)}
|
|
||||||
value={x.value}
|
|
||||||
isSelected={x.isSelected}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="align-self: stretch; height: 2px; background: #36383B; border-radius: 2px"></div>
|
|
||||||
<FilterButton onClick={onApplyFilter} label="Apply" />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{/* FILTER END */}
|
|
||||||
<div>
|
|
||||||
{data.locations.map(x => (
|
|
||||||
<LocationCard
|
|
||||||
containerClass='card-list-container'
|
|
||||||
onCardClick={(id) => console.log(id)}
|
|
||||||
data={x}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
.float-filter-scroll::-webkit-scrollbar-track {
|
|
||||||
background: #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Customizing the scrollbar handle */
|
|
||||||
.float-filter-scroll::-webkit-scrollbar-thumb {
|
|
||||||
background: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
.float-filter-scroll::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Customizing the scrollbar width */
|
|
||||||
.float-filter-scroll::-webkit-scrollbar {
|
|
||||||
width: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For Firefox */
|
|
||||||
.float-filter-scroll {
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: #a8adb3 #2f3136;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-list-container {
|
|
||||||
padding: 10px 1% 15px;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 0 15px;
|
|
||||||
vertical-align: top;
|
|
||||||
width: 20%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-container {
|
|
||||||
width: 195px;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content:
|
|
||||||
flex-start;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 24px;
|
|
||||||
display: inline-flex;
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1300px) {
|
|
||||||
.card-list-container {
|
|
||||||
width: 24.3%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1135px) {
|
|
||||||
.card-list-container {
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1100px) {
|
|
||||||
.card-list-container {
|
|
||||||
width: 33%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 920px) {
|
|
||||||
.card-list-container {
|
|
||||||
width: 33%;
|
|
||||||
}
|
|
||||||
.filter-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 625px) {
|
|
||||||
.card-list-container {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@media screen and (max-width: 425px) {
|
|
||||||
.news-card {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.news-link {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
line-height: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.recently-img-container {
|
|
||||||
height: 120px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.critics-users-image {
|
|
||||||
height: 60px;
|
|
||||||
width: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.location-province {
|
|
||||||
font-size: 10px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trending-image-container {
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 7px;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-location-container .location-title {
|
|
||||||
font-size: 0.685rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
} */
|
|
77
src/pages/Home/index.tsx
Executable file → Normal file
77
src/pages/Home/index.tsx
Executable file → Normal file
@ -1,4 +1,4 @@
|
|||||||
import { LocationCard, SeparatorWithAnchor } from '../../components';
|
import { SeparatorWithAnchor } from '../../components';
|
||||||
import news from '../../datas/recent_news_event.json';
|
import news from '../../datas/recent_news_event.json';
|
||||||
import popular from '../../datas/popular.json';
|
import popular from '../../datas/popular.json';
|
||||||
import popular_user_review from '../../datas/popular_user_reviews.json';
|
import popular_user_review from '../../datas/popular_user_reviews.json';
|
||||||
@ -28,7 +28,7 @@ function Home() {
|
|||||||
async function getRecentLocations() {
|
async function getRecentLocations() {
|
||||||
try {
|
try {
|
||||||
const locations = await getListRecentLocationsRatingsService(12)
|
const locations = await getListRecentLocationsRatingsService(12)
|
||||||
setRecentLocations(locations.data.locations)
|
setRecentLocations(locations.data)
|
||||||
// setIsLoading(false)
|
// setIsLoading(false)
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@ -63,50 +63,46 @@ function Home() {
|
|||||||
getUsersBestLocations()
|
getUsersBestLocations()
|
||||||
},[])
|
},[])
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<div className="content main-content mt-3">
|
<div className="content main-content mt-3">
|
||||||
|
|
||||||
{/* RECENTLY ADDED SECTION */}
|
{/* RECENTLY ADDED SECTION */}
|
||||||
<section about={"Recently added places"} className={'mt-3'}>
|
<section about={"Recently added places"} className={'mt-3'}>
|
||||||
<SeparatorWithAnchor pageLink='#' pageName='recently added' secondLink='#' />
|
<SeparatorWithAnchor pageLink='#' pageName='recently added' secondLink='#' />
|
||||||
{recentLocations.map((x) => (
|
{recentLocations.map((x) => (
|
||||||
<LocationCard
|
<div className={"recently-added-section-card"}>
|
||||||
containerClass='recently-added-section-card'
|
<a onClick={() => onNavigateToDetail(x.id)}>
|
||||||
onCardClick={onNavigateToDetail}
|
<div className={'border-secondary recently-img-container'}>
|
||||||
data={x}
|
<img alt={x.name} src={x.thumbnail ? x.thumbnail : ''} loading="lazy" style={{ width: '100%', height: '100%' }} />
|
||||||
/>
|
</div>
|
||||||
// <div className={"recently-added-section-card"}>
|
</a>
|
||||||
// <a onClick={() => onNavigateToDetail(x.id)}>
|
<div className={"border-primary pb-2 location-container text-sm mb-2 mt-2"}>
|
||||||
// <div className={'border-secondary recently-img-container'}>
|
<p className={'location-title'}>{x.name}</p>
|
||||||
// <img alt={x.name} src={x.thumbnail ? x.thumbnail : ''} loading="lazy" style={{ width: '100%', height: '100%' }} />
|
<p className={'text-xs mt-1'}>{x.regency_name}, {x.province_name}</p>
|
||||||
// </div>
|
</div>
|
||||||
// </a>
|
{ x.critic_count !== 0 &&
|
||||||
// <div className={"border-primary pb-2 location-container text-sm mb-2 mt-2"}>
|
<div className={"flex flex-row items-center mb-3"}>
|
||||||
// <p className={'location-title'}>{x.name}</p>
|
<div className={'mr-3 users-score-bar'}>
|
||||||
// <p className={'text-xs mt-1'}>{x.regency_name}, {x.province_name}</p>
|
<p className={'text-sm text-center'}>{x.critic_score}</p>
|
||||||
// </div>
|
<div style={{ height: 4, width: 30, backgroundColor: "#72767d"}}>
|
||||||
// {x.critic_count !== 0 &&
|
<div style={{ height: 4, width: `${x.critic_score}%`, backgroundColor: 'green' }} />
|
||||||
// <div className={"flex flex-row items-center mb-3"}>
|
</div>
|
||||||
// <div className={'mr-3 users-score-bar'}>
|
</div>
|
||||||
// <p className={'text-sm text-center'}>{x.critic_score}</p>
|
<p className={"users-score"}>critic score ({x.critic_count})</p>
|
||||||
// <div style={{ height: 4, width: 30, backgroundColor: "#72767d" }}>
|
</div>
|
||||||
// <div style={{ height: 4, width: `${x.critic_score}%`, backgroundColor: 'green' }} />
|
}
|
||||||
// </div>
|
{ x.user_score !== 0 &&
|
||||||
// </div>
|
<div className={"flex flex-row items-center"}>
|
||||||
// <p className={"users-score"}>critic score ({x.critic_count})</p>
|
<div className={'mr-3 users-score-bar'}>
|
||||||
// </div>
|
<p className={'text-sm text-center'}>{x.user_score}</p>
|
||||||
// }
|
<div style={{ height: 4, width: 30, backgroundColor: "#72767d" }}>
|
||||||
// {x.user_score !== 0 &&
|
<div style={{ height: 4, width: ` ${x.user_score}%`, backgroundColor: 'green' }} />
|
||||||
// <div className={"flex flex-row items-center"}>
|
</div>
|
||||||
// <div className={'mr-3 users-score-bar'}>
|
</div>
|
||||||
// <p className={'text-sm text-center'}>{x.user_score}</p>
|
<p className={'users-score'}>user score ({x.user_count})</p>
|
||||||
// <div style={{ height: 4, width: 30, backgroundColor: "#72767d" }}>
|
</div>
|
||||||
// <div style={{ height: 4, width: ` ${x.user_score}%`, backgroundColor: 'green' }} />
|
}
|
||||||
// </div>
|
</div>
|
||||||
// </div>
|
|
||||||
// <p className={'users-score'}>user score ({x.user_count})</p>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// </div>
|
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
{/* END RECENTLY ADDED SECTION */}
|
{/* END RECENTLY ADDED SECTION */}
|
||||||
@ -239,6 +235,7 @@ function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
0
src/pages/Home/style.css
Executable file → Normal file
0
src/pages/Home/style.css
Executable file → Normal file
0
src/pages/LocationDetail/index.css
Executable file → Normal file
0
src/pages/LocationDetail/index.css
Executable file → Normal file
106
src/pages/LocationDetail/index.tsx
Executable file → Normal file
106
src/pages/LocationDetail/index.tsx
Executable file → Normal file
@ -193,12 +193,13 @@ function LocationDetail() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (updatePage || id) {
|
if(updatePage) {
|
||||||
getLocationDetail()
|
getLocationDetail()
|
||||||
}
|
}
|
||||||
}, [updatePage, id])
|
}, [updatePage, id])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<div className={'content main-content mt-3'}>
|
<div className={'content main-content mt-3'}>
|
||||||
<section name={"HEADER LINK"}>
|
<section name={"HEADER LINK"}>
|
||||||
<div className={'header-link text-tertiary'}>
|
<div className={'header-link text-tertiary'}>
|
||||||
@ -469,7 +470,10 @@ function LocationDetail() {
|
|||||||
</>
|
</>
|
||||||
|
|
||||||
:
|
:
|
||||||
|
<>
|
||||||
<span className={'text-sm italic'}>No Critics review to display</span>
|
<span className={'text-sm italic'}>No Critics review to display</span>
|
||||||
|
</>
|
||||||
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -536,12 +540,111 @@ function LocationDetail() {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{/* <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="#">
|
||||||
|
<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={''} 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 className={'mb-5'}>
|
<div className={'mb-5'}>
|
||||||
CONTRUBITION
|
CONTRUBITION
|
||||||
<DefaultSeparator />
|
<DefaultSeparator />
|
||||||
anoeantoeh aoenthaoe aoenth aot
|
anoeantoeh aoenthaoe aoenth aot
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/* {screen.width >= 1024 &&
|
||||||
|
<div className={'bg-secondary'} style={{ display: 'table-cell', position: 'relative', verticalAlign: 'top', width: 330, textAlign: 'left', padding: 15, boxSizing: 'border-box', height: 1080 }}>
|
||||||
|
// ADD USER DISTRIBUTION SOMETHING LIKE THIS
|
||||||
|
// https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_user_rating
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit cumque aliquam doloribus in reiciendis? Laborum, ea assumenda, tempora dolore placeat aspernatur, cumque totam sequi debitis dolor nam eligendi suscipit aliquid?
|
||||||
|
</div>
|
||||||
|
} */}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ clear: 'both' }} />
|
<div style={{ clear: 'both' }} />
|
||||||
</section>
|
</section>
|
||||||
@ -557,6 +660,7 @@ function LocationDetail() {
|
|||||||
slides={locationImages?.images}
|
slides={locationImages?.images}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
src/pages/LocationDetail/types.ts
Executable file → Normal file
0
src/pages/LocationDetail/types.ts
Executable file → Normal file
0
src/pages/Login/index.css
Executable file → Normal file
0
src/pages/Login/index.css
Executable file → Normal file
0
src/pages/Login/index.tsx
Executable file → Normal file
0
src/pages/Login/index.tsx
Executable file → Normal file
0
src/pages/NewsEvent/index.tsx
Executable file → Normal file
0
src/pages/NewsEvent/index.tsx
Executable file → Normal file
0
src/pages/NewsEvent/style.css
Executable file → Normal file
0
src/pages/NewsEvent/style.css
Executable file → Normal file
0
src/pages/NotFound/index.tsx
Executable file → Normal file
0
src/pages/NotFound/index.tsx
Executable file → Normal file
2
src/pages/Stories/index.tsx
Executable file → Normal file
2
src/pages/Stories/index.tsx
Executable file → Normal file
@ -1,6 +1,8 @@
|
|||||||
function Story() {
|
function Story() {
|
||||||
return(
|
return(
|
||||||
|
<>
|
||||||
<h1>Best PLaces</h1>
|
<h1>Best PLaces</h1>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
0
src/pages/Submissions/index.tsx
Executable file → Normal file
0
src/pages/Submissions/index.tsx
Executable file → Normal file
0
src/pages/UserFeed/index.tsx
Executable file → Normal file
0
src/pages/UserFeed/index.tsx
Executable file → Normal file
2
src/pages/UserProfile/index.tsx
Executable file → Normal file
2
src/pages/UserProfile/index.tsx
Executable file → Normal file
@ -188,7 +188,9 @@ function UserProfile() {
|
|||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
:
|
:
|
||||||
|
<>
|
||||||
<span className={'text-sm italic'}>No users review to display</span>
|
<span className={'text-sm italic'}>No users review to display</span>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
0
src/pages/UserProfile/style.css
Executable file → Normal file
0
src/pages/UserProfile/style.css
Executable file → Normal file
0
src/pages/UserSettings/index.tsx
Executable file → Normal file
0
src/pages/UserSettings/index.tsx
Executable file → Normal file
0
src/pages/UserSettings/styles.css
Executable file → Normal file
0
src/pages/UserSettings/styles.css
Executable file → Normal file
0
src/pages/index.tsx
Executable file → Normal file
0
src/pages/index.tsx
Executable file → Normal file
0
src/reducers/index.ts
Executable file → Normal file
0
src/reducers/index.ts
Executable file → Normal file
0
src/routes/ProtectedRoute.tsx
Executable file → Normal file
0
src/routes/ProtectedRoute.tsx
Executable file → Normal file
0
src/routes/index.tsx
Executable file → Normal file
0
src/routes/index.tsx
Executable file → Normal file
0
src/services/auth.ts
Executable file → Normal file
0
src/services/auth.ts
Executable file → Normal file
0
src/services/config.ts
Executable file → Normal file
0
src/services/config.ts
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user