|
|
|
@ -1,3 +1,4 @@
|
|
|
|
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
|
|
|
import React, {
|
|
|
|
|
useState,
|
|
|
|
|
useReducer,
|
|
|
|
@ -7,8 +8,9 @@ import React, {
|
|
|
|
|
FormEvent,
|
|
|
|
|
useEffect,
|
|
|
|
|
} from "react";
|
|
|
|
|
import * as ReactDOM from "react-dom";
|
|
|
|
|
import { render } from "react-dom";
|
|
|
|
|
import { offenses } from "./offenses";
|
|
|
|
|
import axios from "axios";
|
|
|
|
|
import Nav from "./Nav";
|
|
|
|
|
//Importing fileReducer to use in useReducer hook, and File interface to use in looping over array of files
|
|
|
|
|
import { fileReducer, filesInitialState, File } from "./fileReducer";
|
|
|
|
@ -18,8 +20,25 @@ import { MapContainer, TileLayer, Marker, useMapEvents } from "react-leaflet";
|
|
|
|
|
import "./styles/reset.css";
|
|
|
|
|
import "./styles/app.scss";
|
|
|
|
|
import { getAddress } from "./location";
|
|
|
|
|
|
|
|
|
|
import { FileType } from "./file";
|
|
|
|
|
const App: FC = () => {
|
|
|
|
|
const [isLogged, setIsLogged] = useState(false);
|
|
|
|
|
|
|
|
|
|
const checkUser = async (): Promise<void> => {
|
|
|
|
|
try {
|
|
|
|
|
await axios.get(
|
|
|
|
|
"http://localhost:8080/api/v1/collections/users/me"
|
|
|
|
|
);
|
|
|
|
|
setIsLogged(true);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
setIsLogged(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
void checkUser();
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
//This reducer handles adding and selecting files.
|
|
|
|
|
//I'm passing in initial state "{files: []}" from fileReducer file.
|
|
|
|
|
//State can be changed by using dispatch function with object contaning right type and payload.
|
|
|
|
@ -35,7 +54,7 @@ const App: FC = () => {
|
|
|
|
|
const [formState, formDispatch] = useReducer(formReducer, fromInitialState);
|
|
|
|
|
|
|
|
|
|
//This hook handles pining location on the map
|
|
|
|
|
const [mapPin, setMapPin] = useState({ lat: 52.39663, lon: 16.89866 });
|
|
|
|
|
const [mapPin, setMapPin] = useState({ lat: 0, lon: 0 });
|
|
|
|
|
|
|
|
|
|
const handleSubmit = async (
|
|
|
|
|
event: FormEvent<HTMLFormElement> | MouseEvent<HTMLButtonElement>
|
|
|
|
@ -46,10 +65,12 @@ const App: FC = () => {
|
|
|
|
|
|
|
|
|
|
const handleUpload = (e: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
const files = e.target.files;
|
|
|
|
|
const readAndPreview = (file: any) => {
|
|
|
|
|
const readAndPreview = (file: FileType) => {
|
|
|
|
|
console.log(file);
|
|
|
|
|
// Make sure `file.name` matches our extensions criteria
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
|
|
|
if (/\.(jpe?g|png|svg)$/i.test(file.name)) {
|
|
|
|
|
let reader = new FileReader();
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.addEventListener(
|
|
|
|
|
"load",
|
|
|
|
|
function () {
|
|
|
|
@ -64,15 +85,16 @@ const App: FC = () => {
|
|
|
|
|
},
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
reader.readAsDataURL(file);
|
|
|
|
|
reader.readAsDataURL((file as unknown) as Blob);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if (files) {
|
|
|
|
|
[].forEach.call(files, readAndPreview);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
getAddress(mapPin).then((blob) =>
|
|
|
|
|
void getAddress(mapPin).then((blob) =>
|
|
|
|
|
formDispatch({
|
|
|
|
|
type: "CHANGE_FIELD",
|
|
|
|
|
payload: {
|
|
|
|
@ -82,6 +104,7 @@ const App: FC = () => {
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}, [mapPin]);
|
|
|
|
|
|
|
|
|
|
const MapComponent = () => {
|
|
|
|
|
useMapEvents({
|
|
|
|
|
click: async (e) => {
|
|
|
|
@ -90,7 +113,7 @@ const App: FC = () => {
|
|
|
|
|
});
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
// console.log(getAddress(mapPin));
|
|
|
|
|
|
|
|
|
|
const formMessage = `Rejestracja: ${formState.plate}\nMiejsce: ${
|
|
|
|
|
formState.address.road === undefined ? "" : formState.address.road
|
|
|
|
|
} ${
|
|
|
|
@ -108,7 +131,7 @@ const App: FC = () => {
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Nav />
|
|
|
|
|
<Nav isLogged={isLogged} />
|
|
|
|
|
<div className="container">
|
|
|
|
|
<section className="container__section">
|
|
|
|
|
<h2 className="container__section__title">Zdjęcia</h2>
|
|
|
|
@ -119,13 +142,15 @@ const App: FC = () => {
|
|
|
|
|
onClick={(e: MouseEvent) =>
|
|
|
|
|
fileDispatch({
|
|
|
|
|
type: "SELECT_FILE",
|
|
|
|
|
payload: { id: (e.target as any).id },
|
|
|
|
|
payload: {
|
|
|
|
|
id: (e.target as Element).id,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
className="section__photos__item"
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
src={file.img}
|
|
|
|
|
src={file.img as string}
|
|
|
|
|
id={file.id}
|
|
|
|
|
className={
|
|
|
|
|
file.selected ? "img--active" : "img"
|
|
|
|
@ -157,9 +182,11 @@ const App: FC = () => {
|
|
|
|
|
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
|
|
|
|
url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
|
|
|
|
|
/>
|
|
|
|
|
{mapPin.lat !== 0 ? (
|
|
|
|
|
<Marker
|
|
|
|
|
position={[mapPin.lat, mapPin.lon]}
|
|
|
|
|
></Marker>
|
|
|
|
|
) : null}
|
|
|
|
|
<MapComponent />
|
|
|
|
|
</MapContainer>
|
|
|
|
|
</div>
|
|
|
|
@ -328,4 +355,4 @@ const App: FC = () => {
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ReactDOM.render(<App />, document.getElementById("root"));
|
|
|
|
|
render(<App />, document.getElementById("root"));
|
|
|
|
|