Skip to content

Commit

Permalink
Events & event registration
Browse files Browse the repository at this point in the history
  • Loading branch information
Tamoziit committed Nov 17, 2024
1 parent df02aea commit 1dcb088
Show file tree
Hide file tree
Showing 22 changed files with 899 additions and 23 deletions.
28 changes: 27 additions & 1 deletion backend/controllers/events.controller.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import clubsData from "../data/clubs.data.json" assert { type: 'json' };
import eventsData from "../data/events.data.json" assert { type: 'json' };
import Membership from "../models/order.model.js";
import Payment from "../models/payment.model.js";

Expand All @@ -19,7 +20,7 @@ export const getClubById = (req, res) => {
if (data) {
res.status(200).json(data);
} else {
res.status(400).json({ error: "No club such found" });
res.status(400).json({ error: "No such club found" });
}
} catch (error) {
console.log(error.message);
Expand All @@ -46,4 +47,29 @@ export const getMyClubs = async (req, res) => {
console.log(err.message)
res.status(500).json({ error: "Internal Server Error" });
}
}

export const getEvents = (req, res) => {
try {
const data = eventsData.events;
return res.status(200).json(data);
} catch (error) {
console.log(error.message);
res.status(500).json({ error: "Internal Server error" });
}
}

export const getEventById = (req, res) => {
try {
const id = req.params.id;
const data = eventsData.events.find(event => event.id === id);
if (data) {
res.status(200).json(data);
} else {
res.status(400).json({ error: "No such event found" });
}
} catch (error) {
console.log(error.message);
res.status(500).json({ error: "Internal Server error" });
}
}
118 changes: 118 additions & 0 deletions backend/controllers/registration.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import stripe from "../stripe/stripeInit.js";
import eventsData from "../data/events.data.json" assert { type: 'json' };
import Event from "../models/event.model.js";
import Registration from "../models/registration.model.js";

export const registrationHandler = async (req, res) => {
const baseUrl = process.env.BASE_URL;
const { id, product_name, product_description, price, imageUrl, team_name, team_lead_name, team_lead_phone, lead_institute, members } = req.body;

try {
const session = await stripe.checkout.sessions.create({
line_items: [
{
price_data: {
currency: 'inr',
product_data: {
name: product_name,
description: product_description,
images: [imageUrl]
},
unit_amount: price * 100
},
quantity: 1
}
],
mode: 'payment',
phone_number_collection: {
enabled: true
},
success_url: `${baseUrl}/complete-registration?session_id={CHECKOUT_SESSION_ID}&order_id=${id}`,
cancel_url: `${baseUrl}/cancel-registration?reason=user_cancelled`,
metadata: {
orderId: id,
team_name,
team_lead_name,
team_lead_phone,
lead_institute,
members: JSON.stringify(members)
},
allow_promotion_codes: true
});

console.log(session.url);
res.json({ url: session.url });
} catch (err) {
console.log("Error in registrationHandler", err.message);
res.status(500).json({ error: "Internal Server Error" });
}
};

