Hackathon finished

This commit is contained in:
2023-05-14 00:40:36 +03:00
commit 619aead639
45 changed files with 4789 additions and 0 deletions

View File

@ -0,0 +1,54 @@
import Modal from 'react-bootstrap/Modal'
import { categoryNames } from '../assets/category'
import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet'
import { Button } from 'react-bootstrap'
import useBook from '../utils/useBook'
function AnnouncementDetails({ close, announcement: { id, name, category, bestBy, description, lat, lng, address, metro } }) {
const handleBook = useBook(id)
return (
<div
className="modal show"
style={{ display: 'flex', position: 'initial', alignItems: "center" }}
>
<Modal.Dialog>
<Modal.Header closeButton onHide={close}>
<Modal.Title>
Подробнее
</Modal.Title>
</Modal.Header>
<Modal.Body>
<h1>{name}</h1>
<span>{categoryNames.get(category)}</span>
<span className='m-2'>&#x2022;</span> {/* dot */}
<span>Годен до {new Date(bestBy).toLocaleString('ru-RU')}</span>
<p className='mb-2'>{description}</p>
<MapContainer style={{ width: "100%", minHeight: 300 }} center={[lat, lng]} zoom={16} >
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[lat, lng]}>
<Popup>{address + "\n" + metro}</Popup>
</Marker>
</MapContainer>
</Modal.Body>
<Modal.Footer>
<Button variant='success' onClick={handleBook}>
Забронировать
</Button>
</Modal.Footer>
</Modal.Dialog>
</div>
)
}
export default AnnouncementDetails

View File

@ -0,0 +1,50 @@
import { Link } from 'react-router-dom'
import addIcon from '../assets/addIcon.svg'
import filterIcon from '../assets/filterIcon.svg'
import userIcon from '../assets/userIcon.svg'
const navBarStyles = {
backgroundColor: 'var(--bs-success)',
height: 56,
width: "100%",
}
const navBarGroupStyles = {
display: "flex",
flexDirection: "row",
height: "100%",
margin: "auto"
}
const navBarElementStyles = {
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center"
}
function BottomNavBar({ width, toggleFilters }) {
return (
<div style={navBarStyles}>
<div style={{ ...navBarGroupStyles, width: width }}>
<a style={navBarElementStyles} onClick={() => toggleFilters(true)}>
<img src={filterIcon} alt="Фильтровать объявления" title='Фильтровать объявления' />
</a>
<Link style={navBarElementStyles} to="/add" >
<img src={addIcon} alt="Опубликовать объявление" title='Опубликовать объявление' />
</Link>
<Link style={navBarElementStyles} to={"/user"} >
<img src={userIcon} alt="Личный кабинет" title='Личный кабинет' />
</Link>
</div>
</div>
)
}
export default BottomNavBar

View File

@ -0,0 +1,74 @@
import { Button, Form, Modal } from "react-bootstrap"
import { categoryNames } from "../assets/category"
import { metros } from '../assets/metro'
function Filters({ filter, setFilter, filterShown, setFilterShown }) {
const handleSubmit = (event) => {
event.preventDefault();
event.stopPropagation();
const formData = new FormData(event.currentTarget)
setFilter(prev => ({
...prev,
category: formData.get("category") || null,
metro: formData.get("metro") || null
}))
setFilterShown(false)
}
return (
<Modal show={filterShown} onHide={() => setFilterShown(false)} centered>
<Modal.Header closeButton>
<Modal.Title>
Фильтрация
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={handleSubmit}>
<Form.Group className="mb-3" controlId="categoryFilter">
<Form.Label>
Категория
</Form.Label>
<Form.Select name="category" defaultValue={filter.category || undefined}>
<option value="">
Выберите категорию
</option>
{Array.from(categoryNames).map(
([category, categoryName]) =>
<option key={category} value={category}>{categoryName}</option>
)}
</Form.Select>
</Form.Group>
<Form.Group className="mb-3" controlId="metroFilter">
<Form.Label>
Станция метро
</Form.Label>
<Form.Select name="metro" defaultValue={filter.metro || undefined}>
<option value="">
Выберите станцию метро
</option>
{metros.map(
(metro) =>
<option key={metro} value={metro}>{metro}</option>
)}
</Form.Select>
</Form.Group>
<Button variant="success" type="submit">
Отправить
</Button>
</Form>
</Modal.Body>
</Modal>
)
}
export default Filters

View File

@ -0,0 +1,19 @@
import { useEffect } from "react"
import { getToken } from "../utils/auth"
import { useNavigate } from "react-router-dom"
function WithToken({ children }) {
const navigate = useNavigate()
useEffect(() => {
if (!getToken()) {
return navigate("/login")
}
}, [])
return (
<>{children}</>
)
}
export default WithToken