mirror of
https://github.com/task-17-lct/frontend.git
synced 2024-11-21 21:36: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="description"
|
||||
content="Web site created using create-react-app"
|
||||
content="Russpass MAGNUM OPUS #1"
|
||||
/>
|
||||
<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";
|
||||
|
||||
// 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({
|
||||
baseURL: 'https://0e06-92-100-146-65.ngrok-free.app/api/',
|
||||
baseURL: BASE_URL,
|
||||
timeout: 100000,
|
||||
headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}
|
||||
}
|
||||
|
@ -16,9 +13,13 @@ export let backend = axios.create({
|
|||
|
||||
export const updateBackend = () =>{
|
||||
backend = axios.create({
|
||||
baseURL: 'https://0e06-92-100-146-65.ngrok-free.app/api/',
|
||||
baseURL: BASE_URL,
|
||||
timeout: 100000,
|
||||
headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const nonAuthToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjg4OTM2NDQ5LCJpYXQiOjE2ODYzNDQ0NDksImp0aSI6IjY0MzgyNzg3NmMzZTRhN2Q5ODAzYjJjMTM0MzY1MTg3IiwidXNlcl9pZCI6OH0._4AkdCc5XkfROe_9taVtFGV4Rx2HOM1HnV0Byc7NY_o'
|
|
@ -1,4 +1,5 @@
|
|||
import React, { useState } from "react";
|
||||
import { useLocation, useParams } from "react-router-dom";
|
||||
import { backend } from "../../consts";
|
||||
import { Button } from "../Button";
|
||||
import './style.css'
|
||||
|
@ -28,12 +29,17 @@ enum category{
|
|||
|
||||
|
||||
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 = ()=>{
|
||||
backend.get('/onboarding/' + props.oid + '/add_to_favorites/')
|
||||
setLiked(!liked)
|
||||
if (localStorage.getItem('token') != null){
|
||||
backend.get('/onboarding/' + props.oid + '/add_to_favorites/')
|
||||
setLiked(!liked)
|
||||
}
|
||||
}
|
||||
console.log(location)
|
||||
|
||||
return(
|
||||
<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 = {
|
||||
options:[
|
||||
{
|
||||
name: 'Park',
|
||||
name: 'Парки',
|
||||
icon: 'icons/park.png',
|
||||
key: 'park'
|
||||
},
|
||||
{
|
||||
name: 'Monument',
|
||||
name: 'Памятники',
|
||||
icon: 'icons/monument.png',
|
||||
key: 'monument'
|
||||
},
|
||||
{
|
||||
name: 'Museum',
|
||||
name: 'Музеи',
|
||||
icon: 'icons/museum.png',
|
||||
key: 'museum'
|
||||
},
|
||||
{
|
||||
name: 'Unesco',
|
||||
name: 'Культурное наследие',
|
||||
icon: 'icons/unesco.png',
|
||||
key: 'unesco'
|
||||
},
|
||||
{
|
||||
name: 'Exhibition',
|
||||
name: 'Выставки ',
|
||||
icon: 'icons/exhibition.png',
|
||||
key: 'exhibition'
|
||||
},
|
||||
|
@ -232,11 +232,11 @@ export const Prefernces = () =>{
|
|||
children:
|
||||
<div>
|
||||
<div>
|
||||
<h2>Как вы предпочитаете добираться</h2>
|
||||
<h2>Как добраться до города</h2>
|
||||
<ChoiceIcon {...transportOptions}></ChoiceIcon>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Как вы предпочитаете передвигаться на месте</h2>
|
||||
<h2>Как передвигаться по городу</h2>
|
||||
<ChoiceIcon {...transportCityOptions}></ChoiceIcon>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -247,7 +247,7 @@ export const Prefernces = () =>{
|
|||
label: `Проживание`,
|
||||
children: <div>
|
||||
<div>
|
||||
<h2>Где вы предпочитаете остановиться</h2>
|
||||
<h2>Где остановиться</h2>
|
||||
<ChoiceIcon {...hotelOptions}></ChoiceIcon>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -270,7 +270,7 @@ export const Prefernces = () =>{
|
|||
label: `Питание`,
|
||||
children: <div>
|
||||
<div>
|
||||
<h2>Где вы предпочитаете есть</h2>
|
||||
<h2>Где поесть</h2>
|
||||
<ChoiceIcon {...eatOptions}></ChoiceIcon>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -284,11 +284,11 @@ export const Prefernces = () =>{
|
|||
label: `Развлечения`,
|
||||
children: <div>
|
||||
<div>
|
||||
<h2>Что вы хотите увидеть</h2>
|
||||
<h2>Что посмотреть</h2>
|
||||
<ChoiceIcon {...attractionOptions}></ChoiceIcon>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Выберите самое интересное</h2>
|
||||
<h2>Выберите понравившиеся вам места</h2>
|
||||
<div className='hotelsCardWrapper'>
|
||||
|
||||
{
|
||||
|
|
|
@ -8,6 +8,8 @@ import { PlaceCard } from "../TourCard";
|
|||
import { Collapse, Tabs, TabsProps } from "antd";
|
||||
import { backend } from "../../consts";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { EventCard } from "../EventCard";
|
||||
import { PanelRoute } from "../PanelRoute";
|
||||
|
||||
export interface RouteCardIE{
|
||||
rawProps:any,
|
||||
|
@ -37,12 +39,16 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
|||
const [showMap, setShowMap] = useState(false)
|
||||
const [selectedDay, setSelectedDay] = useState('0')
|
||||
const [liked, setLiked] = useState(false)
|
||||
|
||||
let navigate = useNavigate()
|
||||
let cntPlaces = 0
|
||||
const [changePoint, setChangePoint] = useState<any>()
|
||||
console.log(changePoint)
|
||||
props.options.forEach((route)=>{
|
||||
cntPlaces += route.paths.length
|
||||
})
|
||||
|
||||
|
||||
let points = props.options[Number(selectedDay)].paths.map((path)=>{
|
||||
return {
|
||||
description:path.point.description,
|
||||
|
@ -67,7 +73,6 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
|||
</div>
|
||||
}
|
||||
})
|
||||
|
||||
const colapseItems: TabsProps['items'] = props.options.map((day, index)=>{
|
||||
|
||||
return {
|
||||
|
@ -77,11 +82,22 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
|||
bordered={false}
|
||||
>
|
||||
{
|
||||
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>
|
||||
<p>{value.point.description}</p>
|
||||
day.paths.map((value, index2) =>{
|
||||
|
||||
return <Panel header={value.point.title} key={'collapse'+index.toString()+index2.toString()}>
|
||||
<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>
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
</Collapse>
|
||||
|
@ -91,18 +107,34 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
|||
|
||||
const onLiked = () =>{
|
||||
// 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', {
|
||||
points: props.rawProps.path
|
||||
points:paths
|
||||
}).then((e)=>console.log(e.data))
|
||||
setLiked(!liked)
|
||||
}
|
||||
|
||||
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(
|
||||
<div key={props.city + props.options[0].paths[0].point.oid}>
|
||||
|
@ -110,9 +142,9 @@ export const RouteCard:React.FC<RouteCardIE> = (props) =>{
|
|||
sidebar={
|
||||
<div className='sidebarContent'>
|
||||
<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='btn-y' onClick={()=>setShowMap(!showMap)}>Закрыть</Button>
|
||||
<Button className='btn-y route-btn' onClick={()=>setShowMap(!showMap)}>Закрыть</Button>
|
||||
</div>
|
||||
}
|
||||
open={showMap}
|
||||
|
|
|
@ -154,11 +154,23 @@
|
|||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.route-btn{
|
||||
width: 100% !important;
|
||||
}
|
||||
.likeBtn:hover{
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.TabsRouteCard{
|
||||
width: 100%;
|
||||
}
|
||||
.nearesrtWrapper{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap:15px
|
||||
}
|
||||
|
||||
@media screen and (max-device-width: 600px) {
|
||||
.tourcard-block{
|
||||
width: 300px;
|
||||
|
|
|
@ -5,6 +5,7 @@ import { Checkbox } from '@yandex/ui/Checkbox/desktop/bundle'
|
|||
import path from "path";
|
||||
import { configureRootTheme } from '@yandex/ui/Theme'
|
||||
import { theme } from '@yandex/ui/Theme/presets/default'
|
||||
import { backend } from "../../consts";
|
||||
configureRootTheme({ theme })
|
||||
|
||||
export interface MapIE{
|
||||
|
@ -125,8 +126,8 @@ export const MyMap: React.FC<MapIE> = (props) =>{
|
|||
}
|
||||
{
|
||||
props.remapedPoints != undefined? props.remapedPoints.map((point, index)=>{
|
||||
return <Marker longitude={point.cords[0]} latitude={point.cords[1]} anchor="bottom" >
|
||||
<img src="/redpin.png" />
|
||||
return <Marker onClick={(e)=>console.log(e, 'click' + point.title)} longitude={point.cords[0]} latitude={point.cords[1]} anchor="bottom" >
|
||||
<img onClick={()=>'IMG IMG IMG'} src="/redpin.png" />
|
||||
</Marker>
|
||||
}) : 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 { useNavigate } from 'react-router-dom';
|
||||
import { backend, updateBackend } from '../../consts';
|
||||
|
@ -22,7 +22,6 @@ export const Main: react.FC = () => {
|
|||
|
||||
let token = localStorage.getItem('token')
|
||||
let firstAuth = localStorage.getItem('firstAuth')
|
||||
console.log(token)
|
||||
|
||||
const queried = useRef(false);
|
||||
|
||||
|
@ -46,16 +45,32 @@ export const Main: react.FC = () => {
|
|||
}
|
||||
|
||||
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 (
|
||||
<div className='mainWrapper'>
|
||||
|
@ -73,7 +88,7 @@ export const Main: react.FC = () => {
|
|||
<div className='mainCard'>
|
||||
<h2>Рекомендации</h2>
|
||||
|
||||
<div className='cardWrapper'>
|
||||
{/* <div className='cardWrapper'>
|
||||
<GenerateCard></GenerateCard>
|
||||
{
|
||||
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 className='mainCard'>
|
||||
<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 { Weather } from './pages/Weather';
|
||||
import { Buyed } from './pages/Buyed';
|
||||
import { NonAuth } from './pages/NonAuth';
|
||||
|
||||
|
||||
const routes = [
|
||||
|
@ -58,6 +59,10 @@ const routes = [
|
|||
{
|
||||
path: '/buyed',
|
||||
element: <Buyed></Buyed>
|
||||
},
|
||||
{
|
||||
path: '/non-auth/:prefs',
|
||||
element: <NonAuth></NonAuth>
|
||||
}
|
||||
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue
Block a user