262 lines
18 KiB
JavaScript
262 lines
18 KiB
JavaScript
'use client'
|
|
import Link from 'next/link'
|
|
import moment from "moment";
|
|
import { useState } from "react"
|
|
import { events } from "@/utility/constant.utils"; // <-- import the events array here
|
|
|
|
export default function UpcomingEventData() {
|
|
const [currentMonth, setCurrentMonth] = useState(moment());
|
|
|
|
// Get start and end of current month
|
|
const startOfMonth = currentMonth.clone().startOf("month");
|
|
const endOfMonth = currentMonth.clone().endOf("month");
|
|
|
|
// Generate calendar days
|
|
const daysInMonth = [];
|
|
for (let i = 0; i < startOfMonth.day(); i++) {
|
|
daysInMonth.push(null);
|
|
}
|
|
for (let i = 1; i <= endOfMonth.date(); i++) {
|
|
daysInMonth.push(moment(currentMonth).date(i));
|
|
}
|
|
|
|
// Get events for a given date
|
|
const getEventForDate = (date) => {
|
|
if (!date) return [];
|
|
const dateString = date.format("YYYY-MM-DD");
|
|
const dateStringDMY = date.format("DD/MM/YYYY");
|
|
return events.filter(event => {
|
|
if (!event.date) return false;
|
|
return event.date === dateString || event.date.includes(dateString) || event.date.includes(dateStringDMY);
|
|
});
|
|
};
|
|
|
|
const formatEventDate = (dateStr) => {
|
|
if (!dateStr) return "";
|
|
const m = moment(dateStr);
|
|
if (m.isValid()) {
|
|
return m.format("ddd, MMM DD, YYYY");
|
|
}
|
|
return dateStr;
|
|
};
|
|
|
|
// Navigate months
|
|
const handleMonthChange = (direction) => {
|
|
setCurrentMonth(currentMonth.clone().add(direction, "months"));
|
|
};
|
|
|
|
return (
|
|
<div className="event3-section-area sp4">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-lg-6 m-auto">
|
|
<div className="event2-header heading5 text-center space-margin60">
|
|
<h2 className="text-anime-style-3">Events</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="row">
|
|
{/* Calendar (left side) */}
|
|
<div className="col-12 col-lg-3">
|
|
<div className="d-flex justify-content-between align-items-center">
|
|
<button
|
|
className="vl-btn4"
|
|
onClick={() => handleMonthChange(-1)}
|
|
>
|
|
Prev
|
|
</button>
|
|
<span className="mx-3 fw-700">
|
|
{currentMonth.format("MMMM YYYY")}
|
|
</span>
|
|
<button
|
|
className="vl-btn4"
|
|
onClick={() => handleMonthChange(1)}
|
|
>
|
|
Next
|
|
</button>
|
|
</div>
|
|
|
|
<table className="table table-bordered mt-4" style={{ tableLayout: "fixed" }}>
|
|
<thead>
|
|
<tr>
|
|
{["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((day, index) => (
|
|
<th key={index} className="text-center">
|
|
{day}
|
|
</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{Array.from({ length: Math.ceil(daysInMonth.length / 7) }, (_, rowIndex) => (
|
|
<tr key={rowIndex}>
|
|
{daysInMonth
|
|
.slice(rowIndex * 7, (rowIndex + 1) * 7)
|
|
.map((day, index) => {
|
|
const eventList = getEventForDate(day);
|
|
return (
|
|
<td
|
|
key={index}
|
|
style={{
|
|
cursor: day ? "default" : "not-allowed",
|
|
backgroundColor: eventList.length > 0 ? "#ce2029" : "white",
|
|
color: eventList.length > 0 ? "white" : "black",
|
|
}}
|
|
title={
|
|
eventList.length > 0
|
|
? eventList.map(e => e.title).join("\n")
|
|
: ""
|
|
}
|
|
>
|
|
{day ? (
|
|
<div style={{ width: "100%", height: "100%" }}>
|
|
<span className="text-end d-block">{day.date()}</span>
|
|
</div>
|
|
) : (
|
|
""
|
|
)}
|
|
</td>
|
|
);
|
|
})}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div className="col-lg-9" data-aos="fade-up" data-aos-duration={1000}>
|
|
<div className="tab-content" id="pills-tabContent">
|
|
<div className={"tab-pane fade show active tab-pane fade"} id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab" tabIndex={0}>
|
|
<div className="event-widget-area">
|
|
{events.map((event, idx) => {
|
|
const isEven = (idx + 1) % 2 === 0;
|
|
|
|
return (
|
|
<div key={event.id} className="mb-5">
|
|
<div className="row align-items-center">
|
|
<div className="col-lg-1" />
|
|
<div className="col-lg-10 m-auto">
|
|
<div className="event2-boxarea box1 d-flex flex-wrap align-items-center">
|
|
<h1 className="active me-3">{String(idx + 1).padStart(2, "0")}</h1>
|
|
|
|
{!isEven ? (
|
|
<>
|
|
<div className="col-lg-5">
|
|
<div className="img1">
|
|
<img src={event.image} alt={event.title} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="col-lg-1" />
|
|
|
|
<div className="col-lg-6">
|
|
<div className="content-area">
|
|
<ul>
|
|
<li>
|
|
<span className='d-flex g-3 metered-data'>
|
|
<img src={event.time ? "/assets/img/icons/clock1.svg" : "/assets/img/icons/calender1.svg"} alt={event.time ? "clock" : "calendar"} />{" "}
|
|
{event.time ? `${event.time} - ` : ""}
|
|
{formatEventDate(event.date)}
|
|
</span>
|
|
</li>
|
|
{event.location && event.location.trim() && (
|
|
<li>
|
|
<span className='d-flex g-3 metered-data'>
|
|
<img src="/assets/img/icons/location1.svg" alt="" />{" "}
|
|
{event.location}
|
|
</span>
|
|
</li>
|
|
)}
|
|
</ul>
|
|
<div className="space20" />
|
|
<Link href={event.link || "#"} className="head">{event.title}</Link>
|
|
<div className="space24" />
|
|
<p
|
|
style={{
|
|
display: '-webkit-box',
|
|
WebkitLineClamp: 2,
|
|
WebkitBoxOrient: 'vertical',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
}}
|
|
>
|
|
{event.desc}
|
|
</p>
|
|
|
|
<div className="space24" />
|
|
<div className="btn-area1">
|
|
<Link href={event.url || "#"} className="vl-btn3" target='_blank'>
|
|
<span className="demo">{event.btnText || "Online Tickets"}</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<>
|
|
<div className="col-lg-6">
|
|
<div className="content-area">
|
|
<ul>
|
|
<li>
|
|
<span className='d-flex g-3 metered-data'>
|
|
<img src={event.time ? "/assets/img/icons/clock1.svg" : "/assets/img/icons/calender1.svg"} alt={event.time ? "clock" : "calendar"} />{" "}
|
|
{event.time ? `${event.time} - ` : ""}
|
|
{formatEventDate(event.date)}
|
|
</span>
|
|
</li>
|
|
{event.location && event.location.trim() && (
|
|
<li>
|
|
<span className='d-flex g-3 metered-data'>
|
|
<img src="/assets/img/icons/location1.svg" alt="" />{" "}
|
|
{event.location}
|
|
</span>
|
|
</li>
|
|
)}
|
|
</ul>
|
|
<div className="space20" />
|
|
<Link href={event.link || "#"} className="head">{event.title}</Link>
|
|
<div className="space24" />
|
|
<p
|
|
style={{
|
|
display: '-webkit-box',
|
|
WebkitLineClamp: 2,
|
|
WebkitBoxOrient: 'vertical',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
}}
|
|
>
|
|
{event.desc}
|
|
</p>
|
|
<div className="space24" />
|
|
<div className="btn-area1">
|
|
<Link href={event.url || "#"} className="vl-btn3" target='_blank'>
|
|
<span className="demo">{event.btnText || "Online Tickets"}</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="col-lg-1" />
|
|
|
|
<div className="col-lg-5">
|
|
<div className="img1">
|
|
<img src={event.image} alt={event.title} />
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|