Skip to content

Commit

Permalink
chore: spec works
Browse files Browse the repository at this point in the history
  • Loading branch information
Sepehr-Sobhani committed Sep 19, 2024
1 parent 35347c1 commit 13fbf9f
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default async function ContactPage({
let userOperatorUsers: UserOperatorUser[] | { error: string } = [];

if (contactId) {
contactFormData = await getContact(contactId);
contactFormData = await getContact(contactId, `/contacts/${contactId}`);
if (contactFormData && "error" in contactFormData)
throw new Error("Failed to retrieve contact information");
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
"use client";

import {
createOperationRepresentativeSchema,
createOperationRepresentativeUiSchema,
newOperationRepresentativeSchema,
} from "apps/registration/app/data/jsonSchema/operationRegistration/operationRepresentative";
import {
OperationRepresentativeFormData,
OperationsContacts,
} from "apps/registration/app/components/operations/registration/types";
import { IChangeEvent } from "@rjsf/core";
import { createNestedFormData } from "@bciers/components/form/formDataUtils";
import { useState } from "react";
import { Button, Alert } from "@mui/material";
import { getContact } from "@bciers/actions/api";
import {
ContactFormData,
ContactRow,
} from "@/administration/app/components/contacts/types";
import FormBase, { FormPropsWithTheme } from "@bciers/components/form/FormBase";

interface FormState {
operation_representatives?: number[];
new_operation_representative: {
existing_contact_id: string;
[key: string]: any;
}[];
}

interface NewOperationRepresentativeFormProps
extends Omit<FormPropsWithTheme<any>, "schema" | "uiSchema"> {
existingOperationRepresentatives: OperationsContacts[];
contacts: ContactRow[];
}

const NewOperationRepresentativeForm: React.FC<
NewOperationRepresentativeFormProps
> = (props) => {
const {
formData,
setErrorReset,
existingOperationRepresentatives,
contacts,
} = props;

const [error, setError] = useState(undefined);
const [formState, setFormState] = useState(formData);
const [key, setKey] = useState(Math.random());
const [existingContactId, setExistingContactId] = useState("");
const [showSubmitButton, setShowSubmitButton] = useState(
existingOperationRepresentatives?.length === 0,
);

const handleSelectingContact = async (newSelectedContactId: string) => {
setExistingContactId(newSelectedContactId);
try {
const contactData: ContactFormData =
await getContact(newSelectedContactId);

const nestedOpRepFormData = createNestedFormData(
contactData,
newOperationRepresentativeSchema,
);
setFormState((prevState: FormState) => ({
...prevState,
new_operation_representative: [
{
existing_contact_id: newSelectedContactId,
...nestedOpRepFormData,
},
],
}));
} catch (err) {
setError("Failed to fetch contact data!" as any);
}
};

const handleClearingExistingContact = () => {
setExistingContactId("");
setFormState((prevState: FormState) => ({
...prevState,
new_operation_representative: [{}],
}));
setKey(Math.random()); // force re-render to clear the form
};

const handleChange = ({ formData: newFormData }: IChangeEvent) => {
// setShowSubmitButton((prev) => prev === false);

const newOperationRepresentative = newFormData.new_operation_representative;
const newSelectedContactId =
newOperationRepresentative[0]?.existing_contact_id;

if (newSelectedContactId && newSelectedContactId !== existingContactId)
handleSelectingContact(newSelectedContactId);
else if (
!newSelectedContactId &&
existingContactId &&
newOperationRepresentative[0] &&
Object.keys(newOperationRepresentative[0]).length > 1
)
handleClearingExistingContact();
};

const submitHandler = async (data: any) => {
// TODO: implement this
console.log("submitHandler data", data);
};

return (
<FormBase
key={key}
schema={createOperationRepresentativeSchema(
existingOperationRepresentatives,
contacts,
)}
uiSchema={createOperationRepresentativeUiSchema(
Boolean(existingContactId),
)}
onChange={handleChange}
onSubmit={submitHandler}
formData={formState}
setErrorReset={setErrorReset}
>
<div>
<div className="min-h-[48px] box-border">
{error && <Alert severity="error">{error}</Alert>}
</div>
{showSubmitButton && (
<Button className="mt-4" variant="outlined" type="submit">
Save Operation Representative
</Button>
)}
</div>
</FormBase>
);
};

export default NewOperationRepresentativeForm;
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
"use client";

import MultiStepBase from "@bciers/components/form/MultiStepBase";
import {
createOperationRepresentativeSchema,
newOperationRepresentativeSchema,
operationRepresentativeUiSchema,
} from "apps/registration/app/data/jsonSchema/operationRegistration/operationRepresentative";
import {
OperationRepresentativeFormData,
OperationRegistrationFormProps,
OperationsContacts,
} from "apps/registration/app/components/operations/registration/types";
import { actionHandler } from "@bciers/actions";
import { IChangeEvent } from "@rjsf/core";
import { createNestedFormData } from "@bciers/components/form/formDataUtils";
import { useCallback, useEffect, useState } from "react";
import { Button, Alert } from "@mui/material";
import { getContact } from "@bciers/actions/api";
import {
ContactFormData,
ContactRow,
} from "@/administration/app/components/contacts/types";
import { ContactRow } from "@/administration/app/components/contacts/types";
import { UUID } from "crypto";
import FormBase, { FormPropsWithTheme } from "@bciers/components/form/FormBase";
import NewOperationRepresentativeForm from "./NewOperationRepresentativeForm";

interface OperationRepresentativeFormProps {
operation: UUID;
Expand All @@ -33,116 +18,6 @@ interface OperationRepresentativeFormProps {
contacts: ContactRow[];
}

// TODO: fix the type here
const OpRepBeforeForm: React.FC<any> = (props) => {
const {
disabled,
formData,
omitExtraData,
formRef,
onChange,
onSubmit,
readonly,
setErrorReset,
schema,
uiSchema,
existingOperationRepresentatives,
contacts,
} = props;

const [error, setError] = useState(undefined);
const [formState, setFormState] = useState(formData);
const [currentContactId, setCurrentContactId] = useState("");
const [key, setKey] = useState(Math.random());
const [showSubmitButton, setShowSubmitButton] = useState(false);

// useEffect(() => {
// setShowSubmitButton(false);
// }, []);

const modifiedSchema = createOperationRepresentativeSchema(
existingOperationRepresentatives,
contacts,
);

const handleSelectingContact = useCallback(
async (newSelectedContactId: string) => {
// TODO: disable first name, last name and email for updating existing contact
try {
const contactData: ContactFormData =
await getContact(newSelectedContactId);

// const nestedOpRepFormData = createNestedFormData(
// contactData,
// newOperationRepresentativeSchema,
// );

// setFormState((prevState) => ({
// ...prevState,
// // existing_contact_id: newSelectedContactId,
// ...nestedOpRepFormData,
// }));
} catch (err) {
setError("Failed to fetch contact data!" as any);
}
},
[],
);

// const handleClearingExistingContact = useCallback(() => {
// setFormState((prevState) => ({
// operation_representatives: prevState.operation_representatives,
// }));
// setKey(Math.random());
// }, []);

const handleChange = (e: IChangeEvent) => {
const { formData: newFormData } = e;
// setShowSubmitButton(true);
const newSelectedContactId =
newFormData.new_operation_representative[0]?.existing_contact_id || "";

if (newSelectedContactId && newSelectedContactId !== currentContactId) {
// setCurrentContactId(newSelectedContactId);
handleSelectingContact(newSelectedContactId);
}
// else if (!newSelectedContactId) {
// setSelectedContactId("");
// handleClearingExistingContact();
// }
};
const submitHandler = async (data: any) => {
// TODO: implement this
console.log("submitHandler data", data);
};

return (
<FormBase
key={key}
schema={modifiedSchema}
className="flex flex-col flex-grow"
uiSchema={operationRepresentativeUiSchema}
// disabled={isDisabled}
// readonly={isDisabled}
onChange={handleChange}
onSubmit={submitHandler}
formData={formState}
setErrorReset={setErrorReset}
>
<div>
<div className="min-h-[48px] box-border">
{error && <Alert severity="error">{error}</Alert>}
</div>
{showSubmitButton && (
<Button className="mt-4" variant="outlined" type="submit">
Save Operation Representative
</Button>
)}
</div>
</FormBase>
);
};

const OperationRepresentativeForm = ({
formData,
operation,
Expand All @@ -167,7 +42,7 @@ const OperationRepresentativeForm = ({
submitButtonText="Continue"
submitButtonDisabled={!hasExistingOperationReps}
beforeForm={
<OpRepBeforeForm
<NewOperationRepresentativeForm
formData={formData}
existingOperationRepresentatives={existingOperationRepresentatives}
contacts={contacts}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,34 @@ export const operationRepresentativeUiSchema: UiSchema = {
},
},
};

export const createOperationRepresentativeUiSchema = (
existingContact: boolean = false,
) => {
// disable first name, last name and email for updating existing contact
if (existingContact)
return {
...operationRepresentativeUiSchema,
new_operation_representative: {
...operationRepresentativeUiSchema.new_operation_representative,
items: {
...operationRepresentativeUiSchema.new_operation_representative.items,
section1: {
...operationRepresentativeUiSchema.new_operation_representative
.items.section1,
"ui:disabled": true,
},
section3: {
...operationRepresentativeUiSchema.new_operation_representative
.items.section3,
email: {
...operationRepresentativeUiSchema.new_operation_representative
.items.section3.email,
"ui:disabled": true,
},
},
},
},
};
else return operationRepresentativeUiSchema;
};
7 changes: 5 additions & 2 deletions bciers/libs/actions/src/api/getContact.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { actionHandler } from "@bciers/actions";

// 🛠️ Function to fetch a contact by id
export default async function getContact(id: string) {
export default async function getContact(
id: string,
pathToRevalidate: string = "",
) {
try {
return await actionHandler(
`registration/contacts/${id}`,
"GET",
`/contacts/${id}`,
pathToRevalidate,
);
} catch (error) {
// Handle the error here or rethrow it to handle it at a higher level
Expand Down

0 comments on commit 13fbf9f

Please sign in to comment.