Files
mwitnessing/components/location/LocationForm.js
Dobromir Popov ffcfb6b15c UI changes;
availability form prettify
2024-03-02 22:49:11 +02:00

273 lines
9.6 KiB
JavaScript

import axiosInstance from '../../src/axiosSecure';
import { useEffect, useState, useRef } from "react";
import { useRouter } from "next/router";
import toast from "react-hot-toast";
import Link from "next/link";
import DayOfWeek from "../DayOfWeek";
import TextEditor from "../TextEditor";
import FileUploadWithPreview from 'components/FileUploadWithPreview ';
import ProtectedRoute, { serverSideAuth } from "../..//components/protectedRoute";
import { UserRole } from "@prisma/client";
const common = require('src/helpers/common');
// ------------------ LocationForm ------------------
// This component is used to create and edit locations
// location model:
// model Location {
// id Int @id @default(autoincrement())
// name String
// address String
// isactive Boolean @default(true)
// content String? @db.Text
// cartEvents CartEvent[]
// reports Report[]
// backupLocationId Int?
// backupLocation Location? @relation("BackupLocation", fields: [backupLocationId], references: [id])
// BackupForLocations Location[] @relation("BackupLocation")
// }
export default function LocationForm() {
const [uploadedImages, setUploadedImages] = useState([]);
const [isPreviewMode, setIsPreviewMode] = useState(false);
useEffect(() => {
const fetchUploadedImages = async () => {
try {
const response = await axiosInstance.get('/uploaded-images');
setUploadedImages(response.data.imageUrls);
} catch (error) {
console.error('Error fetching uploaded images:', error);
}
};
fetchUploadedImages();
}, []);
const quillRef = useRef(null);
const handleImageSelect = (e) => {
const imageUrl = e.target.value;
if (imageUrl && quillRef.current) {
const editor = quillRef.getQuill();
const range = editor.getSelection(true);
if (range) {
editor.insertEmbed(range.index, 'image', imageUrl);
}
}
};
const [content, setContent] = useState("");
const [location, set] = useState({
name: "",
address: "",
isactive: true,
});
// const [isEdit, setIsEdit] = useState(false);
const router = useRouter();
useEffect(() => {
const fetchLocation = async (id) => {
try {
console.log("fetching location " + router.query.id);
const { data } = await axiosInstance.get("/api/data/locations/" + id);
set(data);
setContent(data.content);
} catch (error) {
console.error(error);
}
};
if (router.query?.id) {
fetchLocation(parseInt(router.query.id.toString()));
}
console.log("called");
}, [router.query.id]);
const [locations, setLocations] = useState([]);
useEffect(() => {
const fetchLocations = async () => {
try {
console.log("fetching locations");
const { data } = await axiosInstance.get("/api/data/locations");
setLocations(data);
console.log(data);
} catch (error) {
console.error(error);
}
};
if (!locations.length) {
fetchLocations();
}
}, []);
const handleChange = ({ target }) => {
if (target.type === "checkbox") {
set({ ...location, [target.name]: target.checked });
} else if (target.type === "number") {
set({ ...location, [target.name]: parseInt(target.value) });
} else {
set({ ...location, [target.name]: target.value });
}
}
const handleSubmit = async (e) => {
e.preventDefault();
try {
const dataToSend = {
...location,
name: location.name.trim(),
content: content,
};
if (router.query?.id) { // UPDATE
//connect backup location
delete dataToSend.id;
dataToSend.backupLocationId = parseInt(dataToSend.backupLocationId);
// dataToSend.backupLocation = { connect: { id: location.backupLocationId } };
// delete dataToSend.backupLocationId;
await axiosInstance.put("/api/data/locations/" + router.query.id, {
...dataToSend,
});
toast.success("Task Updated", {
position: "bottom-center",
});
} else { // CREATE
await axiosInstance.post("/api/data/locations", dataToSend);
toast.success("Task Saved", {
position: "bottom-center",
});
}
router.push("/cart/locations");
} catch (error) {
//toast.error(error.response.data.message);
}
};
return (
<>
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage="">
<div className="w-full max-lg">
<form className="bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4" onSubmit={handleSubmit} >
<div className="mb-4">
<label className="label" htmlFor="name">Location Name</label>
<input className="textbox" placeholder="name" id="name" name="name" onChange={handleChange} value={location.name} autoComplete="off" />
</div>
{/* Location.address */}
<div className="mb-4">
<label className="label" htmlFor="address"> Address</label>
<input className="textbox"
placeholder="address" id="address" name="address" onChange={handleChange} value={location.address} autoComplete="off" />
</div>
{/* UI for Location.isactive */}
<div className="mb-4">
<div className="form-check">
<input className="checkbox form-input" type="checkbox" id="isactive" name="isactive" onChange={handleChange} checked={location.isactive} autoComplete="off" />
<label className="label" htmlFor="isactive">Активна</label>
</div>
</div>
{/* backupLocation */}
<div className="mb-4">
<label className="label" htmlFor="backupLocation">При дъжд и лошо време</label>
{locations && (
<select name="backupLocationId" id="backupLocationId" onChange={handleChange} value={location.backupLocationId} placeholder="Избери локация...">
<option>Избери локация...</option>
{locations.map((loc) => (
<option key={loc.id} value={loc.id} type="number">{loc.name}</option>
))}
</select>
)}
</div>
{/* Location.content */}
<div className="mb-4">
{/* <select onChange={handleImageSelect}>
<option>Select an image</option>
{uploadedImages.map((imageUrl, index) => (
<option key={index} value={imageUrl}>{imageUrl}</option>
))}
</select> */}
{router.query.id && (
<>
<div className="flex space-x-4">
<FileUploadWithPreview
name="picture1"
label="Снимка 1"
value={location.picture1}
prefix={`location-${router.query.id}-picture1`}
onUpload={(name, imageUrl) => {
console.log('Uploaded image URL:', imageUrl);
set(location => ({ ...location, [name]: imageUrl }));
}}
/>
<FileUploadWithPreview
name="picture2"
label="Снимка 2"
value={location.picture2}
prefix={`location-${router.query.id}-picture2`}
onUpload={(name, imageUrl) => {
console.log('Uploaded image URL:', imageUrl);
set(location => ({ ...location, [name]: imageUrl }));
}}
/>
<FileUploadWithPreview
name="picture3"
label="Снимка 3"
value={location.picture3}
prefix={`location-${router.query.id}-picture3`}
onUpload={(name, imageUrl) => {
console.log('Uploaded image URL:', imageUrl);
set(location => ({ ...location, [name]: imageUrl }));
}}
/>
</div>
<label className="label" htmlFor="content">Content</label>
<TextEditor
ref={quillRef}
value={content}
onChange={setContent}
placeholder="Описание на локацията. Снимки"
prefix={`location-${router.query.id}`} />
</>)}
</div>
<div className="panel-actions pt-12">
<Link href="/cart/locations" className="action-button"> Отмени </Link>
<button className="button bg-blue-500 hover:bg-blue-700 focus:outline-none focus:shadow-outline" type="submit">
{router.query?.id ? "Обнови" : "Запази"}
</button>
</div>
</form>
</div>
<button className='button' onClick={() => setIsPreviewMode(!isPreviewMode)}>
{isPreviewMode ? 'Скрий прегледа' : 'Преглед'}
</button>
</ProtectedRoute>
<ProtectedRoute allowedRoles={[UserRole.USER]} deniedMessage=" " bypass={isPreviewMode}>
<label className="label" htmlFor="backupLocation">При дъжд и лошо време</label>
{location.name}
{location.address}
{location.backupLocationName}
<div className="border-2 border-blue-500 p-5 my-5 rounded-lg" dangerouslySetInnerHTML={{ __html: content }}></div>
</ProtectedRoute>
</>
);
}