322 lines
14 KiB
JavaScript
322 lines
14 KiB
JavaScript
// import axios from "axios";
|
||
import React, { 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 { monthNamesBG, GetTimeFormat, GetDateFormat } from "../../src/helpers/const"
|
||
import PublisherSearchBox from './PublisherSearchBox';
|
||
import AvailabilityList from "../availability/AvailabilityList";
|
||
import ShiftsList from "../publisher/ShiftsList.tsx";
|
||
import common from "../../src/helpers/common";
|
||
|
||
import ProtectedRoute from '../../components/protectedRoute';
|
||
import { UserRole } from "@prisma/client";
|
||
|
||
// 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();
|
||
console.log("init PublisherForm: ");
|
||
const urls = {
|
||
apiUrl: "/api/data/publishers/",
|
||
indexUrl: "/cart/publishers"
|
||
}
|
||
|
||
const [helpers, setHelper] = useState(null);
|
||
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" 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" name="lastName" value={publisher.lastName} onChange={handleChange} className="textbox" placeholder="Last Name" autoFocus />
|
||
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" ">
|
||
<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>
|
||
</ProtectedRoute>
|
||
</div>
|
||
{/* //desiredShiftsPerMonth */}
|
||
<div className="mb-4">
|
||
<label className="label" htmlFor="desiredShiftsPerMonth">Желани смeни на месец</label>
|
||
<input type="number" name="desiredShiftsPerMonth" value={publisher.desiredShiftsPerMonth} onChange={handleChange} className="textbox" placeholder="desiredShiftsPerMonth" autoFocus />
|
||
</div>
|
||
<div className="mb-4">
|
||
<label className="label" htmlFor="email">Имейл</label>
|
||
<input type="text" name="email" value={publisher.email} onChange={handleChange} className="textbox" placeholder="Email" autoFocus />
|
||
</div>
|
||
<div className="mb-4">
|
||
<label className="label" htmlFor="phone">Телефон</label>
|
||
<input type="text" name="phone" value={publisher.phone} onChange={handleChange} className="textbox" placeholder="Phone" autoFocus />
|
||
</div>
|
||
<div className="mb-4">
|
||
<label className="label" htmlFor="parentPublisher">
|
||
Семейство (избери главата на семейството)
|
||
</label>
|
||
<PublisherSearchBox 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 className="mb-4">
|
||
<label className="label" htmlFor="type">Тип</label>
|
||
<select 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="town">Град</label>
|
||
<input type="text" name="town" value={publisher.town} onChange={handleChange} className="textbox" placeholder="Град" autoFocus />
|
||
</div>
|
||
<div className="mb-4">
|
||
<label className="label" htmlFor="comments">Коментари</label>
|
||
<input type="text" name="comments" value={publisher.comments} onChange={handleChange} className="textbox" placeholder="Коментари" autoFocus />
|
||
</div>
|
||
</div>
|
||
<ProtectedRoute allowedRoles={[UserRole.ADMIN]} deniedMessage=" ">
|
||
<div className="mb-4">
|
||
<label className="label" htmlFor="age">Възраст</label>
|
||
<input type="number" 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>
|
||
<a href="https://t.me/mwhitnessing_bot" className="inline-flex items-center ml-4" target="_blank">
|
||
<img src="/content/icons/telegram-svgrepo-com.svg" alt="Телеграм" width="32" height="32" className="align-middle" />
|
||
<span className="align-middle">Телеграм</span>
|
||
</a>
|
||
</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={handleDelete}>
|
||
Delete
|
||
</button>
|
||
<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 >
|
||
</>
|
||
)
|
||
};
|
||
|
||
|