Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Search bar and filters #305

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/components/EventDetails/EventDetails.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
117 changes: 35 additions & 82 deletions src/components/EventDetails/EventDetails.tsx
Original file line number Diff line number Diff line change
@@ -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([]);
Expand All @@ -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);
Expand All @@ -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) &&
Expand All @@ -75,70 +68,56 @@ 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 (
<>
<PageTitle title={`${title} | Lupo Skill`} />
<div>
{isLoading ? (
<div
className="d-flex justify-content-center align-items-center"
style={{
paddingTop: "9.5em",
}}
>
<div className="d-flex justify-content-center align-items-center" style={{ paddingTop: "9.5em" }}>
<Spinner animation="border" />
</div>
) : (
<Container className="event-detailcontainer">
<Row>
<Col>
<Card className="p-3 shadow mt-2">
<Card.Img
variant="top"
src={banner_Image}
alt="Event Header"
className="card-image"
/>
<Card.Img variant="top" src={banner_Image} alt="Event Header" className="card-image" />
<Card.Body>
<Card.Title>{title}</Card.Title>
<Container>
<Row className="align-items-center mb-2">
<Col xs="auto">
<i className="bi bi-calendar"></i>
</Col>
<Col xs="auto"><i className="bi bi-calendar"></i></Col>
<Col xs="auto">{date}</Col>
<Col xs="auto">
<i className="bi bi-clock"></i>
</Col>
<Col xs="auto"><i className="bi bi-clock"></i></Col>
<Col xs="auto">{time}</Col>
</Row>
<Row>
<Col>

Host: <a href={`#/profile/${host}`} className="link-primary">{hostName}</a>

Host:{" "}
<a href={"/profile/" + host} className="link-primary">
{hostName}
</a>

</Col>
</Row>
<Row>
Expand All @@ -147,9 +126,7 @@ const EventDetails = () => {
<Row>
<Col>
{tags.map((tag, index) => (
<span key={index} className="tag badge me-2">
{tag}
</span>
<span key={index} className="tag badge me-2">{tag}</span>
))}
</Col>
</Row>
Expand All @@ -165,40 +142,16 @@ const EventDetails = () => {
<Card.Body>
<div>
{isHost ? (
<>
<InputGroup className="mb-3">
<InputGroup.Text>
Google Meet link :
</InputGroup.Text>
<FormControl
type="text"
value={googleMeetLink}
onChange={(e) =>
setGoogleMeetLink(e.target.value)
}
/>
<Button
onClick={() => {
addMeetingLink();
}}
variant="primary"
>
Add Link
</Button>
</InputGroup>
</>
<InputGroup className="mb-3">
<InputGroup.Text>Google Meet link :</InputGroup.Text>
<FormControl type="text" value={googleMeetLink} onChange={(e) => setGoogleMeetLink(e.target.value)} />
<Button onClick={addMeetingLink} variant="primary">Add Link</Button>
</InputGroup>
) : (
<>
<span>
Google Meet link :{" "}
{googleMeetLink ===
"Nothing yet, ask the host to add one" ? (
"Nothing yet, ask the host to add one"
) : (
<a href={googleMeetLink} className="link-primary">
{googleMeetLink}
</a>
)}
</>
{googleMeetLink === "Nothing yet, ask the host to add one" ? googleMeetLink : <a href={googleMeetLink} className="link-primary">{googleMeetLink}</a>}
</span>
)}
</div>
</Card.Body>
Expand Down
26 changes: 26 additions & 0 deletions src/components/Events/Events.css
Original file line number Diff line number Diff line change
@@ -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;
}

117 changes: 117 additions & 0 deletions src/components/Events/Events.tsx
Original file line number Diff line number Diff line change
@@ -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<any[]>([]);
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 (
<>
<PageTitle title="Events | Lupo Skill" />
<Container className="mt-5">
<InputGroup className="mb-3">
<FormControl
placeholder="Search by tags"
value={searchTags}
onChange={(e) => setSearchTags(e.target.value)}
/>
<FormControl
type="date"
placeholder="Search by date"
value={searchDate}
onChange={(e) => setSearchDate(e.target.value)}
/>
<Button variant="primary" onClick={handleSearch}>
Search
</Button>
</InputGroup>
</Container>
<div className="text-center mt-4">
{isLoading ? (
<Spinner animation="border" />
) : (
<div>
{eventCardsData
.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage)
.map((event) => (
<EventCard key={event.id} event={event} />
))}
<Pagination className="justify-content-center mt-4">
<Pagination.First onClick={() => handlePageChange(1)} disabled={currentPage === 1} />
<Pagination.Prev onClick={() => handlePageChange(currentPage - 1)} disabled={currentPage === 1} />
{[...Array(totalPages).keys()].map((number) => (
<Pagination.Item
key={number + 1}
active={number + 1 === currentPage}
onClick={() => handlePageChange(number + 1)}
>
{number + 1}
</Pagination.Item>
))}
<Pagination.Next onClick={() => handlePageChange(currentPage + 1)} disabled={currentPage === totalPages} />
<Pagination.Last onClick={() => handlePageChange(totalPages)} disabled={currentPage === totalPages} />
</Pagination>
</div>
)}
</div>
</>
);
};

export default Events;
Loading