diff --git a/apps/core-admin/src/controllers/attributes.ts b/apps/core-admin/src/controllers/attributes.ts
index 0c5d9216..63fe034a 100644
--- a/apps/core-admin/src/controllers/attributes.ts
+++ b/apps/core-admin/src/controllers/attributes.ts
@@ -153,3 +153,75 @@ export const getAttributeParticipants = async (req: Request, res: Response) => {
return res.status(500).json({ error: 'Something went wrong' });
}
};
+
+// Temporary controllers
+
+export const setPaymentStatus = async (req: Request, res: Response) => {
+ try {
+ const { orgId, eventId } = req?.params;
+ const { participantId, paymentStatus } = req?.body;
+
+ if (paymentStatus !== 'yes' && paymentStatus !== 'no') {
+ return res.status(400).json({ error: 'Invalid payment status' });
+ }
+
+ const attribute = await prisma.attributes.findFirst({
+ where: {
+ organizationId: orgId,
+ eventId: eventId,
+ name: 'Paid',
+ },
+ });
+
+ if (!attribute) {
+ return res.status(404).json({ error: 'No attribute for payment status found' });
+ }
+
+ const participant = await prisma.participant.findFirst({
+ where: {
+ id: participantId,
+ eventId,
+ organizationId: orgId,
+ },
+ });
+
+ if (!participant) {
+ return res.status(404).json({ error: 'Participant not found' });
+ }
+
+ const participantAttribute = await prisma.participantAttributes.findFirst({
+ where: {
+ participantId,
+ attributeId: attribute.id,
+ },
+ });
+
+ if (!participantAttribute) {
+ return res.status(400).json({ error: 'Payment attribute not assigned to participant' });
+ }
+
+ if (participantAttribute.value === paymentStatus) {
+ return res
+ .status(400)
+ .json({ error: `Participant already payment status set as ${paymentStatus}` });
+ }
+
+ const updatedParticipantAttribute = await prisma.participantAttributes.update({
+ where: {
+ id: participantAttribute.id,
+ },
+ data: {
+ value: paymentStatus,
+ },
+ });
+
+ if (!updatedParticipantAttribute) {
+ return res.status(500).json({ error: 'Failed to update payment status' });
+ }
+
+ return res.status(200).json({ updatedParticipantAttribute });
+ } catch (err: any) {
+ console.error(err);
+ return res.status(500).json({ error: 'Something went wrong' });
+ }
+};
diff --git a/apps/core-admin/src/controllers/organizations.ts b/apps/core-admin/src/controllers/organizations.ts
index 88342557..0dee77d9 100644
--- a/apps/core-admin/src/controllers/organizations.ts
+++ b/apps/core-admin/src/controllers/organizations.ts
@@ -5,26 +5,64 @@ import prisma from '../utils/database';
export const createNewOrganization = async (req: Request, res: Response) => {
try {
const userId = req?.auth?.payload?.sub;
- const { id, name } = req.body;
- //console.log(id, name);
- const newOrganization = await prisma.organization.create({
- data: {
- id,
- name,
- OrganizationUser: {
- create: {
- userId,
- role: 'ADMIN',
+ const { id, name, email } = req.body;
+ console.log(id, name);
+ console.log(userId);
+
+ const existingUser = await prisma.user.findUnique({
+ where: { id: userId },
+ });
+
+ if (!existingUser) {
+ // throw new Error(`User with ID ${userId} not found`);
+
+ const newUser = await prisma.user.create({
+ data: {
+ email: email,
+ id: userId,
+ },
+ });
+ if (!newUser) {
+ return res.status(500).json({ error: 'Something went wrong' });
+ }
+ const newOrganization = await prisma.organization.create({
+ data: {
+ id,
+ name,
+ OrganizationUser: {
+ create: {
+ userId: userId,
+ role: 'ADMIN',
+ },
},
},
- },
- });
+ });
- if (!newOrganization) {
- return res.status(500).json({ error: 'Something went wrong' });
- }
+ if (!newOrganization) {
+ return res.status(500).json({ error: 'Something went wrong' });
+ }
- return res.status(200).json(newOrganization);
+ return res.status(200).json(newOrganization);
+ } else {
+ const newOrganization = await prisma.organization.create({
+ data: {
+ id,
+ name,
+ OrganizationUser: {
+ create: {
+ userId: userId,
+ role: 'ADMIN',
+ },
+ },
+ },
+ });
+
+ if (!newOrganization) {
+ return res.status(500).json({ error: 'Something went wrong' });
+ }
+
+ return res.status(200).json(newOrganization);
+ }
} catch (err: any) {
console.error(err);
if (err.code === 'P2002') {
diff --git a/apps/core-admin/src/controllers/participants.ts b/apps/core-admin/src/controllers/participants.ts
index a84583c1..717d7d6d 100644
--- a/apps/core-admin/src/controllers/participants.ts
+++ b/apps/core-admin/src/controllers/participants.ts
@@ -299,6 +299,7 @@ export const getAllParticipantsCheckInDetails = async (req: Request, res: Respon
eventId,
},
include: {
+ participantAttributes: true,
participantCheckIn: {
select: {
id: true,
@@ -322,6 +323,9 @@ export const getAllParticipantsCheckInDetails = async (req: Request, res: Respon
phone: participant.phone,
email: participant.email,
checkInKey: participant.checkInKey,
+ paymentStatus: participant.participantAttributes.filter(
+ (attr: any) => attr.value === 'yes' || attr.value === 'no',
+ )[0].value,
checkIn: {
status: participant.participantCheckIn.length > 0 ? true : false,
checkedInAt:
diff --git a/apps/core-admin/src/routes.ts b/apps/core-admin/src/routes.ts
index 55e2f64d..253708cf 100644
--- a/apps/core-admin/src/routes.ts
+++ b/apps/core-admin/src/routes.ts
@@ -27,6 +27,7 @@ import {
getAllAttributes,
getAttributeById,
getAttributeParticipants,
+ setPaymentStatus,
} from './controllers/attributes';
import { fetchAccountDetails, myCredential, updateAccountDetails } from './controllers/users';
import { validateOrganizationUser, validateOrganizationAdmin } from './middlewares/authorization';
@@ -111,6 +112,9 @@ router.put(
updateParticipantAttribute,
);
+// Temp routes
+router.post('/organizations/:orgId/events/:eventId/participants/payment-status', setPaymentStatus);
+
router.post('/organizations/update', updateOrganizationDetails); //ajay
router.get('/organizations/:orgId/events/:eventId/attributes', getAllAttributes); // done
diff --git a/apps/web-admin/src/components/DataDisplay.jsx b/apps/web-admin/src/components/DataDisplay.jsx
index 55ae1c5b..546cba6f 100644
--- a/apps/web-admin/src/components/DataDisplay.jsx
+++ b/apps/web-admin/src/components/DataDisplay.jsx
@@ -189,6 +189,17 @@ export default function DataDisplay({
Open
+ ) : column.field == 'paymentStatus' ? (
+
+ {row[column.field]}
+ {
+ e.stopPropagation();
+ column.togglePaymentStatus(row.id, e.target.checked ? 'yes' : 'no');
+ }}
+ />
+
) : (
//
{row[column.field]}
diff --git a/apps/web-admin/src/components/ProtectedRoute.jsx b/apps/web-admin/src/components/ProtectedRoute.jsx
index a5b219f5..b4b7ef6a 100644
--- a/apps/web-admin/src/components/ProtectedRoute.jsx
+++ b/apps/web-admin/src/components/ProtectedRoute.jsx
@@ -54,7 +54,8 @@ export const ProtectedRoute = ({ children }) => {
async function postOrg() {
const id = user.sub.substring(6);
const name = user.nickname;
- const response = await post(`/core/organizations`, {}, { id, name });
+ const email = user.email;
+ const response = await post(`/core/organizations`, {}, { id, name, email });
if (response) {
const { data, mystatus } = response;
//console.log('created');
@@ -77,7 +78,12 @@ export const ProtectedRoute = ({ children }) => {
async function checkOrg() {
let myResponse = await get('/core/users/mycreds');
// //console.log(myResponse.data.data);
- if (myResponse && myResponse.status === 200) {
+ if (
+ myResponse &&
+ myResponse.status === 200 &&
+ myResponse.data.data &&
+ myResponse.data.data.length !== 0
+ ) {
console.log('Hello world');
setAllAccounts(
myResponse.data.data.map((value) => ({
@@ -95,7 +101,7 @@ export const ProtectedRoute = ({ children }) => {
});
//console.log('final: ', data);
setAccountDetails(data[0]);
- router.replace(`/${data[0].orgId}/events`);
+ // router.replace(`/${data[0].orgId}/events`);
return data;
});
}
diff --git a/apps/web-admin/src/pages/[orgId]/events/[eventId]/navigationmenu.jsx b/apps/web-admin/src/pages/[orgId]/events/[eventId]/navigationmenu.jsx
index 1fc53bbc..a750da8a 100644
--- a/apps/web-admin/src/pages/[orgId]/events/[eventId]/navigationmenu.jsx
+++ b/apps/web-admin/src/pages/[orgId]/events/[eventId]/navigationmenu.jsx
@@ -27,6 +27,10 @@ const NavigationMenu = ({ orgId, eventId, navButton }) => {
name: 'Participants Check-in Details',
path: `/${orgId}/events/${eventId}/participants/check-in`,
},
+ {
+ name: 'Participants Payment Status',
+ path: `/${orgId}/events/${eventId}/paymentstatus`,
+ },
{
name: 'Attributes Details',
path: `/${orgId}/events/${eventId}/attributes`,
diff --git a/apps/web-admin/src/pages/[orgId]/events/[eventId]/participants/new/upload-csv/index.jsx b/apps/web-admin/src/pages/[orgId]/events/[eventId]/participants/new/upload-csv/index.jsx
index 989daac1..adb134db 100644
--- a/apps/web-admin/src/pages/[orgId]/events/[eventId]/participants/new/upload-csv/index.jsx
+++ b/apps/web-admin/src/pages/[orgId]/events/[eventId]/participants/new/upload-csv/index.jsx
@@ -116,8 +116,7 @@ export default function NewParticipantByCSVUpload() {
if (extraColumns.length > 0) {
showAlert({
title: 'Info',
- description:
- 'Extra columns detected. Using _ for attributes and & for check-in extras.',
+ description: 'Extra columns detected. Using _ for attributes and & for extras.',
status: 'info',
duration: 5000,
});
@@ -267,8 +266,7 @@ export default function NewParticipantByCSVUpload() {
fontSize="lg"
color={colorMode === 'light' ? 'gray.600' : 'gray.100'}
>
- Prefix extra attributes with underscore (_) and check-in attributes with ampersand
- (&)
+ Prefix Attributes with underscore ( _ ) and Extra Details with ampersand ( & )
diff --git a/apps/web-admin/src/pages/[orgId]/events/[eventId]/paymentstatus/index.jsx b/apps/web-admin/src/pages/[orgId]/events/[eventId]/paymentstatus/index.jsx
new file mode 100644
index 00000000..86559bdf
--- /dev/null
+++ b/apps/web-admin/src/pages/[orgId]/events/[eventId]/paymentstatus/index.jsx
@@ -0,0 +1,183 @@
+import { useRouter } from 'next/router';
+import { useState } from 'react';
+import { StyledBox, StyledButton, StyledText } from '@/components/ui/StyledComponents';
+import DashboardLayout from '@/layouts/DashboardLayout';
+import DataDisplay from '@/components/DataDisplay';
+import { useAlert } from '@/hooks/useAlert';
+import useWrapper from '@/hooks/useWrapper';
+import NavigationMenu from '../navigationmenu';
+
+import { useDisclosure } from '@chakra-ui/react';
+import CheckInParticipantWithMultiScanner from '@/components/modals/MultiStageScanner/index';
+import CheckInParticipant from '@/components/modals/Check-inParticipant/index';
+import CheckInParticipantWithScanner from '@/components/modals/Check-in-Scanner/index';
+import CheckOutParticipant from '@/components/modals/Check-OutParticipant/index';
+import CheckOutParticipantWithScanner from '@/components/modals/Check-Out-Scanner/index';
+
+export default function ParticipantsCheckIn() {
+ const router = useRouter();
+ const showAlert = useAlert();
+ const { orgId, eventId } = router.query;
+ const [participantsCheckIn, setParticipantsCheckIn] = useState([]);
+ const { useGetQuery, usePostMutation } = useWrapper();
+
+ const {
+ data,
+ status,
+ error,
+ isFetching: loading,
+ } = useGetQuery(
+ `/core/organizations/${orgId}/events/${eventId}/participants/check-in`,
+ `/core/organizations/${orgId}/events/${eventId}/participants/check-in`,
+ {},
+ {},
+ (data) => {
+ setParticipantsCheckIn(data.data.participantsCheckIn || []);
+ },
+ );
+
+ const {
+ isOpen: isMultiScannerModalOpen,
+ onOpen: onMultiScannerModalOpen,
+ onClose: onMultiScannerModalClose,
+ } = useDisclosure();
+ const {
+ isOpen: isCheckInModalOpen,
+ onOpen: onCheckInModalOpen,
+ onClose: onCheckInModalClose,
+ } = useDisclosure();
+ const {
+ isOpen: isScanner1ModalOpen,
+ onOpen: onScanner1ModalOpen,
+ onClose: onScanner1ModalClose,
+ } = useDisclosure();
+ const {
+ isOpen: isScanner2ModalOpen,
+ onOpen: onScanner2ModalOpen,
+ onClose: onScanner2ModalClose,
+ } = useDisclosure();
+ const {
+ isOpen: isCheckOutModalOpen,
+ onOpen: onCheckOutModalOpen,
+ onClose: onCheckOutModalClose,
+ } = useDisclosure();
+
+ const { mutate: handlePaymentStatusMutation } = usePostMutation(
+ `/core/organizations/${orgId}/events/${eventId}/participants/payment-status`,
+ {},
+ {
+ onSuccess: (response) => {
+ showAlert({
+ title: 'Success',
+ description: 'Payment status for participant has been updated successfully.',
+ status: 'success',
+ });
+ },
+ onError: (error) => {
+ showAlert({
+ title: 'Error',
+ description: error.message,
+ status: 'error',
+ });
+ },
+ },
+ );
+
+ const columns = [
+ { field: 'firstName', headerName: 'First Name', width: 200 },
+ { field: 'lastName', headerName: 'Last Name', width: 200 },
+ { field: 'email', headerName: 'Email', width: 200 },
+ { field: 'phone', headerName: 'Phone', width: 200 },
+ { field: 'checkInKey', headerName: 'Check In Key', width: 200 },
+ {
+ field: 'paymentStatus',
+ headerName: 'Payment Status',
+ width: 150,
+ togglePaymentStatus: (id, status) => {
+ handlePaymentStatusMutation({
+ participantId: id,
+ paymentStatus: status,
+ });
+ setParticipantsCheckIn((prevParticipants) =>
+ prevParticipants.map((participant) =>
+ participant.id === id ? { ...participant, paymentStatus: status } : participant,
+ ),
+ );
+ },
+ },
+ {
+ field: 'checkedInAt',
+ headerName: 'Check-In At',
+ width: 200,
+ valueGetter: (params) => params.row?.checkIn?.checkedInAt || 'Not Checked In',
+ },
+ {
+ field: 'checkedInByEmail',
+ headerName: 'Checked In By',
+ width: 200,
+ valueGetter: (params) => params.row?.checkIn?.checkedInByEmail,
+ },
+ ];
+
+ return (
+
+
+
+ Multi-Stage Scanner
+
+
+ Check-In Participant
+
+
+ Open Scanner
+
+
+ Check-Out Participant
+
+
+ Open Scanner
+
+
+ }
+ />
+
+ {
+ // router.push(`/${orgId}/events/${eventId}/participants/${row.id}`);
+ // }}
+ />
+
+ {!loading && participantsCheckIn.length === 0 ? (
+
+
+ No participants checked-in
+
+
+ Add details about the checked-in participants
+
+
+ ) : (
+ <>>
+ )}
+
+
+
+
+
+
+ );
+}