fix: convert landing events/testimonials to client components

Server-side fetch fails during Nix build due to SSL cert issues in
the sandbox. Converted to client components with useEffect+fetch
so data loads at runtime instead of build time.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
maulanasdqn
2026-04-10 15:34:37 +07:00
co-authored by Claude Opus 4.6
parent 8fff0df753
commit e61c003e07
2 changed files with 38 additions and 30 deletions
+25 -15
View File
@@ -1,5 +1,8 @@
'use client';
import { buttonVariants } from '@components';
import { cn } from '@utils';
import { useEffect, useState } from 'react';
import { HiCalendar, HiClock, HiLocationMarker } from 'react-icons/hi';
interface ApiEvent {
@@ -47,28 +50,35 @@ const getEventStatus = (endDate: string) => {
return end > now ? 'upcoming' : 'past';
};
async function fetchEvents(): Promise<ApiEvent[]> {
const res = await fetch(
'https://api.imphnen.dev/v1/landing/cms/events',
{ next: { revalidate: 60 } }
);
export default function EventsPage() {
const [events, setEvents] = useState<ApiEvent[]>([]);
const [loading, setLoading] = useState(true);
if (!res.ok) {
return [];
}
const json: ApiResponse = await res.json();
return json.data.filter((e) => !e.is_deleted);
}
export default async function EventsPage() {
const events = await fetchEvents();
useEffect(() => {
fetch('https://api.imphnen.dev/v1/landing/cms/events')
.then((res) => res.json())
.then((json: ApiResponse) => {
setEvents(json.data?.filter((e) => !e.is_deleted) || []);
})
.catch(() => setEvents([]))
.finally(() => setLoading(false));
}, []);
const sortedEvents = [...events].sort(
(a, b) =>
new Date(b.start_date).getTime() - new Date(a.start_date).getTime()
);
if (loading) {
return (
<section className="min-h-screen bg-background container py-10">
<div className="flex justify-center items-center py-20">
<div className="w-8 h-8 border-3 border-gray-200 border-t-primary-500 rounded-full animate-spin" />
</div>
</section>
);
}
if (sortedEvents.length === 0) {
return (
<section className="min-h-screen bg-background container py-10">
@@ -1,5 +1,8 @@
'use client';
import { Button } from '@components';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import { BsChatLeftQuote } from 'react-icons/bs';
import { FaQuoteLeft } from 'react-icons/fa';
@@ -36,22 +39,17 @@ function getInitial(name: string) {
return name.charAt(0).toUpperCase();
}
async function fetchTestimonials() {
const res = await fetch(
'https://api.imphnen.dev/v1/landing/cms/testimonials',
{ next: { revalidate: 60 } }
);
export default function Page() {
const [testimonials, setTestimonials] = useState<ApiTestimonial[]>([]);
if (!res.ok) {
return [];
}
const json: ApiResponse = await res.json();
return json.data.filter((t) => !t.is_deleted);
}
export default async function Page() {
const testimonials = await fetchTestimonials();
useEffect(() => {
fetch('https://api.imphnen.dev/v1/landing/cms/testimonials')
.then((res) => res.json())
.then((json: ApiResponse) => {
setTestimonials(json.data?.filter((t: ApiTestimonial) => !t.is_deleted) || []);
})
.catch(() => setTestimonials([]));
}, []);
return (
<div className="min-h-screen">