export const confirmRegistration = async (req, res) => {
try {
const { order_id, session_id, user_id } = req.body;

const product = eventsData.events.find(event => event.id === order_id);
const session = await stripe.checkout.sessions.retrieve(session_id, {
expand: ['payment_intent.payment_method']
});

if (product && session) {
const { team_name, team_lead_name, team_lead_phone, lead_institute, members } = session.metadata;
console

const newPayment = new Event({
product_id: order_id,
payment_intent_id: session.payment_intent.id,
name: product.name,
image_url: product.img,
club: product.club,
desc: product.desc,
institute: product.institute,
amount: session.payment_intent.amount / 100,
customer_name: session.customer_details.name,
customer_email: session.customer_details.email,
customer_mobile: session.customer_details.phone,
team_name,
team_lead_name,
team_lead_phone,
lead_institute,
members: JSON.parse(members)
});

if (newPayment) {
let order = await Registration.findOne({ user: user_id });
if (!order) {
order = await Registration.create({ user: user_id });
}
order.events.push(newPayment._id);

await Promise.all([order.save(), newPayment.save()]);
} else {
return res.status(400).json({ error: "Could not process payment, Refund will be processed within 5-7 days" });
}

res.status(200).json({
product_id: newPayment.product_id,
name: newPayment.name,
image_url: newPayment.image_url,
club: newPayment.club,
desc: newPayment.desc,
institute: newPayment.institute,
amount: newPayment.amount,
customer_name: newPayment.customer_name,
customer_email: newPayment.customer_email,
customer_mobile: newPayment.customer_mobile,
team_name: newPayment.team_name,
team_lead_name: newPayment.team_lead_name,
team_lead_phone: newPayment.team_lead_phone,
lead_institute: newPayment.lead_institute,
members: newPayment.members,
});
}
} catch (err) {
console.log(err.message);
res.status(500).json({ error: "Internal Server Error" });
}
};

34 changes: 34 additions & 0 deletions backend/data/events.data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"events": [
{
"id": "EV_ENSY1234.CR",
"name": "JOSH",
"club": "Synergy",
"desc": "Inter College Cricket Tournament",
"institute": "Techno Main Saltlake",
"img": "https://wallpapercave.com/wp/wp13117884.jpg",
"price_pool": "Winner: ₹10K, Runners-up: ₹5K",
"fees": 300
},
{
"id": "EV_ENCH4567.FB",
"name": "The Beautiful Game",
"club": "Charisma",
"desc": "Inter College Football Tournament",
"institute": "Techno Main Saltlake",
"img": "https://i.pinimg.com/736x/33/31/0a/33310a6aa68f2d817ce0cc094dca86b0.jpg",
"price_pool": "Winner: ₹10K, Runners-up: ₹5K",
"fees": 300
},
{
"id": "EV_ENFI7890.BB",
"name": "Ballers",
"club": "Finnesse",
"desc": "Inter College Basketball Tournament",
"institute": "Techno Main Saltlake",
"img": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRVTuplO4f9UQv3vsxUYgno6CfHrf7DzfQAZw&s",
"price_pool": "Winner: ₹10K, Runners-up: ₹5K",
"fees": 300
}
]
}
93 changes: 93 additions & 0 deletions backend/models/event.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import mongoose from "mongoose";

const EventSchema = new mongoose.Schema(
{
product_id: {
type: String,
required: true,
},
payment_intent_id: {
type: String,
required: true,
},
name: {
type: String,
required: true,
min: 2,
max: 50,
},
image_url: {
type: String,
required: true,
min: 2,
max: 50,
},
club: {
type: String,
required: true,
},
desc: {
type: String,
required: true,
},
institute: {
type: String,
required: true,
},
amount: {
type: Number,
required: true,
},
customer_name: {
type: String,
required: true,
},
customer_email: {
type: String,
required: true,
},
customer_mobile: {
type: String,
required: true,
min: 10,
max: 10,
},
team_name: {
type: String,
required: true,
},
team_lead_name: {
type: String,
required: true,
},
team_lead_phone: {
type: String,
required: true,
min: 10,
max: 10,
},
lead_institute: {
type: String,
required: true,
},
members: [
{
name: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
min: 10,
max: 10,
}
}
],
},
{ timestamps: true }
);

const Event = mongoose.model("Event", EventSchema);

export default Event;
20 changes: 20 additions & 0 deletions backend/models/registration.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import mongoose from "mongoose";

const RegistrationSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
},
events: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Event",
default: []
}
]
}, { timestamps: true });

const Registration = mongoose.model("Registration", RegistrationSchema);

export default Registration;
4 changes: 3 additions & 1 deletion backend/routes/event.routes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import express from "express";
import { getClubById, getClubs, getMyClubs } from "../controllers/events.controller.js";
import { getClubById, getClubs, getEventById, getEvents, getMyClubs } from "../controllers/events.controller.js";

