Files
setrip/app/page.tsx
T
2026-04-16 14:51:54 +07:00

243 lines
9.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Link from "next/link";
import { tripService } from "@/server/services/trip.service";
import { TripCard } from "@/features/trip/components/trip-card";
import { SearchBar } from "@/features/trip/components/search-bar";
export default async function HomePage() {
const trips = await tripService.getOpenTrips();
const now = new Date();
const nextWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
const upcomingTrips = trips.filter((t) => new Date(t.date) <= nextWeek);
const budgetTrips = trips.filter((t) => t.price <= 300000).slice(0, 3);
const latestTrips = trips.slice(0, 6);
return (
<div className="relative min-h-screen bg-neutral-50">
{/* ========== HERO ========== */}
<section className="relative overflow-hidden bg-neutral-900">
{/* Gradient overlay */}
<div className="absolute inset-0 bg-linear-to-br from-primary-900/90 via-neutral-900/80 to-secondary-900/70" />
<div className="relative mx-auto max-w-4xl px-4 pb-16 pt-14 text-center">
{/* Brand */}
<div className="mb-6 inline-flex items-center gap-2 rounded-full border border-primary-400/30 bg-primary-600/20 px-4 py-1.5">
<span className="text-sm">🏔</span>
<span className="text-sm font-medium text-primary-300">
Open Trip Pendakian Gunung
</span>
</div>
<h1 className="mb-4 text-4xl font-extrabold leading-tight tracking-tight text-white sm:text-5xl">
Se<span className="text-primary-400">Trip</span>
</h1>
<p className="mx-auto mb-3 max-w-lg text-lg font-medium text-neutral-300">
Masa cowok sejati, cewek seimut nggak{" "}
<span className="text-primary-400">SeTrip</span> bareng?
</p>
<p className="mx-auto mb-8 max-w-md text-neutral-400">
Yuk mulai dari sini. Cari open trip pendakian, gabung bareng, nikmati
petualangan ke gunung-gunung Jawa Barat.
</p>
<SearchBar />
{/* Stats */}
<div className="mt-10 flex justify-center gap-8 sm:gap-12">
<div>
<p className="text-2xl font-bold text-primary-400">
{trips.length}
</p>
<p className="text-xs text-neutral-400">Trip Tersedia</p>
</div>
<div className="h-10 w-px bg-neutral-700" />
<div>
<p className="text-2xl font-bold text-secondary-400">8</p>
<p className="text-xs text-neutral-400">Gunung Jabar</p>
</div>
<div className="h-10 w-px bg-neutral-700" />
<div>
<p className="text-2xl font-bold text-white">100%</p>
<p className="text-xs text-neutral-400">Seru</p>
</div>
</div>
</div>
</section>
{/* ========== CONTENT ========== */}
<div className="mx-auto max-w-6xl px-4 py-10 space-y-12">
{/* Trip Terdekat */}
{upcomingTrips.length > 0 && (
<section>
<div className="mb-5 flex items-center gap-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-primary-100 text-lg">
🔥
</div>
<div>
<h2 className="text-lg font-bold text-neutral-800">
Trip Terdekat
</h2>
<p className="text-xs text-neutral-500">
Berangkat dalam 7 hari ke depan
</p>
</div>
</div>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{upcomingTrips.slice(0, 3).map((trip) => (
<TripCard
key={trip.id}
id={trip.id}
title={trip.title}
mountain={trip.mountain}
location={trip.location}
date={trip.date}
price={trip.price}
maxParticipants={trip.maxParticipants}
participantCount={trip._count.participants}
organizerName={trip.organizer.name}
status={trip.status}
/>
))}
</div>
</section>
)}
{/* Open Trip */}
<section>
<div className="mb-5 flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-secondary-100 text-lg">
🏔
</div>
<div>
<h2 className="text-lg font-bold text-neutral-800">
Open Trip
</h2>
<p className="text-xs text-neutral-500">
Pendakian gunung bareng teman baru
</p>
</div>
</div>
<Link
href="/trips"
className="rounded-lg bg-secondary-50 px-3 py-1.5 text-sm font-medium text-secondary-600 hover:bg-secondary-100"
>
Lihat semua
</Link>
</div>
{latestTrips.length === 0 ? (
<div className="rounded-2xl border-2 border-dashed border-neutral-200 bg-white p-14 text-center">
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary-50 text-3xl">
🏕
</div>
<p className="mb-1 text-lg font-bold text-neutral-800">
Belum ada trip tersedia
</p>
<p className="mb-6 text-sm text-neutral-500">
Jadilah yang pertama buat open trip pendakian!
</p>
<Link
href="/create-trip"
className="inline-block rounded-xl bg-primary-600 px-6 py-2.5 text-sm font-semibold text-white shadow-lg shadow-primary-600/25 hover:bg-primary-700"
>
+ Buat Trip Baru
</Link>
</div>
) : (
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{latestTrips.map((trip) => (
<TripCard
key={trip.id}
id={trip.id}
title={trip.title}
mountain={trip.mountain}
location={trip.location}
date={trip.date}
price={trip.price}
maxParticipants={trip.maxParticipants}
participantCount={trip._count.participants}
organizerName={trip.organizer.name}
status={trip.status}
/>
))}
</div>
)}
</section>
{/* Budget Friendly */}
{budgetTrips.length > 0 && (
<section>
<div className="mb-5 flex items-center gap-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-primary-100 text-lg">
💸
</div>
<div>
<h2 className="text-lg font-bold text-neutral-800">
Budget Friendly
</h2>
<p className="text-xs text-neutral-500">
Trip di bawah Rp 300.000
</p>
</div>
</div>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{budgetTrips.map((trip) => (
<TripCard
key={trip.id}
id={trip.id}
title={trip.title}
mountain={trip.mountain}
location={trip.location}
date={trip.date}
price={trip.price}
maxParticipants={trip.maxParticipants}
participantCount={trip._count.participants}
organizerName={trip.organizer.name}
status={trip.status}
/>
))}
</div>
</section>
)}
{/* CTA Bottom */}
<section className="overflow-hidden rounded-2xl bg-neutral-800 p-8 text-center sm:p-12">
<h2 className="mb-2 text-2xl font-bold text-white">
Siap naik gunung?
</h2>
<p className="mx-auto mb-6 max-w-sm text-neutral-400">
Buat trip sendiri atau gabung trip yang sudah ada. Seru bareng teman
baru!
</p>
<div className="flex justify-center gap-3">
<Link
href="/create-trip"
className="rounded-xl bg-primary-600 px-6 py-2.5 text-sm font-semibold text-white shadow-lg shadow-primary-600/25 hover:bg-primary-500"
>
Buat Trip
</Link>
<Link
href="/trips"
className="rounded-xl border border-neutral-600 px-6 py-2.5 text-sm font-semibold text-neutral-300 hover:border-neutral-500 hover:text-white"
>
Cari Trip
</Link>
</div>
</section>
</div>
{/* ========== FAB ========== */}
<Link
href="/create-trip"
className="fixed bottom-6 right-6 z-50 flex h-14 w-14 items-center justify-center rounded-full bg-primary-600 text-2xl font-bold text-white shadow-xl shadow-primary-600/30 transition-all hover:scale-110 hover:bg-primary-500 active:scale-95"
title="Buat Trip"
>
+
</Link>
</div>
);
}