209 lines
16 KiB
TypeScript
209 lines
16 KiB
TypeScript
'use client'
|
|
import Link from 'next/link'
|
|
import { useState, useEffect } from "react"
|
|
import axios from "axios"
|
|
import { events as staticEvents } from "@/utility/constant.utils"
|
|
|
|
export default function HomeUpcomingEvent() {
|
|
const [isTab, setIsTab] = useState(1)
|
|
const [liveEvents, setLiveEvents] = useState<any[]>([])
|
|
|
|
useEffect(() => {
|
|
const fetchEvents = async () => {
|
|
try {
|
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3006/api';
|
|
const response = await axios.get(`${API_BASE_URL}/upcoming-events`);
|
|
if (response.data && response.data.success && response.data.data.length > 0) {
|
|
const normalizedEvents = response.data.data.map((e: any) => ({
|
|
...e,
|
|
title: e.title || e.eventtitle,
|
|
date: e.date || e.eventdate,
|
|
image: e.image || e.eventimageurl,
|
|
desc: e.description || e.desc || e.eventdescription,
|
|
btnText: e.btn_text || e.btnText,
|
|
link: e.link || `/upcoming-event/${e.slug || e.id}`,
|
|
location: e.location || e.venue,
|
|
}));
|
|
setLiveEvents(normalizedEvents);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching homepage upcoming events:", error);
|
|
}
|
|
};
|
|
fetchEvents();
|
|
}, []);
|
|
|
|
// Take only the first 3 events from API or fallback
|
|
const displayEvents = (liveEvents.length > 0 ? liveEvents : staticEvents).slice(0, 3) as any[];
|
|
|
|
return (
|
|
<>
|
|
|
|
<div className="event3-section-area">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-lg-12 m-auto">
|
|
<div className="event2-header heading5 space-margin60">
|
|
<h2 className="text-anime-style-3">Events</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="row gx-5">
|
|
<div className="col-lg-10" data-aos="fade-up" data-aos-duration={1000}>
|
|
<div className="tab-content" id="pills-tabContent">
|
|
<div className={isTab == 1 ? "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">
|
|
|
|
{displayEvents.map((event, idx) => {
|
|
const buttonHref = event.url || event.link || "#";
|
|
const isExternalButton = /^https?:\/\//.test(buttonHref);
|
|
|
|
return (
|
|
<div key={event.id}>
|
|
{idx > 0 && <div className={idx === 2 ? "space30" : "space48"} />}
|
|
<div className="row">
|
|
<div className="col-lg-12 m-auto">
|
|
<div className="event2-boxarea box1">
|
|
<h1 className="active">{String(idx + 1).padStart(2, "0")}</h1>
|
|
<div className="row align-items-center">
|
|
{/* Alternating layout */}
|
|
{idx % 2 === 0 ? (
|
|
<>
|
|
<div className="col-lg-5">
|
|
<div className="img1">
|
|
<img src={event.image} alt={event.title} />
|
|
</div>
|
|
</div>
|
|
<div className="col-lg-2" />
|
|
<div className="col-lg-5">
|
|
<div className="content-area">
|
|
<ul>
|
|
<li>
|
|
<Link href={event.url || "#"}>
|
|
<span className='d-flex g-3 metered-data align-items-end'>
|
|
<img src="/assets/img/icons/clock1.svg" alt="" />
|
|
{event.time ? event.time + " - " : ""}{event.date}<span> | </span>
|
|
</span>
|
|
</Link>
|
|
</li>
|
|
<li>
|
|
<Link href={event.url || "#"}>
|
|
<span className='d-flex g-3 metered-data align-items-end'> <img src="/assets/img/icons/location1.svg" alt="" />{event.location}
|
|
</span>
|
|
|
|
</Link>
|
|
</li>
|
|
</ul>
|
|
<div className="space20" />
|
|
<Link href={event.link || "#"} className="head">{event.title}</Link>
|
|
<div className="space24" />
|
|
<p
|
|
style={{
|
|
display: '-webkit-box',
|
|
WebkitLineClamp: 1,
|
|
WebkitBoxOrient: 'vertical',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
}}
|
|
>
|
|
{event.desc}
|
|
</p>
|
|
<div className="space24" />
|
|
<div className="btn-area1">
|
|
<Link
|
|
href={buttonHref}
|
|
className="vl-btn3"
|
|
{...(isExternalButton ? { target: "_blank", rel: "noopener noreferrer" } : {})}
|
|
>
|
|
<span className="demo">{event.btnText || "purchase ticket"}</span>
|
|
</Link>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<>
|
|
<div className="col-lg-5 order-2 order-lg-1">
|
|
<div className="content-area">
|
|
<ul>
|
|
<li>
|
|
<Link href={event.url || "#"}>
|
|
<span className='d-flex g-3 metered-data align-items-end'>
|
|
<img src="/assets/img/icons/clock1.svg" alt="" />
|
|
{event.time ? event.time + " - " : ""}{event.date}<span> | </span>
|
|
</span>
|
|
</Link>
|
|
</li>
|
|
<li>
|
|
<Link href={event.url || "#"}>
|
|
<span className='d-flex g-3 metered-data align-items-end'> <img src="/assets/img/icons/location1.svg" alt="" />{event.location}
|
|
</span>
|
|
|
|
</Link>
|
|
</li>
|
|
</ul>
|
|
<div className="space20" />
|
|
<Link href={event.link || "#"} className="head">{event.title}</Link>
|
|
<div className="space24" />
|
|
<p
|
|
style={{
|
|
display: '-webkit-box',
|
|
WebkitLineClamp: 1,
|
|
WebkitBoxOrient: 'vertical',
|
|
overflow: 'hidden',
|
|
textOverflow: 'ellipsis',
|
|
}}
|
|
>
|
|
{event.desc}
|
|
</p>
|
|
<div className="space24" />
|
|
<div className="btn-area1">
|
|
<Link
|
|
href={buttonHref}
|
|
className="vl-btn3"
|
|
{...(isExternalButton ? { target: "_blank", rel: "noopener noreferrer" } : {})}
|
|
>
|
|
<span className="demo">{event.btnText || "purchase ticket"}</span>
|
|
</Link>
|
|
</div>
|
|
|
|
</div>
|
|
<div className="space30 d-lg-none d-block" />
|
|
</div>
|
|
<div className="col-lg-2 order-1 order-lg-2" />
|
|
<div className="col-lg-5 order-1 order-lg-3">
|
|
<div className="img1">
|
|
<img src={event.image} alt={event.title} />
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
})}
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className='col-lg-2 ad-banner'>
|
|
<div className="memory-boxarea pl-3">
|
|
<div className="img1" data-aos="zoom-in" data-aos-duration={1000} >
|
|
<img src="/assets/img/home/ad-banner/upcoming-events-ad.webp" alt="" className='mb-3' />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</>
|
|
)
|
|
}
|