diff --git a/app/(default)/events/EventCard.css b/app/(default)/events/EventCard.css new file mode 100644 index 0000000..20e14a6 --- /dev/null +++ b/app/(default)/events/EventCard.css @@ -0,0 +1,173 @@ +.event-cards-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; + justify-content: center; + margin-bottom: 40px; +} + +.event-card { + border: 1px solid #ddd; + border-radius: 12px; + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); + overflow: hidden; + background-color: #fff; + transition: box-shadow 0.3s ease-in-out, transform 0.3s ease-in-out; + max-width: 400px; + margin: 0 auto; +} + +.event-card:hover { + box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2); + transform: scale(1.05); +} + +.event-container { + text-decoration: none; + color: inherit; + display: flex; + flex-direction: column; +} + +.event-poster-container { + max-height: 220px; + overflow: hidden; + border-bottom: 1px solid #eee; +} + +.event-poster { + width: 100%; + height: auto; + object-fit: cover; + transition: transform 0.3s ease; +} + +.event-poster-container:hover .event-poster { + transform: scale(1.05); +} + +.event-content-container { + padding: 20px; +} + +.event-content-container h3 { + margin: 0 0 12px; + font-size: 1.6em; + color: #333; +} + +.event-content-container p { + margin: 6px 0; + color: #666; + line-height: 1.5; + font-size: 1em; +} + +.event-content-container p:last-child { + color: #999; + font-size: 0.9em; +} + +form { + max-width: 400px; + margin: 20px auto; + padding: 20px; + background-color: #f9f9f9; + border-radius: 12px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +form div { + margin-bottom: 16px; +} + +form label { + display: block; + margin-bottom: 8px; + font-weight: bold; + color: #333; +} + +form input[type="text"], +form input[type="date"], +form textarea { + width: 100%; + padding: 10px; + border: 1px solid #ddd; + border-radius: 8px; + box-sizing: border-box; + font-size: 1em; + color: #333; +} + +form button[type="submit"] { + padding: 10px 20px; + background-color: #007bff; + color: #fff; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 1em; + transition: background-color 0.3s ease; +} + +form button[type="submit"]:hover { + background-color: #0056b3; +} + +button { + display: block; + margin: 60px auto; + padding: 10px 20px; + background-color: #28a745; + color: #fff; + border: none; + border-radius: 8px; + cursor: pointer; + font-size: 1em; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #218838; +} + +h2 { + font-family: 'Arial Narrow Bold', sans-serif; + margin-top: 40px; + padding-bottom: 30px; + font-size: 2.5em; + color: yellow; + text-align: center; +} + +.event-card-inner { + position: relative; + width: 100%; + height: 100%; + transform-style: preserve-3d; + transition: transform 0.6s ease-in-out; +} + +.event-card-front, +.event-card-back { + position: absolute; + width: 100%; + height: 100%; + backface-visibility: hidden; + top: 0; + left: 0; +} + +.event-card-back { + transform: rotateY(180deg); + padding: 20px; + background-color: #000000; + display: flex; + align-items: center; + justify-content: center; +} + +.event-card:hover .event-card-inner { + transform: rotateY(180deg); +} diff --git a/app/(default)/events/Events.css b/app/(default)/events/Events.css deleted file mode 100644 index 289bba4..0000000 --- a/app/(default)/events/Events.css +++ /dev/null @@ -1,124 +0,0 @@ -.container { - padding: 20px; - max-width: 1200px; - margin: 0 auto; - background-color: #000000; - border-radius: 10px; - font-size:medium; -} - -/* Header Styling */ -.header { - text-align: center; - font-size: 2.8rem; - font-weight: 600; /* Slightly bold for emphasis */ - color: #333; /* Dark gray for a softer contrast */ - margin-bottom: 25px; -} - -/* Events Grid Styling */ -.events-grid { - display: flex; - flex-wrap: wrap; - gap: 40px; - justify-content: center; - margin-top: 30px; /* Adds space between h2 and event cards */ -} - -/* Event Card Styling */ -.event-card { - color: #000000; - background-color: #ffffff; - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - padding: 20px; - max-width: 320px; - text-align: center; - transition: transform 0.2s ease, box-shadow 0.2s ease; - border: 3px solid yellow; - display: flex; - flex-direction: column; /* Aligns content vertically */ - align-items: center; /* Centers content horizontally */ - justify-content: center; /* Centers content vertically */ - } - - /* Event Image Styling */ - .event-image { - width: 100%; - max-width: 200px; /* Adjust the maximum width as needed */ - border-radius: 8px; - margin-bottom: 15px; - object-fit: cover; - display: block; /* Ensures the image behaves as a block element */ - } - -/* Event Card Hover Effect */ -.event-card:hover { - transform: scale(1.05); /* Slight scale up on hover */ - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); /* Deeper shadow on hover */ -} - - - -/* h2 Styling */ -h2 { - text-align: center; - margin-top: 40px; - font-size: 2.2rem; - font-weight: 500; - color: rgb(255, 255, 253); - margin-bottom: 30px; /* Adds space between h2 and event cards */ -} - -/* h1 Styling */ -h1 { - text-align: center; - margin-top: 40px; - font-size: 2.2rem; - font-weight: 500; /* Medium weight for balance */ - color: yellow; /* Consistent with header color */ -} - - .container { - padding: 20px; - } - - .header { - text-align: center; - font-size: 2.5rem; - margin-bottom: 20px; - } - - .events-grid { - display: flex; - flex-wrap: wrap; - gap: 40px; - justify-content: center; - } - - .event-card { - background-color: #f8f8f8; - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - padding: 15px; - max-width: 300px; - text-align: center; - transition: transform 0.2s ease; - margin: 10px; /* Adds space around each card */ - } - - .event-card:hover { - transform: scale(1.05); - } - - .event-image { - width: 100%; - border-radius: 8px; - margin-bottom: 10px; - } - - h2 { - text-align: center; - margin-top: 40px; - font-size: 2rem; - } \ No newline at end of file diff --git a/app/(default)/events/page.tsx b/app/(default)/events/page.tsx index 2851739..a2061a1 100644 --- a/app/(default)/events/page.tsx +++ b/app/(default)/events/page.tsx @@ -1,170 +1,318 @@ "use client"; -import React, { useEffect, useState } from "react"; -import { collection, getDocs } from "firebase/firestore"; -import { db } from "@/Firebase"; -import "./Events.css" -import { useRouter } from "next/navigation"; -import { color } from "framer-motion"; -import { onAuthStateChanged } from "firebase/auth"; -import { auth } from "@/Firebase"; - -type Event = { - id: string; - title: string; +import React, { useState, useEffect } from 'react'; +import { db, auth } from '@/Firebase'; +import { collection, addDoc, getDocs, orderBy, query, updateDoc, doc, deleteDoc } from 'firebase/firestore'; +import { onAuthStateChanged } from 'firebase/auth'; +import './EventCard.css'; + +interface Event { + eventName: string; description: string; imageUrl: string; - startDate: Date; - endDate: Date; -}; - -export default function Events() { - const router = useRouter(); - - useEffect(() => { - router.push("/") - }); + startDate: string; + endDate: string; + id?: string; // Add an optional ID field for Firestore document ID +} +const EventCard: React.FC = () => { const [events, setEvents] = useState([]); + const [eventName, setEventName] = useState(''); + const [description, setDescription] = useState(''); + const [imageUrl, setImageUrl] = useState(''); + const [startDate, setStartDate] = useState(''); + const [endDate, setEndDate] = useState(''); + const [formVisible, setFormVisible] = useState(false); + const [editFormVisible, setEditFormVisible] = useState(false); + const [eventToEdit, setEventToEdit] = useState(''); + const [eventDataToEdit, setEventDataToEdit] = useState(null); const [isAdmin, setIsAdmin] = useState(false); + useEffect(() => { - onAuthStateChanged(auth, async (user) => { - if (user) { - //get user uuid - const uid = user.uid; - //check if uuid present in firestore - //if present then set isAdmin to true - const querySnapshot = await getDocs(collection(db, "admin")); -querySnapshot.forEach((doc) => { - if (doc.data().uid === uid) { - setIsAdmin(true); - } -}); - } - } ); - }); + const checkAdminStatus = async () => { + onAuthStateChanged(auth, async (user) => { + if (user) { + const uid = user.uid; + const querySnapshot = await getDocs(collection(db, 'admin')); + querySnapshot.forEach((doc) => { + if (doc.data().uid === uid) { + setIsAdmin(true); + } + }); + } + }); + }; + checkAdminStatus(); + }, []); useEffect(() => { const fetchEvents = async () => { - const querySnapshot = await getDocs(collection(db, "events")); - const eventsData = querySnapshot.docs.map((doc) => ({ - id: doc.id, - ...doc.data(), - })) as Event[]; - setEvents(eventsData); + const q = query(collection(db, 'events'), orderBy('startDate')); + const querySnapshot = await getDocs(q); + const eventsList: Event[] = []; + querySnapshot.forEach((doc) => { + const eventData = doc.data() as Event; + eventData.id = doc.id; // Capture the document ID + eventsList.push(eventData); + }); + console.log(eventsList); // Log events to check data + setEvents(eventsList); }; - fetchEvents(); }, []); - const ongoingEvents = events.filter( - (event) => - new Date(event.startDate) <= new Date() && - new Date(event.endDate) >= new Date() - ); - const futureEvents = events.filter( - (event) => new Date(event.startDate) > new Date() - ); - const pastEvents = events.filter( - (event) => new Date(event.endDate) < new Date() - ); + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); - return ( - <> -
-

Welcome to Point Blank

- -

Ongoing Events

-
-
- Sih registrations -

Sih registrations

-

Description for Sih registrations

-
-
+ const newEvent: Event = { + eventName, + description, + imageUrl, + startDate, + endDate, + }; -

Future Events

-
-
- Pb recruitment + try { + await addDoc(collection(db, 'events'), newEvent); -

Pb recruitment

-

Description for Pb recruitment

-
-
- Pbctf -

Pbctf

-

Description for Pbctf

-
-
- Pbthon -

Pbthon

-

Description for Pbthon

-
-
- -

Past Events

-
-
- Pbctf 2.0 -

Pbctf 2.0

-

Description for Pbctf 2.0

-
-
- Pb recruitment 2023-24 -

Pb recruitment 2023-24

-

Description for Pb recruitment 2023-24

-
-
- Pb hustle -

Pb hustle

-

Description for Pb hustle

-
-
- - {isAdmin && ( -
-

Create a New Event

-
- - - - - - -
-
- )} -
- - ); -} + setEvents((prevEvents) => + [...prevEvents, newEvent].sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime()) + ); + setEventName(''); + setDescription(''); + setImageUrl(''); + setStartDate(''); + setEndDate(''); + setFormVisible(false); + } catch (error) { + console.error('Error adding document: ', error); + } + }; + const handleEditSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!eventDataToEdit || !eventDataToEdit.id) return; + try { + const eventRef = doc(db, 'events', eventDataToEdit.id); + await updateDoc(eventRef, { + eventName: eventToEdit, + description: description, + imageUrl: imageUrl, + startDate: startDate, + endDate: endDate, + }); + setEvents((prevEvents) => + prevEvents.map((event) => + event.id === eventDataToEdit.id + ? { ...eventDataToEdit, eventName, description, imageUrl, startDate, endDate } + : event + ).sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime()) + ); + setEditFormVisible(false); + setEventToEdit(''); + } catch (error) { + console.error('Error updating document: ', error); + } + }; + const handleRemoveEvent = async () => { + if (!eventDataToEdit || !eventDataToEdit.id) return; + try { + await deleteDoc(doc(db, 'events', eventDataToEdit.id)); + setEvents((prevEvents) => prevEvents.filter((event) => event.id !== eventDataToEdit.id)); + setEditFormVisible(false); + setEventToEdit(''); + } catch (error) { + console.error('Error deleting document: ', error); + } + }; + const handleEventToEditChange = (e: React.ChangeEvent) => { + const eventName = e.target.value; + setEventToEdit(eventName); + const selectedEvent = events.find((event) => event.eventName === eventName); + if (selectedEvent) { + setEventDataToEdit(selectedEvent); + setDescription(selectedEvent.description); + setImageUrl(selectedEvent.imageUrl); + setStartDate(selectedEvent.startDate); + setEndDate(selectedEvent.endDate); + } else { + setEventDataToEdit(null); + } + }; + const currentDate = new Date(); + const upcomingEvents = events.filter(event => new Date(event.startDate) > currentDate); + const ongoingEvents = events.filter(event => new Date(event.startDate) <= currentDate && new Date(event.endDate) >= currentDate); + const pastEvents = events.filter(event => new Date(event.endDate) < currentDate); + const renderEventCards = (events: Event[]) => { + if (!events || events.length === 0) { + return

No events to display

; + } + return ( +
+ {events.map((event, index) => ( +
+
+
+
+
+ {event.eventName} +
+
+

{event.eventName}

+

{event.startDate} {event.endDate && ` - ${event.endDate}`}

+
+
+
+
+

{event.description}

+
+
+
+ ))} +
+ ); + }; -// import EventComponent from "@/components/eventcards" + return ( +
+ {isAdmin && ( + <> + + {formVisible && ( +
+
+ + setEventName(e.target.value)} + required + /> +
+
+ +