From 4115455c6b13120fbabb2ebf7421a6bbda4d04b9 Mon Sep 17 00:00:00 2001 From: "ruth.castro" Date: Wed, 24 Apr 2024 22:09:59 -0600 Subject: [PATCH] feat-317: Add profile menu for applicants --- .../components/FormFields/SelectField.tsx | 10 +- app/core/layouts/Header.tsx | 36 +- app/routes/applicants.$applicantId._index.tsx | 19 +- .../applicationForm.$applicantId._index.tsx | 779 ++++++++++-------- 4 files changed, 476 insertions(+), 368 deletions(-) diff --git a/app/core/components/FormFields/SelectField.tsx b/app/core/components/FormFields/SelectField.tsx index 41bd47a1..4b521ae6 100644 --- a/app/core/components/FormFields/SelectField.tsx +++ b/app/core/components/FormFields/SelectField.tsx @@ -3,13 +3,14 @@ import InputLabel from "@mui/material/InputLabel"; import MenuItem from "@mui/material/MenuItem"; import type { SelectChangeEvent } from "@mui/material/Select"; import Select from "@mui/material/Select"; -import React from "react"; +import React, { useEffect } from "react"; import { useField, useControlField } from "remix-validated-form"; interface SelectFieldProps { name: string; label: string; options: string[]; + value?: string; onChange?: ( event?: SelectChangeEvent, child?: React.ReactNode @@ -27,6 +28,7 @@ const SelectField: React.FC = ({ options, style, onChange, + value, }) => { const { error } = useField(name); const [selectedValue, setSelectedValue] = useControlField(name); @@ -35,6 +37,12 @@ const SelectField: React.FC = ({ setSelectedValue(event.target.value); }; + useEffect(() => { + if (value !== undefined) { + setSelectedValue(value); + } + },[value, setSelectedValue]) + return (
diff --git a/app/core/layouts/Header.tsx b/app/core/layouts/Header.tsx index 6396c625..e9833145 100644 --- a/app/core/layouts/Header.tsx +++ b/app/core/layouts/Header.tsx @@ -3,8 +3,11 @@ import Link from "../components/Link"; import Search from "../components/Search"; import AddIcon from "@mui/icons-material/Add"; import { Button, Container, Grid, Paper, styled } from "@mui/material"; -import { useLocation, useSubmit } from "@remix-run/react"; +import { useLocation, useSubmit, useLoaderData } from "@remix-run/react"; import { useOptionalUser } from "~/utils"; +import { getApplicantByEmail } from "~/models/applicant.server"; +import type { LoaderFunction } from "@remix-run/server-runtime"; +import { requireProfile } from "~/session.server"; interface IProps { title: string; @@ -27,11 +30,26 @@ const StyledHeaderButton = styled(Button)(({ theme }) => ({ }, })); +export const loader: LoaderFunction = async ({ request }) => { + try { + const profile = await requireProfile(request); + const applicant = await getApplicantByEmail(profile.email); + + return { + applicant, + }; + } catch (error) { + console.error("Error loading data:", error); + } +}; + const Header = ({ existApplicant }: IProps) => { + const { applicant } = useLoaderData(); const currentUser = useOptionalUser(); const submit = useSubmit(); const location = useLocation(); + const handleClickProfile = async () => { if (currentUser) { const { email } = currentUser; @@ -43,6 +61,12 @@ const Header = ({ existApplicant }: IProps) => { return; } }; + const handleClickProfileApplicant = async () => { + submit(null, { + method: "get", + action: `/applicants/${applicant?.id}`, + }); + }; const handleLogout = async () => { await submit(null, { method: "post", action: "/logout" }); @@ -58,6 +82,15 @@ const Header = ({ existApplicant }: IProps) => { }, ] : []), + ...(currentUser?.role === "APPLICANT" + ? [ + { + onClick: handleClickProfileApplicant, + to: "/", + text: "Profile", + }, + ] + :[]), { to: "/", text: "Home", @@ -79,6 +112,7 @@ const Header = ({ existApplicant }: IProps) => { }, ] : []), + ]; let linkTo = "/internshipProjects"; diff --git a/app/routes/applicants.$applicantId._index.tsx b/app/routes/applicants.$applicantId._index.tsx index 44e73550..9d6a8007 100644 --- a/app/routes/applicants.$applicantId._index.tsx +++ b/app/routes/applicants.$applicantId._index.tsx @@ -21,6 +21,7 @@ import { type SubmitOptions, useFetcher, useNavigation, + useSubmit } from "@remix-run/react"; import { withZod } from "@remix-validated-form/with-zod"; import MarkdownStyles from "@uiw/react-markdown-preview/markdown.css"; @@ -132,6 +133,7 @@ export default function Applicant() { const [projectSelected, setProjectSelected] = useState(); const navigation = useNavigation(); + const submit = useSubmit(); useEffect(() => { const isActionRedirect = validateNavigationRedirect(navigation); @@ -188,6 +190,13 @@ export default function Applicant() { searchProfiles("", ""); }; + const editApplicant = () => { + submit(null, { + method: "get", + action: `/applicationForm/${applicantId}`, + }); + } + return ( <>
@@ -218,7 +227,15 @@ export default function Applicant() { > - ) : null} + ) : ( + editApplicant()} + > + + + ) + } >; profile: UserProfile; + applicantByEmail: Awaited>; } interface UniversityValue { @@ -150,15 +154,21 @@ const profileFetcherOptions: SubmitOptions = { export const loader: LoaderFunction = async ({ request }) => { const universities = await getActiveUniversities(); const profile = await requireProfile(request); + console.log("profile ==>",profile.email) + const applicantByEmail = await getApplicantByEmail(profile.email); + //const applicant = await getApplicantById('123456') +console.log("isApplicantisApplicantisApplicantisApplicant",applicantByEmail) return json({ universities, profile, + applicantByEmail, + //applicant, }); }; export default function FormPage() { - const { universities, profile } = useLoaderData() as LoaderData; + const { universities, profile, applicantByEmail } = useLoaderData() as LoaderData; const [selectedUniversity, setSelectedUniversity] = useState({ @@ -188,376 +198,415 @@ export default function FormPage() { const searchContactsDebounced = debounce(searchContacts, 50); const [startDate, setStartDate] = useState(getCurrentDate()); + const [editMode, setEditMode] = useState(false) + const editForm = () => { + if (profile.email === applicantByEmail?.email) { + setEditMode(true) + } + } + + + useEffect(() => { + editForm() + }) + return ( - Wizeline - - Application Form - - - Wizeline’s Innovation Experience Program is a 3-6 month program - designed to help students transition from the theoretical to the - practical and step into technical specialties. In this program, - participants will immerse in innovation projects with Wizeline industry - experts, where they can make an impact and begin a successful career in - technology. - - - - - - - - - - - - - - If your university is not listed here, please contact us at - internships@wizeline.com to work it out. - +
+ + Wizeline + + Application Form + + + Wizeline’s Innovation Experience Program is a 3-6 month program + designed to help students transition from the theoretical to the + practical and step into technical specialties. In this program, + participants will immerse in innovation projects with Wizeline industry + experts, where they can make an impact and begin a successful career in + technology. + + + + + + + + + + + + + + If your university is not listed here, please contact us at + internships@wizeline.com to work it out. + - + - - option.id === value.id} - id="contact" - getOptionLabel={(option) => option.name} - onInputChange={(_, value) => searchContactsDebounced(value)} - renderTags={() => null} - onChange={( - event, - value: { id: string; name: string } | null, - reason: AutocompleteChangeReason - ) => - reason === "clear" - ? setSelectedContact({ id: "", name: "" }) - : setSelectedContact(value) - } - filterSelectedOptions - renderInput={(params) => ( - - )} - /> + + option.id === value.id} + id="contact" + getOptionLabel={(option) => option.name} + onInputChange={(_, value) => searchContactsDebounced(value)} + renderTags={() => null} + onChange={( + event, + value: { id: string; name: string } | null, + reason: AutocompleteChangeReason + ) => + reason === "clear" + ? setSelectedContact({ id: "", name: "" }) + : setSelectedContact(value) + } + filterSelectedOptions + renderInput={(params) => ( + + )} + /> - - - - - - - - - - - - - - - - ) => - setStartDate(e.target.value) - } - /> - - - - - - - } - label="I agree to finish the program and devote time to improving my skillset by confirming my registration." - style={{ marginBottom: "20px" }} - /> - } - label={ - - I have read, understand, and accept Wizeline's{" "} - - privacy notice - - - } - style={{ marginBottom: "20px" }} - /> - + + + + + + + + + + + + + + + + ) => + setStartDate(e.target.value) + } + /> + + + + + + + } + label="I agree to finish the program and devote time to improving my skillset by confirming my registration." + style={{ marginBottom: "20px" }} + /> + } + label={ + + I have read, understand, and accept Wizeline's{" "} + + privacy notice + + + } + style={{ marginBottom: "20px" }} + /> + + - - + + ); }