From 4007b852e351f45fe857fb2f989c560287a9aa71 Mon Sep 17 00:00:00 2001 From: Saumyapratim Das Date: Tue, 9 Jan 2024 17:16:33 +0530 Subject: [PATCH] Table updates --- app/actions/getNames.ts | 52 +++-- app/actions/getRegistrationDetails.ts | 19 +- app/api/payment/route.ts | 50 +++++ app/api/registrations/route.ts | 55 +++-- app/components/Button.tsx | 32 ++- .../dashboard/registrations/Table.tsx | 48 ++-- .../dashboard/registrations/Toggle.tsx | 48 ++++ .../events/secondaryLayout/EventDateInfo2.tsx | 41 +++- .../events/secondaryLayout/EventDetail.tsx | 2 +- .../[eventId]/registrations/page.tsx | 6 +- app/events/[eventId]/EventClient.tsx | 3 +- app/events/[eventId]/EventClient2.tsx | 205 ++++++++++-------- .../[eventId]/EventRegistrationForm.tsx | 51 ++--- app/events/[eventId]/page.tsx | 4 +- app/types/index.ts | 17 +- prisma/schema.prisma | 7 + 16 files changed, 418 insertions(+), 222 deletions(-) create mode 100644 app/api/payment/route.ts create mode 100644 app/components/dashboard/registrations/Toggle.tsx diff --git a/app/actions/getNames.ts b/app/actions/getNames.ts index 60f4e00..268bf2b 100644 --- a/app/actions/getNames.ts +++ b/app/actions/getNames.ts @@ -11,36 +11,40 @@ export const getNames = async (queryParams: QueryParams) => { const { q, eventId } = queryParams; //@ts-ignore const eventIdInt = parseInt(eventId, 10); - if (isNaN(eventIdInt)) { - throw new Error('Invalid event ID'); - } + + if (isNaN(eventIdInt)) { + throw new Error('Invalid event ID'); + } - try{ - const users = await prisma.registration.findMany({ + try { + const registrations = await prisma.registration.findMany({ where: { AND: [ - { - member1: { - contains: q - } - }, - { - eventId: eventIdInt - } + { member1: { contains: q } }, + { eventId: eventIdInt } ] }, - select: { - member1: true, - member2: true, - member3: true, - phone: true, - semester: true, - userId: true, - }, + include: { + event: { + select: { + id: true, + title: true, + // ... include other fields required for SafeEvent + createdAt: true // Ensure this is formatted as a string + } + } + } }); - console.log(users) - return users; - + + // Transform the data to match SafeRegistration type + return registrations.map(reg => ({ + ...reg, + createdAt: reg.createdAt.toISOString(), // Format createdAt as a string + event: { + ...reg.event, + createdAt: reg.event.createdAt.toISOString() // Format event's createdAt as a string + } + })); } catch (error) { if (error instanceof Error) { throw error; diff --git a/app/actions/getRegistrationDetails.ts b/app/actions/getRegistrationDetails.ts index d892364..d08ec5d 100644 --- a/app/actions/getRegistrationDetails.ts +++ b/app/actions/getRegistrationDetails.ts @@ -57,10 +57,13 @@ export default async function getRegistrationData(eventId) { const currentUser = await getCurrentUser(); if (!currentUser) { - return []; + return { + hasRegistered: false, + hasPaid: false + }; } - const hasRegistered = await prisma.registration.findFirst({ + const registration = await prisma.registration.findFirst({ where: { userId: currentUser.id, eventId: eventId @@ -70,7 +73,17 @@ export default async function getRegistrationData(eventId) { } }); - return Boolean(hasRegistered); + if (!registration) { + return { + hasRegistered: false, + hasPaid: false + }; + } + + return { + hasRegistered: true, + hasPaid: registration.hasPaid + }; } catch (error) { if (error instanceof Error) { throw error; // Re-throw if it's an Error instance diff --git a/app/api/payment/route.ts b/app/api/payment/route.ts new file mode 100644 index 0000000..a7363ac --- /dev/null +++ b/app/api/payment/route.ts @@ -0,0 +1,50 @@ +import { NextResponse } from "next/server"; + +import getCurrentUser from "@/app/actions/getCurrentUser"; +import prisma from "@/app/libs/prismadb"; + +export async function POST(request: Request) { + try { + const currentUser = await getCurrentUser(); + + if (!currentUser) { + return new Response('User not found', { status: 404 }); + } + + const body = await request.json(); + const { registrationId } = body; + console.log(registrationId) + + + if (isNaN(registrationId)) { + return new Response('Invalid Registration ID', { status: 400 }); + } + const registration = await prisma.registration.findUnique({ + where: { + id: registrationId, + }, + }); + + if (!registration) { + return new Response('Registration not found', { status: 404 }); + } + await prisma.registration.update({ + where: { + id: registrationId, + }, + data: { + hasPaid: !registration.hasPaid, // Toggle the hasPaid status + }, + }); + + + return new Response('Registration payment status updated successfully', { status: 200 }); + + } catch (error) { + if (error instanceof Error) { + return new Response(error.message, { status: 500 }); + } else { + return new Response('An unknown error occurred', { status: 500 }); + } + } +} \ No newline at end of file diff --git a/app/api/registrations/route.ts b/app/api/registrations/route.ts index d62db75..32ece21 100644 --- a/app/api/registrations/route.ts +++ b/app/api/registrations/route.ts @@ -7,34 +7,41 @@ export async function POST(request: Request) { try { const currentUser = await getCurrentUser(); - if (!currentUser) { - return new Response("User not authenticated", { status: 401 }); - } + if (!currentUser) { + return new Response("User not authenticated", { status: 401 }); + } - const body = await request.json(); - const { semester, member1, member2, member3, phone, name, eventId, department } = body; + const body = await request.json(); + const { semester, member1, member2, member3, member4, member5, member6, member7, member8, member9, member10, phone, name, eventId, department } = body; - const registration = await prisma.registration.create({ - data: { - userId: currentUser.id, - eventId: parseInt(eventId), - phone: phone.toString(), - semester: semester, - member1: member1, - member2: member2, - member3: member3, - department: department - } - }); + const registration = await prisma.registration.create({ + data: { + userId: currentUser.id, + eventId: parseInt(eventId), + phone: phone.toString(), + semester: semester, + member1: member1, + member2: member2, + member3: member3, + member4: member4, + member5: member5, + member6: member6, + member7: member7, + member8: member8, + member9: member9, + member10: member10, + department: department + } + }); - let userEmail: string; - //@ts-ignore - userEmail = currentUser?.email; - const emailSubject = 'Thanks for registering'; - const emailText = `You have successfully registerd for the event! On the next steps, if the event is paid, you might have to verify your payment at the designated place to get access to the ticket. Otherwise you can download the tiket from the event page itself. We can't wait to see you have fun there.` - await sendMail(emailSubject, userEmail, emailText); + let userEmail: string; + //@ts-ignore + userEmail = currentUser?.email; + const emailSubject = 'Thanks for registering'; + const emailText = `You have successfully registerd for the event! On the next steps, if the event is paid, you might have to verify your payment at the designated place to get access to the ticket. Otherwise you can download the tiket from the event page itself. We can't wait to see you have fun there.` + await sendMail(emailSubject, userEmail, emailText); - return new Response(JSON.stringify(registration), { status: 200, headers: { 'Content-Type': 'application/json' } }); + return new Response(JSON.stringify(registration), { status: 200, headers: { 'Content-Type': 'application/json' } }); } catch (error) { if (error instanceof Error) { diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 8517066..554cc59 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -62,25 +62,19 @@ const Button: React.FC = ({
- {disabled ? ( -
- {!dontShowLoading ? ( - <> -
-
- -
-
-
-
- -
-
- - ) : ( -
{label}
- )} -
+ {disabled && !outline && !dontShowLoading ? ( + <> +
+
+ +
+
+
+
+ +
+
+ ) : (
{label}
)} diff --git a/app/components/dashboard/registrations/Table.tsx b/app/components/dashboard/registrations/Table.tsx index 353bd6d..27718f5 100644 --- a/app/components/dashboard/registrations/Table.tsx +++ b/app/components/dashboard/registrations/Table.tsx @@ -1,41 +1,59 @@ -import Pagination from "./Pagination"; +"use client" +import { useEffect, useState } from "react"; +import Pagination from "./Pagination"; +import { SafeEvent, SafeRegistration } from "@/app/types"; +import Toggle from "./Toggle"; interface TableProps{ - data?: any; + data?: SafeRegistration[]; + event?: SafeEvent } const Table: React.FC = ({ data, + event, }) => { + const generateMemberColumns = (memberCount: number) => { + const columns = []; + for (let i = 1; i <= memberCount; i++) { + columns.push(Member {i}); + } + return columns; + }; + + const renderMemberData = (row: any, memberCount: number) => { + const memberData = []; + for (let i = 1; i <= memberCount; i++) { + memberData.push({row[`member${i}`]}); + } + return memberData; + }; + return (
- + + - - - - - + {event && generateMemberColumns(event.memberCount!)} - {data.map((row: any, index: number) => ( + {data?.map((row: any, index: number) => ( - + + - - - - - + {event && renderMemberData(row, event.memberCount!)} ))} diff --git a/app/components/dashboard/registrations/Toggle.tsx b/app/components/dashboard/registrations/Toggle.tsx new file mode 100644 index 0000000..5908d4d --- /dev/null +++ b/app/components/dashboard/registrations/Toggle.tsx @@ -0,0 +1,48 @@ +"use client" + +import { SafeEvent, SafeRegistration } from "@/app/types"; +import axios from "axios"; +import { useState } from "react"; +import toast from "react-hot-toast"; + +interface ToggleProps{ + registration?: SafeRegistration; +} + +const Toggle: React.FC = ({ + registration +}) => { + const [paidStatus, setPaidStatus] = useState(registration?.hasPaid); + + const handlePaymentStatusChange = () => { + axios.post('/api/payment', { registrationId: registration?.id }) + .then(response => { + console.log(response.data); + }) + .catch(error => { + console.error('Error updating payment status:', error); + }); + }; + + const handleChange = () => { + const newPaidStatus = !paidStatus; + setPaidStatus(newPaidStatus); + + if (registration?.id) { + handlePaymentStatusChange(); + } + }; + return ( +
+ +
+ ); +} + +export default Toggle; \ No newline at end of file diff --git a/app/components/events/secondaryLayout/EventDateInfo2.tsx b/app/components/events/secondaryLayout/EventDateInfo2.tsx index f9ded9c..e485aab 100644 --- a/app/components/events/secondaryLayout/EventDateInfo2.tsx +++ b/app/components/events/secondaryLayout/EventDateInfo2.tsx @@ -1,6 +1,6 @@ import { SafeEvent } from "@/app/types"; import EventDetail from "./EventDetail"; -import { Calendar, LocateIcon, MousePointerClick } from "lucide-react"; +import { Calendar, DollarSign, LocateIcon, MousePointerClick, Users2 } from "lucide-react"; import { BiLocationPlus } from "react-icons/bi"; import { MdLocationPin } from "react-icons/md"; import moment from "moment"; @@ -22,32 +22,49 @@ const EventDateInfo2: React.FC = ({ const trimmedDay = day.slice(0, -1); return ( -
-
+
+
}} /> }} /> }} />
-
+
}} /> - }} - /> - +
+ }} + /> +
+ {event?.price! > 0 ? ( +
+ }} + /> +
+ ) : ( +
+ }} + /> +
+ ) + }
diff --git a/app/components/events/secondaryLayout/EventDetail.tsx b/app/components/events/secondaryLayout/EventDetail.tsx index b284bf4..2c21ba6 100644 --- a/app/components/events/secondaryLayout/EventDetail.tsx +++ b/app/components/events/secondaryLayout/EventDetail.tsx @@ -16,7 +16,7 @@ const EventDetail: React.FC = ({ icon }) => { return ( -
+
{icon && (
{icon.component} diff --git a/app/dashboard/[eventId]/registrations/page.tsx b/app/dashboard/[eventId]/registrations/page.tsx index b997caf..c7d9a47 100644 --- a/app/dashboard/[eventId]/registrations/page.tsx +++ b/app/dashboard/[eventId]/registrations/page.tsx @@ -74,7 +74,11 @@ const DashboardRegistrations = async ({ params, searchParams }: { params: IParam
-
User IDSerial Member 1 SemesterPaid PhonePhonePhonePhonePhonePhone
{row.userId}{index + 1} {row.member1} {row.semester} + + {row.phone}{row.phone}{row.phone}{row.phone}{row.phone}{row.phone}
+
diff --git a/app/events/[eventId]/EventClient.tsx b/app/events/[eventId]/EventClient.tsx index 211387a..ba5e948 100644 --- a/app/events/[eventId]/EventClient.tsx +++ b/app/events/[eventId]/EventClient.tsx @@ -132,8 +132,7 @@ const EventClient: React.FC = ({ }) // let likedBy = [...(event?.likedBy || [])]; - const coordinates: [number, number] = [40.748817, -73.985428]; - + const coordinates: [number, number] = [22.619687629455996, 88.34774099557224]; return (
diff --git a/app/events/[eventId]/EventClient2.tsx b/app/events/[eventId]/EventClient2.tsx index d6d170f..dfda32e 100644 --- a/app/events/[eventId]/EventClient2.tsx +++ b/app/events/[eventId]/EventClient2.tsx @@ -33,6 +33,7 @@ interface EventClient2Props { currentUser?: SafeUser | null; isRegistered?: boolean; ticketData: any; + hasPaid? : boolean; } @@ -42,7 +43,8 @@ const EventClient2: React.FC = ({ event, currentUser, isRegistered, - ticketData + ticketData, + hasPaid }) => { @@ -180,123 +182,138 @@ const EventClient2: React.FC = ({ // let likedBy = [...(event?.likedBy || [])]; - const coordinates: [number, number] = [40.748817, -73.985428]; + const coordinates: [number, number] = [22.619687629455996, 88.34774099557224]; return (
-
-
- {/* Gradient Div */} -
- - {/* Image */} -
-
- {event.title} +
+
+
+ {/* Gradient Div */} +
+ + {/* Image */} +
+
+ {event.title} +
+
-
-
-
-
- {event.title} -
- +
+
+
+
+ {event.title} +
+ - {/* event details */} - - + {/* event details */} + + - {/* Buttons */} + {/* Buttons */} -
-
- {isRegistered ? ( - event.cancellable ? ( -
-
+
+
{isRegistered ? ( -
- + ) + ) : ( +
+
+ {isRegistered ? ( + (hasPaid ? ( +
+ + )} +
-
- + -
-
About {event.title}
-
- {event.description} - +
+
About {event.title}
+
+ {event.description} + +
+ +
+ +
+ +
-
- -
- - -
- +
diff --git a/app/events/[eventId]/EventRegistrationForm.tsx b/app/events/[eventId]/EventRegistrationForm.tsx index 8527ee0..54b9875 100644 --- a/app/events/[eventId]/EventRegistrationForm.tsx +++ b/app/events/[eventId]/EventRegistrationForm.tsx @@ -48,6 +48,10 @@ const EventRegiatrationModal: React.FC = ({ const eventRegistrationModal = useEventRegistrationModal(); const registerSuccess = useRegisterSuccess(); + const [numberOfMembers, setNumberOfMembers] = useState(currEvent?.memberCount || 1); + let memberInputs = []; + + const [selectedDepartment, setSelectedDepartment] = useState('department') @@ -74,6 +78,13 @@ const EventRegiatrationModal: React.FC = ({ member1: '', member2: '', member3: '', + member4: '', + member5: '', + member6: '', + member7: '', + member8: '', + member9: '', + member10: '', phone: '', name: '', department: '', @@ -82,6 +93,20 @@ const EventRegiatrationModal: React.FC = ({ } }) + for (let i = 1; i <= numberOfMembers; i++) { + memberInputs.push( + + ); + } + const handleDateSelect = (selectedDate: dayjs.Dayjs) => { const formattedDate = selectedDate.toISOString(); setCustomValue('date', formattedDate); @@ -207,31 +232,7 @@ const EventRegiatrationModal: React.FC = ({ subtitle='These will be sent to organizers' center /> - - - - + {memberInputs}
) } diff --git a/app/events/[eventId]/page.tsx b/app/events/[eventId]/page.tsx index 9c03a0e..ee5354c 100644 --- a/app/events/[eventId]/page.tsx +++ b/app/events/[eventId]/page.tsx @@ -43,7 +43,9 @@ const EventPage = async (
& { export type SafeRegistration = Omit & { createdAt: string; + userId: number; + eventId: number; + phone: string; + semester: string; + department: string | null; + member1: string | null; + member2: string | null; + member3: string | null; + member4: string | null; + member5: string | null; + member6: string | null; + member7: string | null; + member8: string | null; + member9: string | null; + member10: string | null; + hasPaid: boolean | null; event: SafeEvent; - }; export type SafeUser = Omit & { diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 43552a6..7fd7b23 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -98,6 +98,13 @@ model Registration { member2 String? member3 String? member4 String? + member5 String? + member6 String? + member7 String? + member8 String? + member9 String? + member10 String? + collegeName String? hasPaid Boolean? @default(false) createdAt DateTime @default(now())