mirror of
https://github.com/task-17-lct/frontend.git
synced 2024-11-22 02:26:34 +03:00
add nearest points
This commit is contained in:
parent
19e22d9298
commit
bf51971cd5
|
@ -8,7 +8,7 @@
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Web site created using create-react-app"
|
content="Russpass MAGNUM OPUS #1"
|
||||||
/>
|
/>
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
export const origin = 'https://0e06-92-100-146-65.ngrok-free.app/'
|
// export const origin = 'https://0e06-92-100-146-65.ngrok-free.app/'
|
||||||
|
export const origin = 'https://dev2.akarpov.ru/'
|
|
@ -1,14 +1,11 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
// export const backend = axios.create({
|
|
||||||
// baseURL: 'https://dev2.akarpov.ru/api/',
|
|
||||||
// timeout: 10000,
|
|
||||||
// headers: {'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjg3Mjk0NTExLCJpYXQiOjE2ODQ3MDI1MTEsImp0aSI6ImUwNGNjZGViMzA0NzQxYTlhYzJhODRhNzc1YWFkZTIxIiwidXNlcl9pZCI6N30.M-F08v6Wit5Bbm668m84JThyDX5yZhzsh3_GFh3nzXM'}
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
// export const BASE_URL = 'https://0e06-92-100-146-65.ngrok-free.app/api/'
|
||||||
|
export const BASE_URL = 'https://dev2.akarpov.ru/api/'
|
||||||
|
|
||||||
export let backend = axios.create({
|
export let backend = axios.create({
|
||||||
baseURL: 'https://0e06-92-100-146-65.ngrok-free.app/api/',
|
baseURL: BASE_URL,
|
||||||
timeout: 100000,
|
timeout: 100000,
|
||||||
headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}
|
headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +13,13 @@ export let backend = axios.create({
|
||||||
|
|
||||||
export const updateBackend = () =>{
|
export const updateBackend = () =>{
|
||||||
backend = axios.create({
|
backend = axios.create({
|
||||||
baseURL: 'https://0e06-92-100-146-65.ngrok-free.app/api/',
|
baseURL: BASE_URL,
|
||||||
timeout: 100000,
|
timeout: 100000,
|
||||||
headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}
|
headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const nonAuthToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjg4OTM2NDQ5LCJpYXQiOjE2ODYzNDQ0NDksImp0aSI6IjY0MzgyNzg3NmMzZTRhN2Q5ODAzYjJjMTM0MzY1MTg3IiwidXNlcl9pZCI6OH0._4AkdCc5XkfROe_9taVtFGV4Rx2HOM1HnV0Byc7NY_o'
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import { useLocation, useParams } from "react-router-dom";
|
||||||
import { backend } from "../../consts";
|
import { backend } from "../../consts";
|
||||||
import { Button } from "../Button";
|
import { Button } from "../Button";
|
||||||
import './style.css'
|
import './style.css'
|
||||||
|
@ -28,12 +29,17 @@ enum category{
|
||||||
|
|
||||||
|
|
||||||
export const EventCard:React.FC<EventCardIE> = (props) =>{
|
export const EventCard:React.FC<EventCardIE> = (props) =>{
|
||||||
const [liked, setLiked] = useState(false)
|
let location = useLocation()
|
||||||
|
|
||||||
|
const [liked, setLiked] = useState(location.pathname == '/favorites'? true:false)
|
||||||
|
|
||||||
const onLiked = ()=>{
|
const onLiked = ()=>{
|
||||||
backend.get('/onboarding/' + props.oid + '/add_to_favorites/')
|
if (localStorage.getItem('token') != null){
|
||||||
setLiked(!liked)
|
backend.get('/onboarding/' + props.oid + '/add_to_favorites/')
|
||||||
|
setLiked(!liked)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
console.log(location)
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div key={props.oid}>
|
<div key={props.oid}>
|
||||||
|
|
239
src/elements/NonAuthSearch/index.tsx
Normal file
239
src/elements/NonAuthSearch/index.tsx
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
import { DatePicker, Checkbox, Select, Radio, Space } from 'antd';
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Button } from '../Button';
|
||||||
|
|
||||||
|
import './style.css'
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import type { RangePickerProps } from 'antd/es/date-picker';
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { BASE_URL, nonAuthToken } from '../../consts';
|
||||||
|
|
||||||
|
type RangeValue = [Dayjs | null, Dayjs | null] | null;
|
||||||
|
|
||||||
|
let backend = axios.create({
|
||||||
|
baseURL: BASE_URL,
|
||||||
|
timeout: 100000,
|
||||||
|
headers: {'Authorization': 'Bearer ' + nonAuthToken}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
export const NonAuthSearch:React.FC<{onSearch?:()=>void}> = (props) =>{
|
||||||
|
|
||||||
|
const { RangePicker } = DatePicker;
|
||||||
|
const [cities, setCities] = useState([])
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if (cities.length == 0){
|
||||||
|
backend.get('/data/cities').then((response)=>setCities(response.data))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const [toolsOpened, setToolsOpened] = useState(false)
|
||||||
|
|
||||||
|
const [city, setCity] = useState('')
|
||||||
|
const [datesValue, setDatesValue] = useState([])
|
||||||
|
const [transport, setTransport] = useState('walk')
|
||||||
|
const [whatToSee, setWhatToSee] = useState<string[]>([])
|
||||||
|
const [whereStay, setWhereStay] = useState<string[]>([])
|
||||||
|
const [whereEat, setWhereEat] = useState<string[]>([])
|
||||||
|
const [stars, setStars] = useState<number[]>([])
|
||||||
|
|
||||||
|
const [withKids, setWithKids] = useState(false)
|
||||||
|
const [withAnimals, setWithAnimals] = useState(false)
|
||||||
|
|
||||||
|
const [dates, setDates] = useState<RangeValue>(null);
|
||||||
|
|
||||||
|
const onWhatToSeeChange = (value:string, checked:boolean) =>{
|
||||||
|
if (checked){
|
||||||
|
setWhatToSee([...whatToSee, value])
|
||||||
|
} else {
|
||||||
|
let newData = whatToSee
|
||||||
|
newData.splice(whatToSee.indexOf(value), 1)
|
||||||
|
setWhatToSee(newData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onStarsChange = (value:number, checked:boolean) =>{
|
||||||
|
if (checked){
|
||||||
|
setStars([...stars, value])
|
||||||
|
} else {
|
||||||
|
let newData = stars
|
||||||
|
newData.splice(stars.indexOf(value), 1)
|
||||||
|
setStars(newData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onWhereStay = (value:string, checked:boolean) =>{
|
||||||
|
if (checked){
|
||||||
|
setWhereStay([...whereStay, value])
|
||||||
|
} else {
|
||||||
|
let newData = whereStay
|
||||||
|
newData.splice(whereStay.indexOf(value), 1)
|
||||||
|
setWhereStay(newData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onWhereEat = (value:string, checked:boolean) =>{
|
||||||
|
if (checked){
|
||||||
|
setWhereEat([...whereEat, value])
|
||||||
|
} else {
|
||||||
|
let newData = whereEat
|
||||||
|
newData.splice(whereEat.indexOf(value), 1)
|
||||||
|
setWhereEat(newData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let searchParams = {
|
||||||
|
date_from: datesValue.length == 2? new Date((datesValue as any)[0]).toISOString().split('T')[0]:null,
|
||||||
|
date_to: datesValue.length == 2? new Date((datesValue as any)[1]).toISOString().split('T')[0]:null,
|
||||||
|
city: city,
|
||||||
|
stars:stars,
|
||||||
|
what_to_see:whatToSee,
|
||||||
|
where_stay: whereStay,
|
||||||
|
where_eat: whereEat,
|
||||||
|
with_kids: withKids,
|
||||||
|
with_animals: withAnimals,
|
||||||
|
movement: transport
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const disabledDate: RangePickerProps['disabledDate'] = (current:any) => {
|
||||||
|
if (!dates) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tooLate = dates[0] && current.diff(dates[0], 'days') >= 5;
|
||||||
|
const tooEarly = dates[1] && dates[1].diff(current, 'days') >= 5;
|
||||||
|
|
||||||
|
return current && current < dayjs().endOf('day') || !!tooEarly || !!tooLate;;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const onOpenChange = (open: boolean) => {
|
||||||
|
if (open) {
|
||||||
|
setDates([null, null]);
|
||||||
|
} else {
|
||||||
|
setDates(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let navigate = useNavigate()
|
||||||
|
|
||||||
|
const onNavigate = () => {
|
||||||
|
navigate('/non-auth/' + JSON.stringify(searchParams))
|
||||||
|
|
||||||
|
if (props != undefined){
|
||||||
|
(props as any).onSearch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div style={{width:'75%', marginTop:'50px'}}>
|
||||||
|
<div style={{borderRadius: toolsOpened? '20px 20px 0px 0px':'20px'}} className='toolsMainWrapper'>
|
||||||
|
<div className='rowWrapper' onClick={()=>setToolsOpened(!toolsOpened)}>
|
||||||
|
<img src='/filter.svg'></img>
|
||||||
|
<div>Фильтры</div>
|
||||||
|
</div>
|
||||||
|
<img className='rectIMG' src='/react.svg'></img>
|
||||||
|
<Select
|
||||||
|
className='antdBorder'
|
||||||
|
showSearch
|
||||||
|
placeholder="Выберите направление"
|
||||||
|
optionFilterProp="children"
|
||||||
|
onChange={(e)=>setCity(e)}
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
|
||||||
|
}
|
||||||
|
options={cities.map((city:any)=>{
|
||||||
|
return {
|
||||||
|
value:city.oid,
|
||||||
|
label: city.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img className='rectIMG' src='/react.svg'></img>
|
||||||
|
<RangePicker
|
||||||
|
disabledDate={disabledDate}
|
||||||
|
onCalendarChange={(val) => {
|
||||||
|
setDates(val);
|
||||||
|
}}
|
||||||
|
onOpenChange={onOpenChange}
|
||||||
|
changeOnBlur
|
||||||
|
onChange={(e)=>setDatesValue(e as any)}
|
||||||
|
></RangePicker>
|
||||||
|
<img className='rectIMG' src='/react.svg'></img>
|
||||||
|
<Button className='btn-y' onClick={()=>onNavigate()}>Сгенерировать</Button>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
toolsOpened? <div className='searchOpened'>
|
||||||
|
|
||||||
|
<div className='questionWrapper'>
|
||||||
|
<h2>Где остановимся</h2>
|
||||||
|
<div className='checkboxWrapper'>
|
||||||
|
<Checkbox onChange={(e)=>onWhereStay('hotel', e.target.checked)}>Отель</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhereStay('hostel', e.target.checked)}>Хостел</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhereStay('apartment', e.target.checked)}>Апартаменты</Checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='questionWrapper'>
|
||||||
|
<h2>Как перемещаться на месте</h2>
|
||||||
|
<div className='checkboxWrapper'>
|
||||||
|
<Radio.Group onChange={(e)=>setTransport(e.target.value)} value={transport}>
|
||||||
|
<Space direction="vertical">
|
||||||
|
<Radio value={'walk'}>Пешком</Radio>
|
||||||
|
<Radio value={'auto'}>Автомобиль</Radio>
|
||||||
|
<Radio value={'bike'}>Велосипед</Radio>
|
||||||
|
<Radio value={'scooter'}>Скутер</Radio>
|
||||||
|
</Space>
|
||||||
|
</Radio.Group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='questionWrapper'>
|
||||||
|
<h2>Что посмотреть</h2>
|
||||||
|
<div className='checkboxWrapper'>
|
||||||
|
<Checkbox onChange={(e)=>onWhatToSeeChange('museum', e.target.checked)}>Музеи и выставки</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhatToSeeChange('attractions', e.target.checked)}>Развлечения</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhatToSeeChange('concert', e.target.checked)}>Концерты</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhatToSeeChange('movie', e.target.checked)}>Фильмы</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhatToSeeChange('theme_park', e.target.checked)}>Тематические парки</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhatToSeeChange('viewpoint', e.target.checked)}>Достопримечательности</Checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='questionWrapper'>
|
||||||
|
<h2>Где питаться</h2>
|
||||||
|
<div className='checkboxWrapper'>
|
||||||
|
<Checkbox onChange={(e)=>onWhereEat('restaurant', e.target.checked)}>Рестораны</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhereEat('cafe', e.target.checked)}>Кафе</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onWhereEat('bar', e.target.checked)}>Бары</Checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='questionWrapper'>
|
||||||
|
<h2>Дополнительно</h2>
|
||||||
|
<div className='checkboxWrapper'>
|
||||||
|
<Checkbox onChange={(e)=>setWithKids(e.target.checked)}>С детьми</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>setWithAnimals(e.target.checked)}>С животными</Checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='questionWrapper'>
|
||||||
|
<h2>Рейтинг</h2>
|
||||||
|
<div className='checkboxWrapper'>
|
||||||
|
<Checkbox onChange={(e)=>onStarsChange(5, e.target.checked)}>5*</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onStarsChange(4, e.target.checked)}>4*</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onStarsChange(3, e.target.checked)}>3*</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onStarsChange(2, e.target.checked)}>2*</Checkbox>
|
||||||
|
<Checkbox onChange={(e)=>onStarsChange(1, e.target.checked)}>1*</Checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>:null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
0
src/elements/NonAuthSearch/style.css
Normal file
0
src/elements/NonAuthSearch/style.css
Normal file
29
src/elements/PanelRoute/index.tsx
Normal file
29
src/elements/PanelRoute/index.tsx
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { backend } from "../../consts";
|
||||||
|
import { Button } from "../Button";
|
||||||
|
|
||||||
|
|
||||||
|
export const PanelRoute:React.FC<{value:any, index:number, index2: number, onChange:(oid:string)=>void}> = (props) =>{
|
||||||
|
const [nearest, setNearest] = useState([])
|
||||||
|
return <div>
|
||||||
|
<img style={{width:'200px'}} src='/icons/not_found.jpeg'></img>
|
||||||
|
<p>{props.value.point.description}</p>
|
||||||
|
<div className="nearesrtWrapper">
|
||||||
|
{
|
||||||
|
nearest.length == 0? null: nearest.map((value:any)=>{
|
||||||
|
return <div key={value.oid}>
|
||||||
|
<div className="hotelCard" >
|
||||||
|
<img className="hotelImg" src='/icons/not_found.jpeg'></img>
|
||||||
|
<h5>{value.title}</h5>
|
||||||
|
<div className="hotelCardRow">
|
||||||
|
<div>{value.description.length > 50? value.description.slice(0,70)+'...': value.description}</div>
|
||||||
|
</div>
|
||||||
|
<Button className="btn-y" onClick={() => props.onChange(value.oid)}>Выбрать</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<Button onClick={()=>backend.get('/recommendations/' + props.value.point.oid + '/get_nearest_user_distance/').then((e)=>setNearest(e.data))} className="">Изменить точку маршрута</Button>
|
||||||
|
</div>
|
||||||
|
}
|
|
@ -187,27 +187,27 @@ export const Prefernces = () =>{
|
||||||
const attractionOptions = {
|
const attractionOptions = {
|
||||||
options:[
|
options:[
|
||||||
{
|
{
|
||||||
name: 'Park',
|
name: 'Парки',
|
||||||
icon: 'icons/park.png',
|
icon: 'icons/park.png',
|
||||||
key: 'park'
|
key: 'park'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Monument',
|
name: 'Памятники',
|
||||||
icon: 'icons/monument.png',
|
icon: 'icons/monument.png',
|
||||||
key: 'monument'
|
key: 'monument'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Museum',
|
name: 'Музеи',
|
||||||
icon: 'icons/museum.png',
|
icon: 'icons/museum.png',
|
||||||
key: 'museum'
|
key: 'museum'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Unesco',
|
name: 'Культурное наследие',
|
||||||
icon: 'icons/unesco.png',
|
icon: 'icons/unesco.png',
|
||||||
key: 'unesco'
|
key: 'unesco'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Exhibition',
|
name: 'Выставки ',
|
||||||
icon: 'icons/exhibition.png',
|
icon: 'icons/exhibition.png',
|
||||||
key: 'exhibition'
|
key: 'exhibition'
|
||||||
},
|
},
|
||||||
|
@ -232,11 +232,11 @@ export const Prefernces = () =>{
|
||||||
children:
|
children:
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Как вы предпочитаете добираться</h2>
|
<h2>Как добраться до города</h2>
|
||||||
<ChoiceIcon {...transportOptions}></ChoiceIcon>
|
<ChoiceIcon {...transportOptions}></ChoiceIcon>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Как вы предпочитаете передвигаться на месте</h2>
|
<h2>Как передвигаться по городу</h2>
|
||||||
<ChoiceIcon {...transportCityOptions}></ChoiceIcon>
|
<ChoiceIcon {...transportCityOptions}></ChoiceIcon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -247,7 +247,7 @@ export const Prefernces = () =>{
|
||||||
label: `Проживание`,
|
label: `Проживание`,
|
||||||
children: <div>
|
children: <div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Где вы предпочитаете остановиться</h2>
|
<h2>Где остановиться</h2>
|
||||||
<ChoiceIcon {...hotelOptions}></ChoiceIcon>
|
<ChoiceIcon {...hotelOptions}></ChoiceIcon>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -270,7 +270,7 @@ export const Prefernces = () =>{
|
||||||
label: `Питание`,
|
label: `Питание`,
|
||||||
children: <div>
|
children: <div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Где вы предпочитаете есть</h2>
|
<h2>Где поесть</h2>
|
||||||
<ChoiceIcon {...eatOptions}></ChoiceIcon>
|
<ChoiceIcon {...eatOptions}></ChoiceIcon>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -284,11 +284,11 @@ export const Prefernces = () =>{
|
||||||
label: `Развлечения`,
|
label: `Развлечения`,
|
||||||
children: <div>
|
children: <div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Что вы хотите увидеть</h2>
|
<h2>Что посмотреть</h2>
|
||||||
<ChoiceIcon {...attractionOptions}></ChoiceIcon>
|
<ChoiceIcon {...attractionOptions}></ChoiceIcon>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Выберите самое интересное</h2>
|
<h2>Выберите понравившиеся вам места</h2>
|
||||||
<div className='hotelsCardWrapper'>
|
<div className='hotelsCardWrapper'>
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,8 @@ import { PlaceCard } from "../TourCard";
|
||||||
import { Collapse, Tabs, TabsProps } from "antd";
|
import { Collapse, Tabs, TabsProps } from "antd";
|
||||||
import { backend } from "../../consts";
|
import { backend } from "../../consts";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { EventCard } from "../EventCard";
|
||||||
|
import { PanelRoute } from "../PanelRoute";
|
||||||
|
|
||||||
export interface RouteCardIE{
|
export interface RouteCardIE{
|
||||||
rawProps:any,
|
rawProps:any,
|
||||||
|
@ -37,12 +39,16 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
||||||
const [showMap, setShowMap] = useState(false)
|
const [showMap, setShowMap] = useState(false)
|
||||||
const [selectedDay, setSelectedDay] = useState('0')
|
const [selectedDay, setSelectedDay] = useState('0')
|
||||||
const [liked, setLiked] = useState(false)
|
const [liked, setLiked] = useState(false)
|
||||||
|
|
||||||
let navigate = useNavigate()
|
let navigate = useNavigate()
|
||||||
let cntPlaces = 0
|
let cntPlaces = 0
|
||||||
|
const [changePoint, setChangePoint] = useState<any>()
|
||||||
|
console.log(changePoint)
|
||||||
props.options.forEach((route)=>{
|
props.options.forEach((route)=>{
|
||||||
cntPlaces += route.paths.length
|
cntPlaces += route.paths.length
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
let points = props.options[Number(selectedDay)].paths.map((path)=>{
|
let points = props.options[Number(selectedDay)].paths.map((path)=>{
|
||||||
return {
|
return {
|
||||||
description:path.point.description,
|
description:path.point.description,
|
||||||
|
@ -67,7 +73,6 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const colapseItems: TabsProps['items'] = props.options.map((day, index)=>{
|
const colapseItems: TabsProps['items'] = props.options.map((day, index)=>{
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -77,11 +82,22 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
||||||
bordered={false}
|
bordered={false}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
day.paths.map((value, index2) =>
|
day.paths.map((value, index2) =>{
|
||||||
<Panel header={value.point.title} key={'collapse'+index.toString()+index2.toString()}>
|
|
||||||
<img style={{width:'200px'}} src='/icons/not_found.jpeg'></img>
|
return <Panel header={value.point.title} key={'collapse'+index.toString()+index2.toString()}>
|
||||||
<p>{value.point.description}</p>
|
<PanelRoute onChange={
|
||||||
|
(oid)=>backend.get('/onboarding/'+oid+'/get_json_event')
|
||||||
|
.then((e)=>setChangePoint(
|
||||||
|
{
|
||||||
|
point_to_change:value.point.oid,
|
||||||
|
new_point: e.data,
|
||||||
|
day:index
|
||||||
|
} as any
|
||||||
|
))}
|
||||||
|
index={index} index2={index2} value={value}></PanelRoute>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
}
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
@ -91,18 +107,34 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
||||||
|
|
||||||
const onLiked = () =>{
|
const onLiked = () =>{
|
||||||
// backend.get('route/list').then((e)=>console.log(e.data))
|
// backend.get('route/list').then((e)=>console.log(e.data))
|
||||||
|
let paths = props.rawProps.path
|
||||||
|
|
||||||
|
if (changePoint != undefined){
|
||||||
|
console.log(paths[changePoint.day])
|
||||||
|
|
||||||
|
for (let i = 0; i < paths[changePoint.day].paths.length; i++) {
|
||||||
|
console.log(paths[changePoint.day].paths[i])
|
||||||
|
if (paths[changePoint.day].paths[i].point.oid == changePoint.point_to_change) {
|
||||||
|
paths[changePoint.day].paths.splice(i, 1);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paths[changePoint.day].paths.push(changePoint.new_point)
|
||||||
|
}
|
||||||
backend.post('route/save', {
|
backend.post('route/save', {
|
||||||
points: props.rawProps.path
|
points:paths
|
||||||
}).then((e)=>console.log(e.data))
|
}).then((e)=>console.log(e.data))
|
||||||
setLiked(!liked)
|
setLiked(!liked)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBuy = () =>{
|
const onBuy = () =>{
|
||||||
backend.post('route/save', {
|
|
||||||
points: props.rawProps.path
|
|
||||||
}).then((e)=>backend.get('buy/' + e.data.id + '/add_to_buy/'))
|
|
||||||
|
|
||||||
navigate('/buyed')
|
if (localStorage.getItem('token') != null){
|
||||||
|
backend.post('route/save', {
|
||||||
|
points: props.rawProps.path
|
||||||
|
}).then((e)=>backend.get('buy/' + e.data.id + '/add_to_buy/'))
|
||||||
|
navigate('/buyed')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(
|
return(
|
||||||
<div key={props.city + props.options[0].paths[0].point.oid}>
|
<div key={props.city + props.options[0].paths[0].point.oid}>
|
||||||
|
@ -110,9 +142,9 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
||||||
sidebar={
|
sidebar={
|
||||||
<div className='sidebarContent'>
|
<div className='sidebarContent'>
|
||||||
<MyMap points={points}></MyMap>
|
<MyMap points={points}></MyMap>
|
||||||
<Tabs defaultActiveKey="0" items={colapseItems} onChange={(e:string)=>setSelectedDay(e)} />
|
<Tabs className="TabsRouteCard" defaultActiveKey="0" items={colapseItems} onChange={(e:string)=>setSelectedDay(e)} />
|
||||||
<Button className='' onClick={()=>onBuy()}>КУПИТЬ</Button>
|
<Button className='' onClick={()=>onBuy()}>КУПИТЬ</Button>
|
||||||
<Button className='btn-y' onClick={()=>setShowMap(!showMap)}>Закрыть</Button>
|
<Button className='btn-y route-btn' onClick={()=>setShowMap(!showMap)}>Закрыть</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
open={showMap}
|
open={showMap}
|
||||||
|
|
|
@ -154,11 +154,23 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
|
.route-btn{
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
.likeBtn:hover{
|
.likeBtn:hover{
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.TabsRouteCard{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.nearesrtWrapper{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap:15px
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-device-width: 600px) {
|
@media screen and (max-device-width: 600px) {
|
||||||
.tourcard-block{
|
.tourcard-block{
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { Checkbox } from '@yandex/ui/Checkbox/desktop/bundle'
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { configureRootTheme } from '@yandex/ui/Theme'
|
import { configureRootTheme } from '@yandex/ui/Theme'
|
||||||
import { theme } from '@yandex/ui/Theme/presets/default'
|
import { theme } from '@yandex/ui/Theme/presets/default'
|
||||||
|
import { backend } from "../../consts";
|
||||||
configureRootTheme({ theme })
|
configureRootTheme({ theme })
|
||||||
|
|
||||||
export interface MapIE{
|
export interface MapIE{
|
||||||
|
@ -125,8 +126,8 @@ export const MyMap: React.FC<MapIE> = (props) =>{
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
props.remapedPoints != undefined? props.remapedPoints.map((point, index)=>{
|
props.remapedPoints != undefined? props.remapedPoints.map((point, index)=>{
|
||||||
return <Marker longitude={point.cords[0]} latitude={point.cords[1]} anchor="bottom" >
|
return <Marker onClick={(e)=>console.log(e, 'click' + point.title)} longitude={point.cords[0]} latitude={point.cords[1]} anchor="bottom" >
|
||||||
<img src="/redpin.png" />
|
<img onClick={()=>'IMG IMG IMG'} src="/redpin.png" />
|
||||||
</Marker>
|
</Marker>
|
||||||
}) : null
|
}) : null
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AutoComplete, DatePicker, Input, Checkbox, Select, Radio, Space, Spin } from 'antd';
|
import { AutoComplete, DatePicker, Input, Checkbox, Select, Radio, Space, Spin, TabsProps, Tabs } from 'antd';
|
||||||
import react, { useEffect, useRef, useState } from 'react'
|
import react, { useEffect, useRef, useState } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { backend, updateBackend } from '../../consts';
|
import { backend, updateBackend } from '../../consts';
|
||||||
|
@ -22,7 +22,6 @@ export const Main: react.FC = () => {
|
||||||
|
|
||||||
let token = localStorage.getItem('token')
|
let token = localStorage.getItem('token')
|
||||||
let firstAuth = localStorage.getItem('firstAuth')
|
let firstAuth = localStorage.getItem('firstAuth')
|
||||||
console.log(token)
|
|
||||||
|
|
||||||
const queried = useRef(false);
|
const queried = useRef(false);
|
||||||
|
|
||||||
|
@ -46,16 +45,32 @@ export const Main: react.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null == localStorage.getItem('token')){
|
if (null == localStorage.getItem('token')){
|
||||||
navigate('/login')
|
navigate('/non-auth/{}')
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (favorites.length == 0){
|
|
||||||
// backend.get('user/favorite').then((e)=>setFavorites(e.data))
|
|
||||||
// }
|
|
||||||
// if (events.length == 0){
|
|
||||||
// backend.get('recommendations/recommendations/').then((e)=>setEvents(e.data as any));
|
|
||||||
// }
|
|
||||||
})
|
})
|
||||||
|
console.log(events)
|
||||||
|
|
||||||
|
const items: TabsProps['items'] = []
|
||||||
|
events.forEach((category:any, index)=>{
|
||||||
|
items.push({
|
||||||
|
key:index.toString(),
|
||||||
|
label: category.category,
|
||||||
|
children: <div className='cardWrapper'>
|
||||||
|
<GenerateCard></GenerateCard>
|
||||||
|
{
|
||||||
|
category.events.map((event:any)=>{
|
||||||
|
return <EventCard category={category.category} {...event}></EventCard>
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mainWrapper'>
|
<div className='mainWrapper'>
|
||||||
|
@ -73,7 +88,7 @@ export const Main: react.FC = () => {
|
||||||
<div className='mainCard'>
|
<div className='mainCard'>
|
||||||
<h2>Рекомендации</h2>
|
<h2>Рекомендации</h2>
|
||||||
|
|
||||||
<div className='cardWrapper'>
|
{/* <div className='cardWrapper'>
|
||||||
<GenerateCard></GenerateCard>
|
<GenerateCard></GenerateCard>
|
||||||
{
|
{
|
||||||
events.length == 0? <Spin/>
|
events.length == 0? <Spin/>
|
||||||
|
@ -87,7 +102,10 @@ export const Main: react.FC = () => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div> */}
|
||||||
|
{
|
||||||
|
items.length == 0? <Spin></Spin>: <Tabs defaultActiveKey="0" items={items}></Tabs>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className='mainCard'>
|
<div className='mainCard'>
|
||||||
<h2>Избранное</h2>
|
<h2>Избранное</h2>
|
||||||
|
|
140
src/pages/NonAuth/index.tsx
Normal file
140
src/pages/NonAuth/index.tsx
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { RouteCard, RouteCardIE } from "../../elements/RouteCard";
|
||||||
|
import { Search } from "../../elements/Search";
|
||||||
|
import { Spin } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
|
import { NonAuthSearch } from "../../elements/NonAuthSearch";
|
||||||
|
import { Button } from "../../elements/Button";
|
||||||
|
import { EventCard } from "../../elements/EventCard";
|
||||||
|
import { BASE_URL, nonAuthToken } from "../../consts";
|
||||||
|
|
||||||
|
|
||||||
|
let backend = axios.create({
|
||||||
|
baseURL: BASE_URL,
|
||||||
|
timeout: 100000,
|
||||||
|
headers: {'Authorization': 'Bearer ' + nonAuthToken}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const NonAuth:React.FC = () =>{
|
||||||
|
let { prefs } = useParams();
|
||||||
|
|
||||||
|
const [data, setData] = useState([])
|
||||||
|
const [events, setEvents] = useState([])
|
||||||
|
|
||||||
|
const queried = useRef(false);
|
||||||
|
useEffect(()=>{
|
||||||
|
|
||||||
|
const dataLoad = async (prefs: string) => {
|
||||||
|
const routes = await backend.post('/route/build',JSON.parse(prefs as string))
|
||||||
|
const events = await backend.post('/recommendations/build_events/',JSON.parse(prefs as string))
|
||||||
|
return {
|
||||||
|
routes, events
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!queried.current) {
|
||||||
|
queried.current = true;
|
||||||
|
dataLoad(prefs as string).then((data) => {
|
||||||
|
setData(data.routes.data as any);
|
||||||
|
setEvents(data.events.data as any);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [prefs])
|
||||||
|
|
||||||
|
let newData;
|
||||||
|
|
||||||
|
if (data.length != 0){
|
||||||
|
newData = data.map((tour:any)=>{
|
||||||
|
|
||||||
|
let newPath = tour.path.map((path:any)=>{
|
||||||
|
let newPaths = path.paths
|
||||||
|
for (let i = 0; i < newPaths.length; i++) {
|
||||||
|
if (newPaths[i].type == 'transition') {
|
||||||
|
newPaths.splice(i, 1);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
date:path.date,
|
||||||
|
paths: newPaths
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
city: tour.city,
|
||||||
|
path: newPath
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const onSearch = () =>{
|
||||||
|
setData([])
|
||||||
|
}
|
||||||
|
|
||||||
|
let navigate = useNavigate()
|
||||||
|
return(
|
||||||
|
<div className="mainWrapper">
|
||||||
|
|
||||||
|
<h1>Зарегистрируйтесь или войдите, чтобы использовать весь функционал</h1>
|
||||||
|
<div className="changeBtnWrapper">
|
||||||
|
<Button onClick={()=>navigate('/register')} className="changeYBtn">Зарегистрироваться</Button>
|
||||||
|
<Button onClick={()=>navigate('/login')} className='changeBtn'>Войти</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<NonAuthSearch onSearch={()=>onSearch()}></NonAuthSearch>
|
||||||
|
{
|
||||||
|
data.length == 0 || newData == undefined?
|
||||||
|
|
||||||
|
<Spin />:
|
||||||
|
<div className='mainCard'>
|
||||||
|
<h2>Предлагаемые туры</h2>
|
||||||
|
|
||||||
|
<div className='cardWrapper'>
|
||||||
|
{
|
||||||
|
newData.map((tour:any, index:number)=>
|
||||||
|
<RouteCard city={tour.city} rawProps={data[index]} options={tour.path}></RouteCard>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
events.length == 0? <Spin/>
|
||||||
|
:
|
||||||
|
<div className='mainCard'>
|
||||||
|
<h2>Рекомендованные меропрития</h2>
|
||||||
|
<div className='cardWrapper'>{
|
||||||
|
events.map((event:any)=>{
|
||||||
|
return <EventCard category={'viewpoint'} {...event}></EventCard>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<a href='https://1drv.ms/w/s!AuaFmGWFNV5Np0OhMmVtxPXlG2Ob?e=f7NDCp'>Документация</a>
|
||||||
|
|
||||||
|
<div className='mainIconWrapper'>
|
||||||
|
<img className='mainIcon' src='/icons/yt.svg'></img>
|
||||||
|
<img className='mainIcon' src='/icons/vk.svg'></img>
|
||||||
|
<img className='mainIcon' src='/icons/dz.svg'></img>
|
||||||
|
<img className='mainIcon' src='/icons/tg.svg'></img>
|
||||||
|
<img className='mainIcon' src='/icons/ok.svg'></img>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='grey'>© 2023 A project of the Government of Moscow</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import { Prefernces } from './elements/Prefernces';
|
||||||
import { Favorites } from './pages/Favorites';
|
import { Favorites } from './pages/Favorites';
|
||||||
import { Weather } from './pages/Weather';
|
import { Weather } from './pages/Weather';
|
||||||
import { Buyed } from './pages/Buyed';
|
import { Buyed } from './pages/Buyed';
|
||||||
|
import { NonAuth } from './pages/NonAuth';
|
||||||
|
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
|
@ -58,6 +59,10 @@ const routes = [
|
||||||
{
|
{
|
||||||
path: '/buyed',
|
path: '/buyed',
|
||||||
element: <Buyed></Buyed>
|
element: <Buyed></Buyed>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/non-auth/:prefs',
|
||||||
|
element: <NonAuth></NonAuth>
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user