Files
mwitnessing/components/publisher/PublisherForm.js
2024-04-30 13:16:44 +03:00

350 lines
16 KiB
JavaScript
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.

// import axios from "axios";
import React, { use, useEffect, useState } from "react";
import toast from "react-hot-toast";
import { useRouter } from "next/router";
import Link from "next/link";
import axiosInstance from '../../src/axiosSecure';
//import { getDate } from "date-fns";
import PwaManager from "../PwaManager";
import common from "../../src/helpers/common";
import ProtectedRoute from '../../components/protectedRoute';
import { monthNamesBG, GetTimeFormat, GetDateFormat } from "../../src/helpers/const"
import PublisherSearchBox from './PublisherSearchBox';
import AvailabilityList from "../availability/AvailabilityList";
import ShiftsList from "../publisher/ShiftsList.tsx";
import ConfirmationModal from "../ConfirmationModal";
import { UserRole } from "@prisma/client";
import { getSession } from "next-auth/react";
// import { Tabs, List } from 'tw-elements'
// model Publisher {
// id String @id @default(cuid())
// firstName String
// lastName String
// email String @unique
// phone String?
// isActive Boolean @default(true)
// isImported Boolean @default(false)
// age Int?
// availabilities Availability[]
// assignments Assignment[]
// emailVerified DateTime?
// accounts Account[]
// sessions Session[]
// role UserRole @default(USER)
// desiredShiftsPerMonth Int @default(4)
// isMale Boolean @default(true)
// isNameForeign Boolean @default(false)
// familyHeadId String? // Optional familyHeadId for each family member
// familyHead Publisher? @relation("FamilyMember", fields: [familyHeadId], references: [id])
// familyMembers Publisher[] @relation("FamilyMember")
// type PublisherType @default(Publisher)
// Town String?
// Comments String?
// }
Array.prototype.groupBy = function (prop) {
return this.reduce(function (groups, item) {
const val = item[prop]
groups[val] = groups[val] || []
groups[val].push(item)
return groups
}, {})
}
export default function PublisherForm({ item, me }) {
const router = useRouter();
const urls = {
apiUrl: "/api/data/publishers/",
indexUrl: "/dash"
}
const [helpers, setHelper] = useState(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const fetchModules = async () => {
const h = (await import("../../src/helpers/const.js")).default;
//console.log("fetchModules: " + JSON.stringify(h));
setHelper(h);
}
useEffect(() => {
fetchModules();
}, []);
const [publisher, set] = useState(item || {
isActive: true,
});
const handleChange = ({ target }) => {
if (target.type === "checkbox") {
set({ ...publisher, [target.name]: target.checked });
} else if (target.type === "number") {
set({ ...publisher, [target.name]: parseInt(target.value) });
} else {
set({ ...publisher, [target.name]: target.value });
}
if (item?.firstName) {
publisher.isMale = item.firstName && item.firstName.endsWith('а') ? false : true;
}
}
const handleParentSelection = (head) => {
//setSelectedParent(parent);
// Update the publisher state with the selected publisher's ID
console.log("handleParentSelection: " + JSON.stringify(head));
set({ ...publisher, familyHeadId: head.id });
// Create a new object excluding the familyHeadId property
};
const handleSubmit = async (e) => {
router.query.id = router.query.id || "";
console.log("handleSubmit: " + JSON.stringify(publisher));
console.log("urls.apiUrl + router.query.id: " + urls.apiUrl + router.query.id)
e.preventDefault();
//remove availabilities, assignments from publisher
publisher.availabilities = undefined;
publisher.assignments = undefined;
let { familyHeadId, userId, ...rest } = publisher;
// Set the familyHead relation based on the selected head
const familyHeadRelation = familyHeadId ? { connect: { id: familyHeadId } } : { disconnect: true };
const userRel = userId ? { connect: { id: userId } } : { disconnect: true };
// Return the new state without familyHeadId and with the correct familyHead relation
rest = {
...rest,
familyHead: familyHeadRelation,
user: userRel
};
try {
if (router.query?.id) {
await axiosInstance.put(urls.apiUrl + router.query.id, {
...rest,
});
toast.success("Task Updated", {
position: "bottom-center",
});
} else {
await axiosInstance.post(urls.apiUrl, publisher);
toast.success("Task Saved", {
position: "bottom-center",
});
}
router.push(urls.indexUrl);
} catch (error) {
console.log(JSON.stringify(error));
//toast.error(error.response.data.message);
}
};
const handleDelete = async (e) => {
e.preventDefault();
try {
//console.log("deleting publisher id = ", router.query.id, "; url=" + urls.apiUrl + router.query.id);
await axiosInstance.delete(urls.apiUrl + router.query.id);
toast.success("Записът изтрит", {
position: "bottom-center",
});
router.push(urls.indexUrl);
} catch (error) {
console.log(JSON.stringify(error));
toast.error(error.response.data.message);
}
};
let formTitle;
me = common.parseBool(me);
if (me) {
formTitle = "Моят профил / Настройки";
} else if (router.query?.id) {
formTitle = "Редактирай вестител"; // "Edit Publisher"
} else {
formTitle = "Създай вестител"; // "Create Publisher"
}
return (
<>
<div className="flex flex-col">
<h3 className="text-2xl font-semibold mt-6 mb-4">{formTitle}</h3>
<div className="h-4"></div>
<div className="flex flex-row">
<form className="form"
onSubmit={handleSubmit}>
<div className="mb-4">
<label className="label" htmlFor="firstName">Име</label>
<input type="text" id="firstName" name="firstName" value={publisher.firstName} onChange={handleChange} className="textbox" placeholder="First Name" autoFocus />
</div>
<div className="mb-4">
<label className="label" htmlFor="lastName">Фамилия</label>
<input type="text" id="lastName" name="lastName" value={publisher.lastName} onChange={handleChange} className="textbox" placeholder="Last Name" autoFocus />
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" ">
<div className="border border-blue-500 border-solid p-2">
<div className="form-check">
<input className="checkbox" type="checkbox" value={publisher.isNameForeign} id="isNameForeign" name="isNameForeign" onChange={handleChange} checked={publisher.isNameForeign} autoComplete="off" />
<label className="label" htmlFor="isNameForeign">
Чуждестранна фамилия</label>
</div>
</div>
</ProtectedRoute>
</div>
{/* //desiredShiftsPerMonth */}
<div className="mb-4">
<label className="label" htmlFor="desiredShiftsPerMonth">Желани смeни на месец</label>
<input type="number" id="desiredShiftsPerMonth" name="desiredShiftsPerMonth" value={publisher.desiredShiftsPerMonth} onChange={handleChange} className="textbox" placeholder="desiredShiftsPerMonth" autoFocus />
</div> <div className="mb-4">
<label className="label" htmlFor="email">Имейл</label>
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage={publisher.email} className="">
<div className="border border-blue-500 border-solid p-2">
<input type="text" id="email" name="email" value={publisher.email} onChange={handleChange} className="textbox" placeholder="Email" autoFocus />
</div>
</ProtectedRoute>
</div>
<div className="mb-4">
<label className="label" htmlFor="phone">Телефон</label>
<input type="text" id="phone" name="phone" value={publisher.phone} onChange={handleChange} className="textbox" placeholder="Phone" autoFocus />
</div>
<div className="mb-4">
<label className="label" htmlFor="familyHeadId">
Семейство (избери главата на семейството)
</label>
<PublisherSearchBox id="familyHeadId" selectedId={publisher.familyHeadId} onChange={handleParentSelection} />
</div>
<div className="mb-4">
<div className="flex items-center space-x-4">
<div className="form-check">
<input className="radio" type="radio" id="male" name="isMale"
onChange={() => handleChange({ target: { name: "isMale", value: true } })}
checked={publisher.isMale}
/>
<label className="label" htmlFor="male">
Мъж
</label>
</div>
<div className="form-check">
<input className="radio" type="radio" id="female" name="isMale"
onChange={() => handleChange({ target: { name: "isMale", value: false } })}
checked={!publisher.isMale}
/>
<label className="label" htmlFor="female">
Жена
</label>
</div>
</div>
</div>
<div className="mb-4">
<label className="label" htmlFor="town">Град</label>
<input type="text" id="town" name="town" value={publisher.town} onChange={handleChange} className="textbox" placeholder="Град" autoFocus />
</div>
<div className="mb-4">
{/* notifications */}
<div className="form-check">
<input className="checkbox" type="checkbox" id="isSubscribedToCoverMe" name="isSubscribedToCoverMe" onChange={handleChange} checked={publisher.isSubscribedToCoverMe} autoComplete="off" />
<label className="label" htmlFor="isSubscribedToCoverMe">Абониран за имейли за заместване</label>
<input className="checkbox" type="checkbox" id="isSubscribedToReminders" name="isSubscribedToReminders" onChange={handleChange} checked={publisher.isSubscribedToReminders} autoComplete="off" />
<label className="label" htmlFor="isSubscribedToReminders">Абониран за напомняния (имейл)</label>
{/* prompt to install PWA */}
</div>
</div>
{/* button to install PWA */}
{/* <div className="mb-4">
<button className="button bg-blue-500 hover:bg-blue-700 focus:outline-none focus:shadow-outline" type="button" onClick={() => window.installPWA()}>
Инсталирай приложението
</div> */}
{/* ADMINISTRATORS ONLY */}
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" " className="">
<div className="border border-blue-500 border-solid p-2">
<PwaManager />
<div className="mb-4">
<label className="label" htmlFor="type">Тип</label>
<select id="type" name="type" value={publisher.type} onChange={handleChange} className="textbox" placeholder="Type" autoFocus >
<option value="Publisher">Вестител</option>
<option value="Bethelite">Бетелит</option>
<option value="RegularPioneer">Редовен Пионер</option>
<option value="SpecialPioneer_Missionary">Специален Пионер/Мисионер</option>
{/* <option value="Missionary">Мисионер</option>
<option value="CircuitOverseer">Пътуваща служба</option> */}
</select>
</div>
<div className="mb-4">
<label className="label" htmlFor="comments">Коментари</label>
<input type="text" id="comments" name="comments" value={publisher.comments} onChange={handleChange} className="textbox" placeholder="Коментари" autoFocus />
</div>
<div className="mb-4">
<label className="label" htmlFor="age">Възраст</label>
<input type="number" id="age" name="age" value={publisher.age} onChange={handleChange} className="textbox" placeholder="Age" autoFocus />
</div>
<div className="mb-4">
<div className="form-check">
<input className="checkbox" type="checkbox" id="isActive" name="isActive" onChange={handleChange} checked={publisher.isActive} autoComplete="off" />
<label className="label" htmlFor="isActive">Активен</label>
<input className="checkbox" type="checkbox" id="isTrained" name="isTrained" onChange={handleChange} checked={publisher.isTrained} autoComplete="off" />
<label className="label" htmlFor="isTrained">Получил обучение</label>
<input className="checkbox disabled" type="checkbox" id="isImported" name="isImported" onChange={handleChange} checked={publisher.isImported} autoComplete="off" />
<label className="label " htmlFor="isImported">Импортиран от график</label>
</div>
</div>
<div className="mb-4">
<label className="label" htmlFor="role">Роля Потребител</label>
<select name="role" id="role" className="select" value={publisher.role} onChange={handleChange} >
{/* <option value='${UserRole.USER}'>Потребител</option> */}
<option value={`${UserRole.USER}`}>Потребител</option>
<option value={`${UserRole.EXTERNAL}`}>Външен</option>
<option value={`${UserRole.POWERUSER}`}>Организатор</option>
<option value={`${UserRole.ADMIN}`}>Администратор</option>
{/* Add other roles as needed */}
</select>
</div>
</div>
</ProtectedRoute>
{/* ---------------------------- Actions --------------------------------- */}
<div className="panel-actions">
<Link href={urls.indexUrl} className="action-button"> Отмени </Link>
{/* delete */}
<button className="button bg-red-500 hover:bg-red-700 focus:outline-none focus:shadow-outline" type="button" onClick={() => setIsModalOpen(true)}>
Изтрий
</button>
<ConfirmationModal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
onConfirm={handleDelete}
message="Сигурни ли сте, че искате да изтриете този профил? Това действие не може да бъде отменено."
/>
{/* save */}
<button className="button bg-blue-500 hover:bg-blue-700 focus:outline-none focus:shadow-outline" type="submit">
{router.query?.id ? "Update" : "Create"}
</button>
</div>
</form>
<div className="flex flex-col">
<div className="flex flex-row">
<div className="flex-col" id="shiftlist" >
<div className="">
<ShiftsList assignments={publisher.assignments} selectedtab={common.getCurrentYearMonth()} />
</div>
</div>
</div>
<div className="flex-1 p-5">
<AvailabilityList publisher={publisher} />
</div>
</div>
</div >
</div >
</>
)
};