forked from polka_billy/porridger
Added TypeScript for frontend
Added type definitions for components, functions, data Added guards for network responses fixes #8
This commit is contained in:
@ -4,8 +4,14 @@ import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet'
|
||||
import LineDot from './LineDot'
|
||||
import { categoryNames } from '../assets/category'
|
||||
import { useBook } from '../hooks/api'
|
||||
import { Announcement } from '../hooks/api/useHomeAnnouncementList'
|
||||
|
||||
function AnnouncementDetails({ close, announcement: { id, name, category, bestBy, description, lat, lng, address, metro } }) {
|
||||
type AnnouncementDetailsProps = {
|
||||
close: () => void,
|
||||
announcement: Announcement
|
||||
}
|
||||
|
||||
function AnnouncementDetails({ close, announcement: { id, name, category, bestBy, description, lat, lng, address, metro } }: AnnouncementDetailsProps) {
|
||||
const { handleBook, status: bookStatus } = useBook(id)
|
||||
|
||||
return (
|
||||
@ -46,7 +52,7 @@ function AnnouncementDetails({ close, announcement: { id, name, category, bestBy
|
||||
</Modal.Body>
|
||||
|
||||
<Modal.Footer>
|
||||
<Button variant='success' onClick={handleBook}>
|
||||
<Button variant='success' onClick={() => void handleBook()}>
|
||||
{bookStatus || "Забронировать"}
|
||||
</Button>
|
||||
</Modal.Footer>
|
@ -4,20 +4,20 @@ import addIcon from '../assets/addIcon.svg'
|
||||
import filterIcon from '../assets/filterIcon.svg'
|
||||
import userIcon from '../assets/userIcon.svg'
|
||||
|
||||
const navBarStyles = {
|
||||
const navBarStyles: React.CSSProperties = {
|
||||
backgroundColor: 'var(--bs-success)',
|
||||
height: 56,
|
||||
width: "100%",
|
||||
}
|
||||
|
||||
const navBarGroupStyles = {
|
||||
const navBarGroupStyles: React.CSSProperties = {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
height: "100%",
|
||||
margin: "auto"
|
||||
}
|
||||
|
||||
const navBarElementStyles = {
|
||||
const navBarElementStyles: React.CSSProperties = {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
@ -25,7 +25,12 @@ const navBarElementStyles = {
|
||||
justifyContent: "center"
|
||||
}
|
||||
|
||||
function BottomNavBar({ width, toggleFilters }) {
|
||||
type BottomNavBarProps = {
|
||||
width: number,
|
||||
toggleFilters: (p: boolean) => void
|
||||
}
|
||||
|
||||
function BottomNavBar({ width, toggleFilters }: BottomNavBarProps) {
|
||||
return (
|
||||
<div style={navBarStyles}>
|
||||
<div style={{ ...navBarGroupStyles, width: width }}>
|
||||
@ -47,4 +52,4 @@ function BottomNavBar({ width, toggleFilters }) {
|
||||
)
|
||||
}
|
||||
|
||||
export default BottomNavBar
|
||||
export default BottomNavBar
|
@ -1,12 +0,0 @@
|
||||
import { useMapEvent } from "react-leaflet"
|
||||
|
||||
function ClickHandler({ setPosition }) {
|
||||
const map = useMapEvent('click', (e) => {
|
||||
setPosition(e.latlng)
|
||||
map.setView(e.latlng)
|
||||
})
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export default ClickHandler
|
14
front/src/components/ClickHandler.tsx
Normal file
14
front/src/components/ClickHandler.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { useMapEvent } from "react-leaflet"
|
||||
import { SetState } from "../utils/types"
|
||||
import { LatLng } from "leaflet"
|
||||
|
||||
function ClickHandler({ setPosition }: { setPosition: SetState<LatLng> }) {
|
||||
const map = useMapEvent('click', (e) => {
|
||||
setPosition(e.latlng)
|
||||
map.setView(e.latlng)
|
||||
})
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export default ClickHandler
|
@ -1,11 +1,21 @@
|
||||
import { Button, Form, Modal } from "react-bootstrap"
|
||||
|
||||
import { categoryNames } from "../assets/category"
|
||||
import { stations, lines } from '../assets/metro'
|
||||
import { stations, lines, lineNames } from '../assets/metro'
|
||||
import { FiltersType } from "../utils/filters"
|
||||
import { SetState } from "../utils/types"
|
||||
import { FormEventHandler } from "react"
|
||||
|
||||
function Filters({ filter, setFilter, filterShown, setFilterShown }) {
|
||||
type FiltersProps = {
|
||||
filter: FiltersType,
|
||||
setFilter: SetState<FiltersType>,
|
||||
filterShown: boolean,
|
||||
setFilterShown: SetState<boolean>
|
||||
}
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
function Filters({ filter, setFilter, filterShown, setFilterShown }: FiltersProps) {
|
||||
|
||||
const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
@ -13,8 +23,8 @@ function Filters({ filter, setFilter, filterShown, setFilterShown }) {
|
||||
|
||||
setFilter(prev => ({
|
||||
...prev,
|
||||
category: formData.get("category") || null,
|
||||
metro: formData.get("metro") || null
|
||||
category: (formData.get("category") as (FiltersType['category'] | null)) || undefined,
|
||||
metro: (formData.get("metro") as (FiltersType['metro'] | null)) || undefined
|
||||
}))
|
||||
|
||||
setFilterShown(false)
|
||||
@ -55,10 +65,10 @@ function Filters({ filter, setFilter, filterShown, setFilterShown }) {
|
||||
<option value="">
|
||||
Выберите станцию метро
|
||||
</option>
|
||||
{Object.entries(stations).map(
|
||||
([line, stations]) =>
|
||||
<optgroup key={line} label={lines[line]}>
|
||||
{Array.from(stations).map(metro =>
|
||||
{lines.map(
|
||||
line =>
|
||||
<optgroup key={line} label={lineNames[line]}>
|
||||
{Array.from(stations[line]).map(metro =>
|
||||
<option key={metro} value={metro}>{metro}</option>
|
||||
)}
|
||||
</optgroup>
|
@ -1,9 +1,13 @@
|
||||
import { colors, lines } from '../assets/metro'
|
||||
import { colors, lineNames } from '../assets/metro'
|
||||
import { lineByName } from '../utils/metro'
|
||||
|
||||
function LineDot({ station }) {
|
||||
function LineDot({ station }: { station: string }) {
|
||||
const line = lineByName(station)
|
||||
const lineTitle = lines[line]
|
||||
|
||||
if (line == undefined)
|
||||
return <></>
|
||||
|
||||
const lineTitle = lineNames[line]
|
||||
const color = colors[line]
|
||||
|
||||
return <span title={`${lineTitle} ветка`} style={{ color: color }}>⬤</span>
|
@ -1,6 +1,14 @@
|
||||
import { Marker, Popup, useMapEvents } from "react-leaflet"
|
||||
import { LatLng } from 'leaflet'
|
||||
import { SetState } from "../utils/types"
|
||||
|
||||
const LocationMarker = ({ address, position, setPosition }) => {
|
||||
type LocationMarkerProps = {
|
||||
address: string,
|
||||
position: LatLng,
|
||||
setPosition: SetState<LatLng>
|
||||
}
|
||||
|
||||
const LocationMarker = ({ address, position, setPosition }: LocationMarkerProps) => {
|
||||
|
||||
const map = useMapEvents({
|
||||
dragend: () => {
|
@ -1,9 +1,15 @@
|
||||
import { Marker, Popup } from "react-leaflet"
|
||||
import { Trashbox } from "../hooks/api/useTrashboxes"
|
||||
|
||||
const TrashboxMarkers = ({ trashboxes, selectTrashbox }) => {
|
||||
type TrashboxMarkersProps = {
|
||||
trashboxes: Trashbox[],
|
||||
selectTrashbox: ({ index, category }: { index: number, category: string }) => void
|
||||
}
|
||||
|
||||
const TrashboxMarkers = ({ trashboxes, selectTrashbox }: TrashboxMarkersProps) => {
|
||||
return (
|
||||
<>{trashboxes.map((trashbox, index) => (
|
||||
<Marker key={trashbox.Lat + "" + trashbox.Lng} position={[trashbox.Lat, trashbox.Lng]}>
|
||||
<Marker key={`${trashbox.Lat}${trashbox.Lng}`} position={[trashbox.Lat, trashbox.Lng]}>
|
||||
<Popup>
|
||||
<p>{trashbox.Address}</p>
|
||||
<p>Тип мусора: <>
|
||||
@ -23,4 +29,4 @@ const TrashboxMarkers = ({ trashboxes, selectTrashbox }) => {
|
||||
)
|
||||
}
|
||||
|
||||
export default TrashboxMarkers
|
||||
export default TrashboxMarkers
|
@ -1,8 +1,8 @@
|
||||
import { useEffect } from "react"
|
||||
import { PropsWithChildren, useEffect } from "react"
|
||||
import { getToken } from "../utils/auth"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
|
||||
function WithToken({ children }) {
|
||||
function WithToken({ children }: PropsWithChildren) {
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
@ -10,10 +10,10 @@ function WithToken({ children }) {
|
||||
return navigate("/login")
|
||||
}
|
||||
}, [navigate])
|
||||
|
||||
|
||||
return (
|
||||
<>{children}</>
|
||||
)
|
||||
}
|
||||
|
||||
export default WithToken
|
||||
export default WithToken
|
Reference in New Issue
Block a user