const router = express();

router.get("/get-clubs", getClubs);
router.get("/get-club/:id", getClubById);
router.get("/my-clubs/:id", getMyClubs);
router.get("/get-events", getEvents);
router.get("/get-event/:id", getEventById);

export default router;
3 changes: 3 additions & 0 deletions backend/routes/payment.routes.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import express from "express";
import { confirmMembership, paymentHandler } from "../controllers/payment.controller.js";
import { confirmRegistration, registrationHandler } from "../controllers/registration.controller.js";

const router = express.Router();

router.post("/pay", paymentHandler);
router.post("/confirm-membership", confirmMembership);
router.post("/register", registrationHandler);
router.post("/confirm-registration", confirmRegistration);

export default router;
8 changes: 6 additions & 2 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import Registration from "./pages/registration/Registration";
import NoticeBoard from "./pages/notice-board/NoticeBoard";
import CompletePayment from "./pages/payments/CompletePayment";
import CancelPayment from "./pages/payments/CancelPayment";
import CompleteRegistration from "./pages/registration/CompleteRegistration";
import CancelRegistration from "./pages/registration/CancelRegistration";

function App() {
const { authUser } = useAuthContext();
Expand All @@ -22,10 +24,12 @@ function App() {
<Route path="/signup" element={authUser ? <Navigate to="/" /> : <Signup />} />
<Route path="/login" element={authUser ? <Navigate to="/" /> : <Login />} />
<Route path="/events" element={authUser ? <Events /> : <Navigate to="/login" />} />
<Route path="/register" element={authUser ? <Registration /> : <Navigate to="/login" />} />
<Route path="/register/:id" element={authUser ? <Registration /> : <Navigate to="/login" />} />
<Route path="/notice-board" element={authUser ? <NoticeBoard /> : <Navigate to="/login" />} />
<Route path="/complete-payment" element={authUser ? <CompletePayment /> : <Navigate to="/login" />} />
<Route path="/cancel-apyment" element={authUser ? <CancelPayment /> : <Navigate to="/login" />} />
<Route path="/cancel-payment" element={authUser ? <CancelPayment /> : <Navigate to="/login" />} />
<Route path="/complete-registration" element={authUser ? <CompleteRegistration /> : <Navigate to="/login" />} />
<Route path="/cancel-registration" element={authUser ? <CancelRegistration /> : <Navigate to="/login" />} />
</Routes>

<Toaster />
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/components/EventCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable react/prop-types */
import { MdSportsCricket } from "react-icons/md";
import { IoMdFootball } from "react-icons/io";
import { Link } from "react-router-dom";

const EventCard = ({ event }) => {
return (
<div className="flex flex-col gap-2 items-center bg-green-500/30 backdrop-blur-lg p-3 rounded-lg shadow-lg border border-green-500/20 hover:border-4">
<img src="logo.png" alt="logo" className="w-[300px] h-[70px]" />
<img src={event.img} alt={event.id} className="w-[250px] h-[220px] rounded-md" />

<div className="flex flex-col gap-1 items-center justify-center">
<span className="text-lg font-semibold text-gray-700">{event.club} presents</span>
<span className="text-xl font-bold">{event.name}</span>
<span className="text-lg font-semibold text-gray-700">{event.desc}</span>
<span className="text-gray-600">{event.price_pool}</span>
<span className="text-gray-600">Registration Fees: ₹{event.fees}</span>
</div>

<Link
className="flex items-center gap-2 rounded-md bg-green-700 hover:bg-green-500 text-white text-lg p-2 w-[90%] justify-center mt-2"
to={`/register/${event.id}`}
><MdSportsCricket /> Register Now <IoMdFootball /></Link>
</div>
)
}

export default EventCard;
Loading

0 comments on commit 1dcb088

Please sign in to comment.