diff --git a/src/components/EventDetails/EventDetails.css b/src/components/EventDetails/EventDetails.css index 12637d9..3e1c846 100644 --- a/src/components/EventDetails/EventDetails.css +++ b/src/components/EventDetails/EventDetails.css @@ -9,22 +9,20 @@ .card-image { pointer-events: none; border-radius: 10px 10px 10px 10px; - /* height: 450px; */ object-fit: cover; } @media (min-width: 1024px) { - .card_image { + .card-image { height: 450px; } } @media (min-width: 768px) { - .card_image { + .card-image { height: 200px; } } - @media (max-width: 767px) { - .card_image { + .card-image { height: 150px; } } diff --git a/src/components/EventDetails/EventDetails.tsx b/src/components/EventDetails/EventDetails.tsx index 8b49075..a6a1758 100644 --- a/src/components/EventDetails/EventDetails.tsx +++ b/src/components/EventDetails/EventDetails.tsx @@ -1,31 +1,18 @@ import React, { useEffect, useState } from "react"; -import { - Container, - Row, - Col, - Button, - Badge, - Card, - FormControl, - InputGroup, - Spinner, -} from "react-bootstrap"; -import { Image as BootstrapImage } from "react-bootstrap"; -import "./EventDetails.css"; -import bannerImage from "../image_assets/bannerImage.png"; -import { Link, useParams } from "react-router-dom"; +import { Container, Row, Col, Button, Card, FormControl, InputGroup, Spinner } from "react-bootstrap"; +import { useParams } from "react-router-dom"; import { ref, get, update } from "firebase/database"; -import { Zoom, toast } from "react-toastify"; import { database } from "../../firebaseConf"; import PageTitle from "../../utils/PageTitle"; import moment from "moment"; +import "./EventDetails.css"; const EventDetails = () => { const { id } = useParams(); const userUid = localStorage.getItem("userUid"); const [isHost, setIsHost] = useState(false); const [isLoading, setIsLoading] = useState(true); - const [banner_Image, setBannerImage] = useState(bannerImage); + const [banner_Image, setBannerImage] = useState(""); const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); const [tags, setTags] = useState([]); @@ -35,21 +22,23 @@ const EventDetails = () => { const [hostName, setHostName] = useState(""); const [lastEdited, setLastEdited] = useState(null); const [registeredUsers, setRegisteredUsers] = useState([]); - const [googleMeetLink, setGoogleMeetLink] = useState( - "Nothing yet, ask the host to add one" - ); + const [googleMeetLink, setGoogleMeetLink] = useState("Nothing yet, ask the host to add one"); useEffect(() => { + + if (!userUid) { + window.location.href = "#/dashboard"; + if (userUid == null) { window.location.href = "/dashboard"; toast.warn("You are not signed in", { transition: Zoom }); + } const fetchData = async () => { - const eventRef = ref(database, "events/" + id); + const eventRef = ref(database, `events/${id}`); const snapshot = await get(eventRef); if (snapshot.exists()) { const eventData = snapshot.val(); - setBannerImage(eventData.banner); setTitle(eventData.title); setDescription(eventData.description); @@ -66,6 +55,10 @@ const EventDetails = () => { if (eventData.registrants) { setRegisteredUsers(eventData.registrants.split(",")); + if (!eventData.registrants.split(",").includes(userUid) && userUid !== eventData.host) { + window.location.href = "#/dashboard"; + + if ( (!eventData.registrants.split(",").includes(userUid) || userUid == null) && @@ -75,25 +68,21 @@ const EventDetails = () => { toast.warn("You are not registered for this event", { transition: Zoom, }); + } } if (eventData.googleMeetLink) { setGoogleMeetLink(eventData.googleMeetLink); } setIsLoading(false); - } else { - toast.error("Event not found", { transition: Zoom }); } }; fetchData(); }, [id, userUid]); const addMeetingLink = () => { - const eventRef = ref(database, "events/" + id); - update(eventRef, { - googleMeetLink: googleMeetLink, - }); - toast.success("Google Meet link added successfully", { transition: Zoom }); + const eventRef = ref(database, `events/${id}`); + update(eventRef, { googleMeetLink }); }; return ( @@ -101,12 +90,7 @@ const EventDetails = () => {
{isLoading ? ( -
+
) : ( @@ -114,31 +98,26 @@ const EventDetails = () => { - + {title} - - - + {date} - - - + {time} + + Host: {hostName} + Host:{" "} {hostName} + @@ -147,9 +126,7 @@ const EventDetails = () => { {tags.map((tag, index) => ( - - {tag} - + {tag} ))} @@ -165,40 +142,16 @@ const EventDetails = () => {
{isHost ? ( - <> - - - Google Meet link : - - - setGoogleMeetLink(e.target.value) - } - /> - - - + + Google Meet link : + setGoogleMeetLink(e.target.value)} /> + + ) : ( - <> + Google Meet link :{" "} - {googleMeetLink === - "Nothing yet, ask the host to add one" ? ( - "Nothing yet, ask the host to add one" - ) : ( - - {googleMeetLink} - - )} - + {googleMeetLink === "Nothing yet, ask the host to add one" ? googleMeetLink : {googleMeetLink}} + )}
diff --git a/src/components/Events/Events.css b/src/components/Events/Events.css new file mode 100644 index 0000000..f74a4e3 --- /dev/null +++ b/src/components/Events/Events.css @@ -0,0 +1,26 @@ +.event-card { + border-radius: 10px; + position: relative; + overflow: hidden; + } + .event-card img { + height: 200px; + object-fit: cover; + } + .event-card-info { + display: flex; + justify-content: space-between; + margin-bottom: 10px; + } + .tag { + background-color: rgb(233, 255, 199) !important; + border-radius: 100px !important; + border: 1px solid green; + color: #555 !important; + transition: 200ms; + } + .tag:hover { + cursor: pointer; + background-color: rgb(201, 255, 121) !important; + } + \ No newline at end of file diff --git a/src/components/Events/Events.tsx b/src/components/Events/Events.tsx new file mode 100644 index 0000000..fe3a803 --- /dev/null +++ b/src/components/Events/Events.tsx @@ -0,0 +1,117 @@ +import React, { useEffect, useState } from "react"; +import { Container, InputGroup, FormControl, Button, Spinner, Pagination } from "react-bootstrap"; +import { getDatabase, ref, get } from "firebase/database"; +import PageTitle from "../../utils/PageTitle"; +import EventCard from "../Cards/EventCard/EventCard"; +import "./Events.css"; + +const Events: React.FC = () => { + const [eventCardsData, setEventCardsData] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [searchTags, setSearchTags] = useState(""); + const [searchDate, setSearchDate] = useState(""); + const [currentPage, setCurrentPage] = useState(1); + const itemsPerPage = 5; + const [totalPages, setTotalPages] = useState(1); + + useEffect(() => { + const fetchData = async () => { + const db = getDatabase(); + const eventsRef = ref(db, "events"); + const snapshot = await get(eventsRef); + if (snapshot.exists()) { + const eventsData = snapshot.val(); + const fetchedEvents = Object.keys(eventsData).map((key) => ({ + id: key, + ...eventsData[key], + })); + setEventCardsData(fetchedEvents); + setTotalPages(Math.ceil(fetchedEvents.length / itemsPerPage)); + } else { + console.log("No data available"); + } + setIsLoading(false); + }; + + fetchData(); + }, []); + + const handleSearch = async () => { + setIsLoading(true); + const db = getDatabase(); + const searchRef = ref(db, "events"); + const snapshot = await get(searchRef); + if (snapshot.exists()) { + const eventsData = snapshot.val(); + const filteredEvents = Object.keys(eventsData) + .map((key) => ({ id: key, ...eventsData[key] })) + .filter((event) => { + const matchesTags = !searchTags || event.tags.toLowerCase().includes(searchTags.toLowerCase()); + const matchesDate = !searchDate || event.date === searchDate; + return matchesTags && matchesDate; + }); + + setEventCardsData(filteredEvents); + setTotalPages(Math.ceil(filteredEvents.length / itemsPerPage)); + } + setIsLoading(false); + }; + + const handlePageChange = (pageNumber: number) => { + setCurrentPage(pageNumber); + }; + + return ( + <> + + + + setSearchTags(e.target.value)} + /> + setSearchDate(e.target.value)} + /> + + + +
+ {isLoading ? ( + + ) : ( +
+ {eventCardsData + .slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage) + .map((event) => ( + + ))} + + handlePageChange(1)} disabled={currentPage === 1} /> + handlePageChange(currentPage - 1)} disabled={currentPage === 1} /> + {[...Array(totalPages).keys()].map((number) => ( + handlePageChange(number + 1)} + > + {number + 1} + + ))} + handlePageChange(currentPage + 1)} disabled={currentPage === totalPages} /> + handlePageChange(totalPages)} disabled={currentPage === totalPages} /> + +
+ )} +
+ + ); +}; + +export default Events; diff --git a/src/firebaseConf.ts b/src/firebaseConf.ts index 0aaafdc..309d0cb 100644 --- a/src/firebaseConf.ts +++ b/src/firebaseConf.ts @@ -1,23 +1,21 @@ +import { initializeApp } from "firebase/app"; import { GoogleAuthProvider, getAuth, signInWithPopup, signOut, } from "firebase/auth"; -import firebase from "firebase/compat/app"; -import "firebase/compat/auth"; -import "firebase/compat/database"; -import "firebase/storage"; import { getFirestore } from "firebase/firestore"; import { getDatabase } from "firebase/database"; import { getStorage } from "firebase/storage"; import { Zoom, toast } from "react-toastify"; const firebaseConfig = { - // firebase config + // Your firebase config }; -const app = firebase.initializeApp(firebaseConfig); +const app = initializeApp(firebaseConfig); + // Initialize Firebase authentication const auth = getAuth(app); @@ -32,11 +30,13 @@ const storage = getStorage(app); const provider = new GoogleAuthProvider(); -// whenever a user interacts with the provider, we force them to select an account +// Whenever a user interacts with the provider, we force them to select an account provider.setCustomParameters({ - prompt: "select_account ", + prompt: "select_account", }); + const signInWithGooglePopup = () => signInWithPopup(auth, provider); + const signOutUser = () => { signOut(auth) .then(() => { @@ -50,6 +50,7 @@ const signOutUser = () => { console.error(error); }); }; + export { auth, firestore, diff --git a/src/utils/searchEvents.ts b/src/utils/searchEvents.ts new file mode 100644 index 0000000..d4e8919 --- /dev/null +++ b/src/utils/searchEvents.ts @@ -0,0 +1,18 @@ +import { getDatabase, ref, get } from "firebase/database"; + +export const searchEvents = async (tags: string, date: string) => { + const db = getDatabase(); + const eventsRef = ref(db, "events"); + const snapshot = await get(eventsRef); + if (snapshot.exists()) { + const eventsData = snapshot.val(); + return Object.keys(eventsData) + .map((key) => ({ id: key, ...eventsData[key] })) + .filter((event) => { + const matchesTags = !tags || event.tags.toLowerCase().includes(tags.toLowerCase()); + const matchesDate = !date || event.date === date; + return matchesTags && matchesDate; + }); + } + return []; +};