472 lines
15 KiB
JavaScript
472 lines
15 KiB
JavaScript
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import React, { useMemo, useState } from "react";
|
|
import { FormProvider, useForm } from "react-hook-form";
|
|
import {
|
|
defaultOrganizationValues,
|
|
organizationSchema,
|
|
} from "./OrganizationSchema";
|
|
import Modal from "../common/Modal";
|
|
import {
|
|
useCreateOrganization,
|
|
useOrganizationBySPRID,
|
|
useOrganizationModal,
|
|
useOrganizationsList,
|
|
} from "../../hooks/useOrganization";
|
|
import Label from "../common/Label";
|
|
import SelectMultiple from "../common/SelectMultiple";
|
|
import { useServices } from "../../hooks/masterHook/useMaster";
|
|
|
|
const ManageOrganization = ({
|
|
projectOrganizations = ["ee"],
|
|
organizationId = null,
|
|
}) => {
|
|
const [step, setStep] = useState(1);
|
|
const orgModal = useOrganizationModal();
|
|
const { data: masterService, isLoading } = useServices();
|
|
const [searchText, setSearchText] = useState();
|
|
const [SPRID, setSPRID] = useState("");
|
|
const { data: orgList, isLoading: orgLoading } = useOrganizationsList(
|
|
20,
|
|
1,
|
|
true,
|
|
searchText
|
|
);
|
|
const { data: OrgListbySPRID, isLoading: isLoadingBySPRID } =
|
|
useOrganizationBySPRID(SPRID);
|
|
const [Organization, setOrganization] = useState({});
|
|
|
|
const method = useForm({
|
|
resolver: zodResolver(organizationSchema),
|
|
defaultValues: defaultOrganizationValues,
|
|
});
|
|
console.log(masterService);
|
|
|
|
const {
|
|
handleSubmit,
|
|
register,
|
|
reset,
|
|
formState: { errors },
|
|
} = method;
|
|
|
|
const { mutate: CreateOrganization, isPending } = useCreateOrganization(
|
|
() => {
|
|
reset(defaultOrganizationValues);
|
|
orgModal.onClose();
|
|
setStep(1); // reset to first step
|
|
}
|
|
);
|
|
|
|
const onSubmit = (OrgPayload) => {
|
|
CreateOrganization(OrgPayload);
|
|
};
|
|
|
|
const RenderTitle = useMemo(() => {
|
|
if (organizationId) {
|
|
return "Update Organization";
|
|
}
|
|
|
|
if (step === 1) {
|
|
return projectOrganizations && projectOrganizations !== null
|
|
? "Add Organization"
|
|
: "Find Organization";
|
|
}
|
|
|
|
if (step === 2) {
|
|
return "Organization Details";
|
|
}
|
|
|
|
if (step === 3) {
|
|
return "Create Organization";
|
|
}
|
|
|
|
return "Manage Organization"; // fallback
|
|
}, [step, orgModal?.orgData, organizationId]);
|
|
|
|
const contentBody = (
|
|
<div>
|
|
{/* ---------- STEP 1: Service Provider- Form Own Tenant list ---------- */}
|
|
{step === 1 && (
|
|
<div className="d-block">
|
|
<div className="text-start mb-1">
|
|
<Label className="text-secondary">Find Organization</Label>
|
|
<input
|
|
type="text"
|
|
value={SPRID}
|
|
className="form-control form-control-sm w-auto"
|
|
placeholder="Enter Organization"
|
|
aria-describedby="search-label"
|
|
/>
|
|
</div>
|
|
|
|
<div className="py-2 text-tiny text-center">
|
|
<div className="d-flex flex-column gap-2 border-0 bg-none">
|
|
{orgList?.map((org) => (
|
|
<div className="list-group-item list-group-item-action d-flex align-items-center cursor-pointer border-0">
|
|
<div className="d-flex align-items-center justify-content-center me-3">
|
|
<i className="bx bx-building-house bx-md text-primary"></i>
|
|
</div>
|
|
|
|
<div className="w-100">
|
|
<div className="d-flex justify-content-between">
|
|
<div className="user-info text-start">
|
|
<h6 className="mb-1 fw-normal">{org.name}</h6>
|
|
<small className="text-body-secondary">
|
|
{org.contactPerson}
|
|
</small>
|
|
<div className="user-status">
|
|
<small>In Meeting</small>
|
|
</div>
|
|
</div>
|
|
<div className="add-btn">
|
|
<button
|
|
className="btn btn-primary btn-xs"
|
|
onClick={() => {
|
|
setOrganization(org);
|
|
setStep(3);
|
|
}}
|
|
>
|
|
Add
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{orgModal.orgData && (
|
|
<p className="text-secondary">
|
|
Don't have required organization, Please find using{" "}
|
|
<span
|
|
className="text-mutes cursor-pointer text-decoration-underline"
|
|
onClick={() => setStep(2)}
|
|
>
|
|
SPRID
|
|
</span>
|
|
</p>
|
|
)}
|
|
</div>
|
|
|
|
<div
|
|
className={`d-flex ${
|
|
projectOrganizations
|
|
? "justify-content-end"
|
|
: "justify-content-between"
|
|
} text-secondary mt-3`}
|
|
>
|
|
{!projectOrganizations && (
|
|
<button
|
|
type="button"
|
|
className="btn btn-xs btn-outline-secondary"
|
|
onClick={() => setStep(1)}
|
|
>
|
|
<i className="bx bx-left-arrow-alt"></i> Back
|
|
</button>
|
|
)}
|
|
|
|
<button
|
|
type="button"
|
|
className="btn btn-xs btn-secondary"
|
|
onClick={() => setStep(4)}
|
|
>
|
|
<i className="bx bx-plus-circle me-2"></i>
|
|
Add New Organization
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* ---------- STEP 1: Service Provider From Own Other Tenant ---------- */}
|
|
{step === 2 && (
|
|
<div className="d-block">
|
|
<div className="text-start mb-1">
|
|
<Label className="text-secondary">Find Organization</Label>
|
|
<input
|
|
type="text"
|
|
className="form-control form-control-sm w-auto"
|
|
placeholder="Enter Servicee Provider Id"
|
|
aria-describedby="search-label"
|
|
/>
|
|
</div>
|
|
{/* ======== org list ======*/}
|
|
<div className="d-flex flex-column gap-2 border-0 bg-none">
|
|
{OrgListbySPRID?.map((org) => (
|
|
<div className="list-group-item list-group-item-action d-flex align-items-center cursor-pointer border-0">
|
|
<div className="d-flex align-items-center justify-content-center me-3">
|
|
<i className="bx bx-building-house bx-md text-primary"></i>
|
|
</div>
|
|
|
|
<div className="w-100">
|
|
<div className="d-flex justify-content-between">
|
|
<div className="user-info text-start">
|
|
<h6 className="mb-1 fw-normal">Icing sweet gummies</h6>
|
|
<small className="text-body-secondary">15 minutes</small>
|
|
<div className="user-status">
|
|
<small>In Meeting</small>
|
|
</div>
|
|
</div>
|
|
<div className="add-btn">
|
|
<button
|
|
className="btn btn-primary btn-xs"
|
|
onClick={() => setStep(3)}
|
|
>
|
|
Add
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="d-flex justify-content-between gap-2 mt-3">
|
|
<button
|
|
type="button"
|
|
className="btn btn-xs btn-outline-secondary"
|
|
onClick={() => setStep(1)}
|
|
>
|
|
<i className="bx bx-left-arrow-alt"></i> Back
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className="btn btn-xs btn-secondary"
|
|
onClick={() => setStep(4)}
|
|
>
|
|
<i className="bx bx-plus-circle me-2"></i>
|
|
Add New Organization
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* ---------- STEP 2: Existing Organization Details ---------- */}
|
|
{step === 3 && (
|
|
<div className="row text-black mb-3">
|
|
<div className="col-12 mb-3"></div>
|
|
<div className="text-start mb-2">
|
|
<div className="text-muted">{Organization.name}</div>
|
|
</div>
|
|
{/* Row 1 */}
|
|
<div className="col-md-6 mb-3">
|
|
<div className="d-flex">
|
|
<label
|
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
|
style={{ minWidth: "130px" }}
|
|
>
|
|
Constact Person :
|
|
</label>
|
|
<div className="text-muted">{Organization.name}</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-md-6 mb-3">
|
|
<div className="d-flex">
|
|
<label
|
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
|
style={{ minWidth: "130px" }}
|
|
>
|
|
Contact Number :
|
|
</label>
|
|
<div className="text-muted">{Organization.contactNumber}</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-md-6 mb-3">
|
|
<div className="d-flex">
|
|
<label
|
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
|
style={{ minWidth: "130px" }}
|
|
>
|
|
Email Address :
|
|
</label>
|
|
<div className="text-muted">{Organization.email}</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-12 mb-3">
|
|
<div className="d-flex">
|
|
<label
|
|
className="form-label me-2 mb-0 fw-semibold text-start text-wrap"
|
|
style={{ maxWidth: "130px" }}
|
|
>
|
|
Service provider Id (SPRID) :
|
|
</label>
|
|
<div className="text-muted">{Organization.sprid}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="col-12 mb-3">
|
|
<div className="d-flex">
|
|
<label
|
|
className="form-label me-1 mb-0 fw-semibold text-start"
|
|
style={{ minWidth: "130px" }}
|
|
>
|
|
Address :
|
|
</label>
|
|
<div className="text-muted text-start">
|
|
{Organization.address}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="text-black text-start">
|
|
<div className="mb-2">
|
|
<Label className="fs-6">Add Services</Label>
|
|
<ul className="list-group list-group-flush">
|
|
{masterService.data &&
|
|
masterService.data?.map((serv) => (
|
|
<li className="list-group-item py-1">
|
|
<input
|
|
type="checkbox"
|
|
className="form-check-input me-2"
|
|
/>
|
|
{serv.name}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
|
|
<div className="d-flex justify-content-between mt-3">
|
|
<button
|
|
type="button"
|
|
className="btn btn-xs btn-outline-secondary"
|
|
onClick={() => setStep(1)}
|
|
>
|
|
<i className="bx bx-left-arrow-alt"></i> Back
|
|
</button>
|
|
<button type="button" className="btn btn-sm btn-primary">
|
|
Add
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* ---------- STEP 3: Add New Organization ---------- */}
|
|
{step === 4 && (
|
|
<FormProvider {...method}>
|
|
<form className="form" onSubmit={handleSubmit(onSubmit)}>
|
|
<div className="mb-1 text-start">
|
|
<Label htmlFor="name" required>
|
|
Organization Name
|
|
</Label>
|
|
<input
|
|
className="form-control form-control-sm"
|
|
{...register("name")}
|
|
/>
|
|
{errors.name && (
|
|
<span className="danger-text">{errors.name.message}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="mb-1 text-start">
|
|
<Label htmlFor="contactPerson" required>
|
|
Contact Person
|
|
</Label>
|
|
<input
|
|
className="form-control form-control-sm"
|
|
{...register("contactPerson")}
|
|
/>
|
|
{errors.contactPerson && (
|
|
<span className="danger-text">
|
|
{errors.contactPerson.message}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="mb-1 text-start">
|
|
<Label htmlFor="contactNumber" required>
|
|
Contact Number
|
|
</Label>
|
|
<input
|
|
className="form-control form-control-sm"
|
|
{...register("contactNumber")}
|
|
/>
|
|
{errors.contactNumber && (
|
|
<span className="danger-text">
|
|
{errors.contactNumber.message}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="mb-1 text-start">
|
|
<Label htmlFor="email" required>
|
|
Email Address
|
|
</Label>
|
|
<input
|
|
className="form-control form-control-sm"
|
|
{...register("email")}
|
|
/>
|
|
{errors.email && (
|
|
<span className="danger-text">{errors.email.message}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="mb-1 text-start">
|
|
<SelectMultiple
|
|
name="serviceIds"
|
|
label="Services"
|
|
required
|
|
valueKey="id"
|
|
options={services?.data || []}
|
|
/>
|
|
{errors.serviceIds && (
|
|
<span className="danger-text">{errors.serviceIds.message}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="mb-1 text-start">
|
|
<Label htmlFor="address" required>
|
|
Address
|
|
</Label>
|
|
<textarea
|
|
className="form-control form-control-sm"
|
|
{...register("address")}
|
|
rows={2}
|
|
/>
|
|
{errors.address && (
|
|
<span className="danger-text">{errors.address.message}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="d-flex justify-content-between gap-2 my-2">
|
|
<button
|
|
type="button"
|
|
className="btn btn-sm btn-outline-secondary"
|
|
onClick={() => setStep(1)}
|
|
>
|
|
← Back
|
|
</button>
|
|
<div>
|
|
<button
|
|
type="button"
|
|
className="btn btn-sm btn-secondary me-2"
|
|
onClick={orgModal.onClose}
|
|
disabled={isPending || isLoading}
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
className="btn btn-sm btn-primary"
|
|
disabled={isPending || isLoading}
|
|
>
|
|
{isPending ? "Please Wait..." : "Submit"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</FormProvider>
|
|
)}
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<Modal
|
|
isOpen={orgModal.isOpen}
|
|
onClose={orgModal.onClose}
|
|
title={RenderTitle}
|
|
body={contentBody}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default ManageOrganization;
|