forked from polka_billy/porridger
Hackathon finished
This commit is contained in:
54
front/src/components/AnnouncementDetails.jsx
Normal file
54
front/src/components/AnnouncementDetails.jsx
Normal 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'>•</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='© <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
|
50
front/src/components/BottomNavBar.jsx
Normal file
50
front/src/components/BottomNavBar.jsx
Normal 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
|
74
front/src/components/Filters.jsx
Normal file
74
front/src/components/Filters.jsx
Normal 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
|
19
front/src/components/WithToken.jsx
Normal file
19
front/src/components/WithToken.jsx
Normal 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
|
Reference in New Issue
Block a user