Files
mwitnessing/components/publisher/PublisherForm.js
2024-06-28 19:47:59 +03:00

405 lines
19 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 { useSession } from "next-auth/react"
// import { Tabs, List } from 'tw-elements'
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 { data: session } = useSession()
const [congregations, setCongregations] = useState([]);
const urls = {
apiUrl: "/api/data/publishers/",
congregationsUrl: "/api/data/congregations",
indexUrl: session?.user?.role == UserRole.ADMIN ? "/cart/publishers" : "/dash"
}
console.log("urls.indexUrl: " + urls.indexUrl);
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);
const response = await axiosInstance.get(urls.congregationsUrl);
setCongregations(response.data);
}
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, congregationId, ...rest } = publisher;
// Set the familyHead relation based on the selected head
const familyHeadRelation = familyHeadId ? { connect: { id: familyHeadId } } : null;
const userRel = userId ? { connect: { id: userId } } : null;
const congregationRel = congregationId ? { connect: { id: parseInt(congregationId) } } : null;
// Return the new state without familyHeadId and with the correct familyHead relation
rest = {
...rest,
...(familyHeadRelation ? { familyHead: familyHeadRelation } : {}),
...(userRel ? { user: userRel } : {}),
...(congregationRel ? { congregation: congregationRel } : {}),
};
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, rest);
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>
{/* language preference */}
<div className="mb-4">
<label className="label" htmlFor="locale">Език (в разработка)</label>
<select id="locale" name="locale" value={publisher.locale} onChange={handleChange} className="select textbox" placeholder="Език" autoFocus >
<option value="bg" >Български</option>
<option value="en">English</option>
<option value="ru">Руски</option>
</select>
</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">
<label className="label" htmlFor="congregationId">Сбор</label>
<select id="congregationId" name="congregationId" value={publisher.congregationId} onChange={handleChange} className="select textbox" placeholder="Община" autoFocus >
<option value="">Избери сбор</option>
{congregations.map((congregation) => (
<option key={congregation.id} value={congregation.id}>
{congregation.name}
</option>
))}
</select>
</div>
{/* notifications */}
<div className="mb-6 p-4 border border-gray-300 rounded-lg">
<fieldset>
<legend className="text-lg font-medium mb-2">Известия</legend>
{/* Email notifications group */}
<div className="mb-4">
<h3 className="text-md font-semibold mb-2">Известия по имейл</h3>
<div className="space-y-4">
<div className="form-check">
<input
className="checkbox cursor-not-allowed opacity-50"
type="checkbox"
id="isSubscribedToCoverMeMandatory"
name="isSubscribedToCoverMeMandatory"
onChange={handleChange} // This will not fire due to being disabled, but kept for consistency
checked={true} // Always checked
disabled={true} // User cannot change this field
autoComplete="off" />
<label className="label cursor-not-allowed opacity-50" htmlFor="isSubscribedToCoverMeMandatory">
Имейли за заместване които отговарят на моите предпочитания
</label>
</div>
<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>
</div>
<div className="form-check">
<input
className="checkbox"
type="checkbox"
id="isSubscribedToReminders"
name="isSubscribedToReminders"
onChange={handleChange}
checked={publisher.isSubscribedToReminders}
autoComplete="off" />
<label className="label" htmlFor="isSubscribedToReminders">
Други напомняния
</label>
</div>
</div>
</div>
{/* In-App notifications group */}
<div className="mb-4">
<h3 className="text-md font-semibold mb-2">Известия в приложението</h3>
<PwaManager userId={publisher.userId || session.user.id} />
</div>
</fieldset>
</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">
{/* prompt to install PWA */}
<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 ? "Запази" : "Създай"}
</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 >
</>
)
};