From 6a472115a2c16deec11a95a5e669997512955bb6 Mon Sep 17 00:00:00 2001 From: vaidyanath b <82041246+vaidyanath-b@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:26:23 +0530 Subject: [PATCH] feat: UUID validator middleware and edit Participant (#328) * validateUUID * fix UUID checks * feat - edit participant * Revert "feat - edit participant" This reverts commit 1e38f1780d7c42942a9cecba99cdb4ba78dcd9c2. * Revert "Revert "feat - edit participant"" This reverts commit 86b99e948909c8539801498c7b2f3182585c73e7. * participant attribute display * Removed console.log --- apps/core-admin/src/controllers/attributes.ts | 2 + .../src/controllers/participants.ts | 31 ++- apps/core-admin/src/routes.ts | 6 + .../[participantId]/edit/index.js | 178 ++++++++++++++++++ .../events/[eventId]/participants/index.jsx | 57 +++++- 5 files changed, 264 insertions(+), 10 deletions(-) create mode 100644 apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/[participantId]/edit/index.js diff --git a/apps/core-admin/src/controllers/attributes.ts b/apps/core-admin/src/controllers/attributes.ts index f3510e7e..0c5d9216 100644 --- a/apps/core-admin/src/controllers/attributes.ts +++ b/apps/core-admin/src/controllers/attributes.ts @@ -72,6 +72,8 @@ export const getAttributeById = async (req: Request, res: Response) => { addedAt: participantAttribute.createdAt, firstName: participantAttribute.participant.firstName, lastName: participantAttribute.participant.lastName, + email: participantAttribute.participant.email, + phone: participantAttribute.participant.phone, }; }, ), diff --git a/apps/core-admin/src/controllers/participants.ts b/apps/core-admin/src/controllers/participants.ts index 54ffd2c7..82526abd 100644 --- a/apps/core-admin/src/controllers/participants.ts +++ b/apps/core-admin/src/controllers/participants.ts @@ -177,7 +177,7 @@ export const addNewParticipant = async (req: Request, res: Response) => { export const editParticipant = async (req: Request, res: Response) => { try { const { orgId, eventId, participantId } = req?.params; - const { firstName, lastName, phone, email, checkInKey } = req?.body; + const { firstName, lastName, phone, email, checkInKey, attributes } = req?.body; if (!firstName || !lastName) { return res.status(400).json({ error: 'First name and last name are required' }); @@ -196,10 +196,37 @@ export const editParticipant = async (req: Request, res: Response) => { }, }); + const awaitAttributes = attributes?.map(async (attribute: any) => { + try { + const participantAttribute = await prisma.participantAttributes.updateMany({ + where: { + attributeId: attribute.id, + participantId: participantId, + }, + data: { + value: attribute.value, + }, + }); + if (participantAttribute.count === 0) { + const newParticipantAttribute = await prisma.participantAttributes.create({ + data: { + participantId, + attributeId: attribute.id, + value: attribute.value, + }, + }); + return newParticipantAttribute; + } + return participantAttribute; + } catch (err: any) { + console.error(err); + return res.status(500).json({ error: 'Something went wrong' }); + } + }); + if (!updatedParticipant) { return res.status(500).json({ error: 'Something went wrong' }); } - return res.status(200).json({ updatedParticipant }); } catch (err: any) { console.error(err); diff --git a/apps/core-admin/src/routes.ts b/apps/core-admin/src/routes.ts index 81bf4a85..058d62ca 100644 --- a/apps/core-admin/src/routes.ts +++ b/apps/core-admin/src/routes.ts @@ -29,9 +29,15 @@ import { import { fetchAccountDetails, updateAccountDetails } from './controllers/users'; import { validateOrganizationUser, validateOrganizationAdmin } from './middlewares/authorization'; import { addNewExtra, checkInExtra, getAllExtras, getExtraById } from './controllers/extras'; +import { validateUUID } from './middlewares/validateParams'; const router: Router = express.Router(); +router.param('eventId', validateUUID); +router.param('attributeId', validateUUID); +router.param('participantId', validateUUID); +router.param('extraId', validateUUID); + router.get('/', (req: any, res: any) => { try { return res.send('Hello World!'); diff --git a/apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/[participantId]/edit/index.js b/apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/[participantId]/edit/index.js new file mode 100644 index 00000000..12d42674 --- /dev/null +++ b/apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/[participantId]/edit/index.js @@ -0,0 +1,178 @@ +import { useState, useEffect } from 'react'; +import { useRouter } from 'next/router'; + +import { Button, FormControl, FormLabel, Input } from '@chakra-ui/react'; + +import DashboardLayout from '@/layouts/DashboardLayout'; + +import { useAlert } from '@/hooks/useAlert'; +import { useFetch } from '@/hooks/useFetch'; + +export default function EditParticipant() { + const { loading, put, get } = useFetch(); + const showAlert = useAlert(); + + const router = useRouter(); + const { orgId, eventId, participantId } = router.query; + + const [participant, setParticipant] = useState(null); + const [attributes, setAttributes] = useState([]); + const [attributeValues, setAttributeValues] = useState([]); + + const handleSubmit = async (e) => { + e.preventDefault(); + + const { data, status } = await put( + `/core/organizations/${orgId}/events/${eventId}/participants/${participantId}`, + {}, + { + firstName: participant.firstName, + lastName: participant.lastName, + email: participant.email, + phone: participant.phone, + checkInKey: participant.checkInKey, + checkedIn: participant.checkedIn, + attributes: attributeValues, + }, + ); + + if (status === 200) { + showAlert({ + title: 'Success', + description: 'Participant has been updated successfully.', + status: 'success', + }); + router.push(`/organizations/${orgId}/events/${eventId}/participants`); + } else { + showAlert({ + title: 'Error', + description: data.error, + status: 'error', + }); + } + }; + + useEffect(() => { + const fetchParticipant = async () => { + const { data, status } = await get( + `/core/organizations/${orgId}/events/${eventId}/participants/${participantId}`, + ); + + if (status === 200) { + setParticipant(data.participant); + setAttributeValues(data.participant.attributes); + } + }; + }, [orgId, eventId, participantId]); + + if (!participant) { + return null; + } + + return ( + participant && ( + +
+ + First Name + { + setParticipant({ ...participant, firstName: e.target.value }); + }} + /> + + + Last Name + { + setParticipant({ ...participant, lastName: e.target.value }); + }} + /> + + + Check In + { + setParticipant({ ...participant, checkInKey: e.target.value }); + }} + /> + + + mail + { + setParticipant({ ...participant, email: e.target.value }); + }} + /> + + + Phone + { + setParticipant({ ...participant, phone: e.target.value }); + }} + /> + + + {attributeValues.map((attribute) => ( + + {attribute.name} + value.id === attribute.id)?.value || ''} + onChange={(e) => { + setAttributeValues((prev) => { + const index = prev.findIndex((value) => value.id === attribute.id); + if (index === -1) { + return [ + ...prev, + { + id: attribute.id, + value: e.target.value, + }, + ]; + } + return prev.map((value) => { + if (value.id === attribute.id) { + return { + ...value, + value: e.target.value, + }; + } + return value; + }); + }); + }} + /> + + ))} + + {/* Add more form fields as needed */} + +
+
+ ) + ); +} diff --git a/apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/index.jsx b/apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/index.jsx index 09aec4ff..43ab2b1e 100644 --- a/apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/index.jsx +++ b/apps/web-admin/src/pages/organizations/[orgId]/events/[eventId]/participants/index.jsx @@ -9,6 +9,7 @@ import DataDisplay from '@/components/DataDisplay'; import { useAlert } from '@/hooks/useAlert'; import { useFetch } from '@/hooks/useFetch'; +import { EditIcon, ViewIcon } from '@chakra-ui/icons'; const columns = [ { field: 'firstName', headerName: 'First Name', width: 200, editable: true }, @@ -23,6 +24,53 @@ const columns = [ ]; export default function Participants() { + const columns = [ + { field: 'firstName', headerName: 'First Name', width: 125 }, + { field: 'lastName', headerName: 'Last Name', width: 125 }, + { + field: 'edit', + headerName: '', + sortable: false, + width: 50, + renderCell: (params) => ( + + ), + }, + { + field: 'view', + headerName: '', + sortable: false, + width: 50, + renderCell: (params) => ( + + ), + }, + { field: 'email', headerName: 'Email', width: 200 }, + { field: 'phone', headerName: 'Phone', width: 125 }, + { field: 'checkInKey', headerName: 'Check In Key', width: 125 }, + { field: 'checkedIn', headerName: 'CheckedIn', width: 125 }, + { field: 'numberOfAttributesAssigned', headerName: 'Attributes Assigned', width: 125 }, + { field: 'numnerOfExtrasAssigned', headerName: 'Extras Assigned', width: 125 }, + { field: 'addedAt', headerName: 'Added At', width: 125 }, + ]; const router = useRouter(); const showAlert = useAlert(); @@ -75,14 +123,7 @@ export default function Participants() { } debugInfo={participants} > - { - router.push(`/organizations/${orgId}/events/${eventId}/participants/${row.id}`); - }} - /> + ); }