kgroad-frontend2/src/widgets/ReportForm/ReportForm.tsx
Vladislav Khorev e0e2f5470d renamed folders
2024-02-14 08:04:02 +00:00

196 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import "./ReportForm.scss";
import "leaflet/dist/leaflet.css";
import Image from "next/image";
import {
MapContainer,
Marker,
Popup,
TileLayer,
useMapEvents,
} from "react-leaflet";
import clip from "./icons/clip.svg";
import arrow_right from "./icons/arrow-right.svg";
import pin_image from "./icons/pin-image.svg";
import { ChangeEventHandler, useState } from "react";
import { Icon } from "leaflet";
import pin_icon from "./icons/pin_icon.svg";
import axios from "axios";
import { apiInstance } from "@/shared/config/apiConfig";
import { useSession } from "next-auth/react";
interface ILatLng {
lat: number;
lng: number;
}
const ReportForm = () => {
const session = useSession();
const [latLng, setLatLng] = useState<ILatLng[]>([]);
const [displayLatLng, setDisplayLatLng] = useState<string[]>([]);
const [images, setImages] = useState<File[]>([]);
const position = {
lat: 42.8746,
lng: 74.606,
};
const customIcon = new Icon({
iconUrl: pin_icon.src,
iconSize: [32, 32],
});
const handleImages: ChangeEventHandler<HTMLInputElement> = (e) => {
if (e.target.files) {
const getArrayFromObject = Array.from(e.target.files);
setImages(getArrayFromObject);
}
};
const deleteImage = (name: string) => {
setImages((prev) => prev.filter((img) => img.name !== name));
};
const createReport: React.MouseEventHandler<
HTMLFormElement
> = async (e) => {
e.preventDefault();
const Authorization = `Bearer ${session.data?.access_token}`;
const config = {
headers: {
Authorization,
},
};
const formData = new FormData(e.currentTarget);
images.forEach((image) => {
formData.append("image", image);
});
formData.append("latitude1", latLng[0].lat.toString());
formData.append("longitude1", latLng[0].lng.toString());
formData.append("latitude2", latLng[1].lat.toString());
formData.append("longitude2", latLng[1].lng.toString());
const res = await apiInstance.post(
"/report/create/",
formData,
config
);
console.log(res.status);
};
const MapPins = (e: any) => {
useMapEvents({
click(e) {
if (latLng.length < 2) {
setLatLng([...latLng, e.latlng]);
axios
.get(
`https://nominatim.openstreetmap.org/reverse?lat=${e.latlng.lat}&lon=${e.latlng.lng}&format=json`
)
.then((res) =>
setDisplayLatLng([
...displayLatLng,
res.data.display_name,
])
)
.catch((error) => console.log(error));
}
},
});
return latLng.map((l) => (
<Marker key={l.lat} icon={customIcon} position={l} />
));
};
return (
<form onSubmit={createReport} className="report-form">
<div className="report-form__input">
<label>Адрес</label>
<input
value={displayLatLng.join("; ")}
disabled
placeholder="Отметьте точки на карте"
type="text"
/>
</div>
<div className="report-form__map">
<MapContainer
center={position}
zoom={14}
scrollWheelZoom={false}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<MapPins />
</MapContainer>
<div className="report-form__info">
<h4>Как отметить участок дороги? </h4>
<Image src={pin_image} alt="Pin Image" />
<p>
Поставьте булавку и начните рисовать участок дороги{" "}
<span>
(он может состоять из любого количества ломаных линий)
</span>
</p>
<p>Чтобы удалить отрезок нажмите на точки повторно.</p>
</div>
</div>
<div className="report-form__input">
<label>Добавьте описание проблемы</label>
<textarea name="description" placeholder="Введите описание" />
</div>
<div className="report-form__add-images">
<label>Добавьте фотографии</label>
<p>
Загрузите до 5 фотографии, связанные с дорогой, которую Вы
хотите отметить. Фотографии помогут лучше понять проблему.
</p>
<label
className="report-form__upload"
htmlFor="report-form-upload"
>
<Image src={clip} alt="Paper Clip Icon" />
Прикрепить файл
<span>(до 5 МБ)</span>
</label>
<input
onChange={handleImages}
multiple
type="file"
id="report-form-upload"
/>
{images.length ? (
<div className="report-form__images">
{images.map((image) => (
<div key={image.name}>
<img
src={URL.createObjectURL(image)}
alt="Report Image"
/>
<button onClick={() => deleteImage(image.name)}>
удалить
</button>
</div>
))}
</div>
) : null}
</div>
<button type="submit">
Отправить на модерацию
<Image src={arrow_right} alt="Arrow Right Icon" />
</button>
</form>
);
};
export default ReportForm;