add nearest points

This commit is contained in:
= 2023-06-10 02:40:39 +03:00
parent 19e22d9298
commit bf51971cd5
14 changed files with 536 additions and 52 deletions

View File

@ -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" />
<!--

View File

@ -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/'

View File

@ -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'

View File

@ -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}>

View 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>
);
}

View File

View 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>
}

View File

@ -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'>
{

View File

@ -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>
</Panel>
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}

View File

@ -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;

View File

@ -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
}

View File

@ -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,17 +45,33 @@ 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
View 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>
);
}

View File

@ -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>
}
]