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

230 lines
8.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.
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { useSession } from "next-auth/react";
import Link from "next/link";
import { createTripAction } from "@/features/trip/actions";
const SAMPLE_MOUNTAINS = [
{ name: "Gunung Papandayan", location: "Garut, Jawa Barat" },
{ name: "Gunung Ciremai", location: "Kuningan, Jawa Barat" },
{ name: "Gunung Pangrango", location: "Bogor/Cianjur, Jawa Barat" },
{ name: "Gunung Gede", location: "Bogor/Cianjur, Jawa Barat" },
{ name: "Gunung Tangkuban Parahu", location: "Bandung, Jawa Barat" },
{ name: "Gunung Bukit Tunggul", location: "Bandung, Jawa Barat" },
{ name: "Gunung Malabar", location: "Bandung, Jawa Barat" },
{ name: "Gunung Guntur", location: "Garut, Jawa Barat" },
];
export default function CreateTripPage() {
const { data: session } = useSession();
const router = useRouter();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
if (!session?.user) {
return (
<div className="flex min-h-[calc(100vh-3.5rem)] items-center justify-center px-4">
<div className="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-4 text-neutral-500">
Kamu harus login untuk membuat trip.
</p>
<Link
href="/login"
className="inline-block rounded-xl bg-primary-600 px-6 py-2.5 text-sm font-semibold text-white hover:bg-primary-700"
>
Login
</Link>
</div>
</div>
);
}
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setError("");
setLoading(true);
const formData = new FormData(e.currentTarget);
const result = await createTripAction(formData);
setLoading(false);
if (result.error) {
setError(result.error);
} else if (result.tripId) {
router.push(`/trips/${result.tripId}`);
}
}
function handleMountainSelect(e: React.ChangeEvent<HTMLSelectElement>) {
const selected = SAMPLE_MOUNTAINS.find((m) => m.name === e.target.value);
if (selected) {
const form = e.target.form;
if (form) {
const mountainInput = form.elements.namedItem(
"mountain"
) as HTMLInputElement;
const locationInput = form.elements.namedItem(
"location"
) as HTMLInputElement;
mountainInput.value = selected.name;
locationInput.value = selected.location;
}
}
}
return (
<div className="mx-auto max-w-2xl px-4 py-8">
<div className="mb-6">
<h1 className="text-2xl font-bold text-neutral-800">Buat Trip Baru</h1>
<p className="mt-1 text-sm text-neutral-500">
Ajak teman baru naik gunung bareng!
</p>
</div>
<div className="rounded-2xl border border-neutral-200 bg-white p-6 shadow-sm">
{error && (
<div className="mb-4 rounded-xl bg-red-50 px-4 py-3 text-sm font-medium text-red-600">
{error}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-5">
{/* Mountain Quick Picker */}
<div className="rounded-xl bg-primary-50 p-4">
<label className="mb-2 flex items-center gap-1.5 text-sm font-bold text-primary-800">
<span>🏔</span> Pilih Gunung Jawa Barat
</label>
<select
onChange={handleMountainSelect}
className="w-full rounded-lg border border-primary-200 bg-white px-4 py-2.5 text-sm text-neutral-800"
defaultValue=""
>
<option value="" disabled>
Pilih gunung...
</option>
{SAMPLE_MOUNTAINS.map((m) => (
<option key={m.name} value={m.name}>
{m.name} {m.location}
</option>
))}
</select>
</div>
<div>
<label htmlFor="title" className="mb-1.5 block text-sm font-semibold text-neutral-700">
Judul Trip
</label>
<input
id="title"
name="title"
type="text"
required
className="w-full rounded-xl border border-neutral-200 bg-neutral-50 px-4 py-2.5 text-sm text-neutral-800 placeholder:text-neutral-400 focus:bg-white"
placeholder="contoh: Open Trip Papandayan Weekend"
/>
</div>
<div className="grid gap-4 sm:grid-cols-2">
<div>
<label htmlFor="mountain" className="mb-1.5 block text-sm font-semibold text-neutral-700">
Nama Gunung
</label>
<input
id="mountain"
name="mountain"
type="text"
required
className="w-full rounded-xl border border-neutral-200 bg-neutral-50 px-4 py-2.5 text-sm text-neutral-800 placeholder:text-neutral-400 focus:bg-white"
placeholder="Gunung Papandayan"
/>
</div>
<div>
<label htmlFor="location" className="mb-1.5 block text-sm font-semibold text-neutral-700">
Lokasi
</label>
<input
id="location"
name="location"
type="text"
required
className="w-full rounded-xl border border-neutral-200 bg-neutral-50 px-4 py-2.5 text-sm text-neutral-800 placeholder:text-neutral-400 focus:bg-white"
placeholder="Garut, Jawa Barat"
/>
</div>
</div>
<div>
<label htmlFor="description" className="mb-1.5 block text-sm font-semibold text-neutral-700">
Deskripsi
</label>
<textarea
id="description"
name="description"
rows={4}
className="w-full rounded-xl border border-neutral-200 bg-neutral-50 px-4 py-2.5 text-sm text-neutral-800 placeholder:text-neutral-400 focus:bg-white"
placeholder="Detail trip, itinerary, meeting point, fasilitas..."
/>
</div>
<div className="grid gap-4 sm:grid-cols-3">
<div>
<label htmlFor="date" className="mb-1.5 block text-sm font-semibold text-neutral-700">
Tanggal
</label>
<input
id="date"
name="date"
type="date"
required
className="w-full rounded-xl border border-neutral-200 bg-neutral-50 px-4 py-2.5 text-sm text-neutral-800 focus:bg-white"
/>
</div>
<div>
<label htmlFor="maxParticipants" className="mb-1.5 block text-sm font-semibold text-neutral-700">
Maks Peserta
</label>
<input
id="maxParticipants"
name="maxParticipants"
type="number"
required
min={1}
className="w-full rounded-xl border border-neutral-200 bg-neutral-50 px-4 py-2.5 text-sm text-neutral-800 placeholder:text-neutral-400 focus:bg-white"
placeholder="10"
/>
</div>
<div>
<label htmlFor="price" className="mb-1.5 block text-sm font-semibold text-neutral-700">
Harga (Rp)
</label>
<input
id="price"
name="price"
type="number"
required
min={0}
className="w-full rounded-xl border border-neutral-200 bg-neutral-50 px-4 py-2.5 text-sm text-neutral-800 placeholder:text-neutral-400 focus:bg-white"
placeholder="150000"
/>
</div>
</div>
<button
type="submit"
disabled={loading}
className="w-full rounded-xl bg-primary-600 py-3 text-sm font-bold text-white shadow-lg shadow-primary-600/20 transition-colors hover:bg-primary-700 disabled:opacity-50"
>
{loading ? "Membuat Trip..." : "Buat Trip"}
</button>
</form>
</div>
</div>
);
}