diff --git a/app/create-trip/layout.tsx b/app/create-trip/layout.tsx
new file mode 100644
index 0000000..911b0e5
--- /dev/null
+++ b/app/create-trip/layout.tsx
@@ -0,0 +1,13 @@
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Buat Open Trip",
+ description:
+ "Buat open trip pendakian gunung di SeTrip. Atur itinerary, harga, dan ajak pendaki lain ikut serta.",
+ alternates: { canonical: "/create-trip" },
+ robots: { index: false, follow: false },
+};
+
+export default function CreateTripLayout({ children }: { children: React.ReactNode }) {
+ return children;
+}
diff --git a/app/layout.tsx b/app/layout.tsx
index 93c0a7d..bfb10f9 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import { SessionProvider } from "@/components/providers/session-provider";
import { Navbar } from "@/components/shared/navbar";
+import { siteConfig, siteUrl } from "@/lib/site";
import "./globals.css";
const geistSans = Geist({
@@ -15,9 +16,50 @@ const geistMono = Geist_Mono({
});
export const metadata: Metadata = {
- title: "SeTrip",
- description:
- "Cari open trip pendakian gunung, gabung bareng, nikmati petualangan ke gunung-gunung Jawa Barat.",
+ metadataBase: new URL(siteUrl),
+ title: {
+ default: `${siteConfig.name} — Open Trip Pendakian Gunung`,
+ template: `%s · ${siteConfig.name}`,
+ },
+ description: siteConfig.description,
+ applicationName: siteConfig.name,
+ keywords: [...siteConfig.keywords],
+ authors: [{ name: siteConfig.name }],
+ creator: siteConfig.name,
+ publisher: siteConfig.name,
+ alternates: { canonical: "/" },
+ openGraph: {
+ type: "website",
+ locale: "id_ID",
+ url: "/",
+ siteName: siteConfig.name,
+ title: `${siteConfig.name} — Open Trip Pendakian Gunung`,
+ description: siteConfig.description,
+ images: [
+ {
+ url: "/images/SeTrip.png",
+ width: 1200,
+ height: 630,
+ alt: `${siteConfig.name} — ${siteConfig.slogan}`,
+ },
+ ],
+ },
+ twitter: {
+ card: "summary_large_image",
+ title: `${siteConfig.name} — Open Trip Pendakian Gunung`,
+ description: siteConfig.description,
+ images: ["/images/SeTrip.png"],
+ },
+ robots: {
+ index: true,
+ follow: true,
+ googleBot: {
+ index: true,
+ follow: true,
+ "max-image-preview": "large",
+ "max-snippet": -1,
+ },
+ },
icons: {
icon: "/SeTrip.ico",
apple: "/images/SeTrip.png",
diff --git a/app/login/layout.tsx b/app/login/layout.tsx
new file mode 100644
index 0000000..85ab886
--- /dev/null
+++ b/app/login/layout.tsx
@@ -0,0 +1,13 @@
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Masuk",
+ description:
+ "Masuk ke akun SeTrip untuk gabung open trip pendakian dan kelola perjalananmu.",
+ alternates: { canonical: "/login" },
+ robots: { index: false, follow: true },
+};
+
+export default function LoginLayout({ children }: { children: React.ReactNode }) {
+ return children;
+}
diff --git a/app/page.tsx b/app/page.tsx
index 4a29a25..9eabe88 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,7 +1,20 @@
+import type { Metadata } from "next";
import Link from "next/link";
import Image from "next/image";
import { tripService } from "@/server/services/trip.service";
import { TripCard } from "@/features/trip/components/trip-card";
+import { siteConfig, siteUrl, absoluteUrl } from "@/lib/site";
+
+export const metadata: Metadata = {
+ title: "Cari Open Trip Pendakian Gunung Bareng",
+ description: `${siteConfig.slogan} ${siteConfig.description}`,
+ alternates: { canonical: "/" },
+ openGraph: {
+ title: `${siteConfig.name} — Open Trip Pendakian Gunung Bareng`,
+ description: siteConfig.slogan,
+ url: "/",
+ },
+};
export default async function HomePage() {
const trips = await tripService.getOpenTrips();
@@ -25,8 +38,41 @@ export default async function HomePage() {
.filter((t) => !shownIds.has(t.id) && t.price <= 300000)
.slice(0, 3);
+ const orgJsonLd = {
+ "@context": "https://schema.org",
+ "@graph": [
+ {
+ "@type": "Organization",
+ "@id": `${siteUrl}/#organization`,
+ name: siteConfig.name,
+ url: siteUrl,
+ logo: absoluteUrl("/images/SeTrip.png"),
+ slogan: siteConfig.slogan,
+ description: siteConfig.description,
+ },
+ {
+ "@type": "WebSite",
+ "@id": `${siteUrl}/#website`,
+ url: siteUrl,
+ name: siteConfig.name,
+ description: siteConfig.description,
+ publisher: { "@id": `${siteUrl}/#organization` },
+ inLanguage: "id-ID",
+ potentialAction: {
+ "@type": "SearchAction",
+ target: `${siteUrl}/trips?q={search_term_string}`,
+ "query-input": "required name=search_term_string",
+ },
+ },
+ ],
+ };
+
return (
+
{/* ========== HERO ========== */}
{/* Logo background full */}
diff --git a/app/profile/page.tsx b/app/profile/page.tsx
index d1a47d1..d9ff5dc 100644
--- a/app/profile/page.tsx
+++ b/app/profile/page.tsx
@@ -1,3 +1,4 @@
+import type { Metadata } from "next";
import { redirect } from "next/navigation";
import Image from "next/image";
import Link from "next/link";
@@ -7,6 +8,11 @@ import { profileService } from "@/server/services/profile.service";
import { TripCard } from "@/features/trip/components/trip-card";
import { ProfileTripRow } from "@/features/profile/components/profile-trip-row";
+export const metadata: Metadata = {
+ title: "Profil Saya",
+ robots: { index: false, follow: false },
+};
+
export default async function ProfilePage() {
const session = await getServerSession(authOptions);
if (!session?.user) {
diff --git a/app/register/layout.tsx b/app/register/layout.tsx
new file mode 100644
index 0000000..1642803
--- /dev/null
+++ b/app/register/layout.tsx
@@ -0,0 +1,12 @@
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Daftar Akun",
+ description:
+ "Buat akun SeTrip gratis. Cari open trip pendakian gunung, gabung bareng, dan mulai petualanganmu.",
+ alternates: { canonical: "/register" },
+};
+
+export default function RegisterLayout({ children }: { children: React.ReactNode }) {
+ return children;
+}
diff --git a/app/robots.ts b/app/robots.ts
new file mode 100644
index 0000000..2595504
--- /dev/null
+++ b/app/robots.ts
@@ -0,0 +1,16 @@
+import type { MetadataRoute } from "next";
+import { absoluteUrl, siteUrl } from "@/lib/site";
+
+export default function robots(): MetadataRoute.Robots {
+ return {
+ rules: [
+ {
+ userAgent: "*",
+ allow: "/",
+ disallow: ["/api/", "/profile", "/create-trip"],
+ },
+ ],
+ sitemap: absoluteUrl("/sitemap.xml"),
+ host: siteUrl,
+ };
+}
diff --git a/app/sitemap.ts b/app/sitemap.ts
new file mode 100644
index 0000000..4d96707
--- /dev/null
+++ b/app/sitemap.ts
@@ -0,0 +1,43 @@
+import type { MetadataRoute } from "next";
+import { prisma } from "@/lib/prisma";
+import { absoluteUrl } from "@/lib/site";
+
+export default async function sitemap(): Promise {
+ const trips = await prisma.trip.findMany({
+ where: { status: { in: ["OPEN", "FULL"] } },
+ select: { id: true, updatedAt: true },
+ orderBy: { updatedAt: "desc" },
+ });
+
+ const now = new Date();
+
+ const staticEntries: MetadataRoute.Sitemap = [
+ {
+ url: absoluteUrl("/"),
+ lastModified: now,
+ changeFrequency: "daily",
+ priority: 1,
+ },
+ {
+ url: absoluteUrl("/trips"),
+ lastModified: now,
+ changeFrequency: "hourly",
+ priority: 0.9,
+ },
+ {
+ url: absoluteUrl("/register"),
+ lastModified: now,
+ changeFrequency: "yearly",
+ priority: 0.3,
+ },
+ ];
+
+ const tripEntries: MetadataRoute.Sitemap = trips.map((t) => ({
+ url: absoluteUrl(`/trips/${t.id}`),
+ lastModified: t.updatedAt,
+ changeFrequency: "daily",
+ priority: 0.8,
+ }));
+
+ return [...staticEntries, ...tripEntries];
+}
diff --git a/app/trips/[id]/opengraph-image.tsx b/app/trips/[id]/opengraph-image.tsx
new file mode 100644
index 0000000..d0b2633
--- /dev/null
+++ b/app/trips/[id]/opengraph-image.tsx
@@ -0,0 +1,227 @@
+import { ImageResponse } from "next/og";
+import { tripService } from "@/server/services/trip.service";
+import { formatRupiah } from "@/lib/utils";
+import { formatTripCalendarDateRangeLong } from "@/lib/trip-dates";
+import { siteConfig } from "@/lib/site";
+
+export const alt = `${siteConfig.name} — Open Trip Pendakian`;
+export const size = { width: 1200, height: 630 };
+export const contentType = "image/png";
+
+export default async function TripOgImage({
+ params,
+}: {
+ params: Promise<{ id: string }>;
+}) {
+ const { id } = await params;
+
+ let trip;
+ try {
+ trip = await tripService.getTripById(id);
+ } catch {
+ return new ImageResponse(
+ (
+
+ {siteConfig.name}
+
+ ),
+ { ...size }
+ );
+ }
+
+ const cover = trip.images[0]?.url;
+ const dateLabel = formatTripCalendarDateRangeLong(trip.date, trip.endDate);
+ const price = formatRupiah(trip.price);
+
+ return new ImageResponse(
+ (
+
+ {cover && (
+ // eslint-disable-next-line @next/next/no-img-element
+

+ )}
+
+
+
+
+ {/* Top: brand badge */}
+
+
+ 🏔️
+ Open Trip Pendakian
+
+
+
+ {/* Middle: title + mountain */}
+
+
40 ? 64 : 76,
+ fontWeight: 800,
+ letterSpacing: -2,
+ lineHeight: 1.05,
+ display: "flex",
+ maxWidth: 1050,
+ }}
+ >
+ {trip.title}
+
+
+ 📍
+
+ {trip.mountain} · {trip.location}
+
+
+
+
+ {/* Bottom: date / price / brand */}
+
+
+
+ 📅
+ {dateLabel}
+
+
+ Mulai
+
+ {price}
+
+ / orang
+
+
+
+
+
+ Se
+ Trip
+
+
+ {siteConfig.slogan}
+
+
+
+
+
+ ),
+ { ...size }
+ );
+}
diff --git a/app/trips/[id]/page.tsx b/app/trips/[id]/page.tsx
index 379213b..3820838 100644
--- a/app/trips/[id]/page.tsx
+++ b/app/trips/[id]/page.tsx
@@ -1,3 +1,4 @@
+import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { getServerSession } from "next-auth";
import Link from "next/link";
@@ -6,6 +7,7 @@ import { tripService } from "@/server/services/trip.service";
import { trustService } from "@/server/services/trust.service";
import { formatRupiah } from "@/lib/utils";
import { formatTripCalendarDateRangeLong } from "@/lib/trip-dates";
+import { siteConfig, siteUrl, absoluteUrl } from "@/lib/site";
import { JoinTripButton } from "@/features/trip/components/join-trip-button";
import { OrganizerJoinRequests } from "@/features/trip/components/organizer-join-requests";
import { OrganizerTrustPanel } from "@/features/trip/components/organizer-trust-panel";
@@ -18,6 +20,47 @@ import {
isTripDepartureDayPast,
} from "@/lib/trip-dates";
+export async function generateMetadata({
+ params,
+}: {
+ params: Promise<{ id: string }>;
+}): Promise {
+ const { id } = await params;
+ let trip;
+ try {
+ trip = await tripService.getTripById(id);
+ } catch {
+ return {
+ title: "Trip tidak ditemukan",
+ robots: { index: false, follow: false },
+ };
+ }
+
+ const title = `${trip.title} — ${trip.mountain}`;
+ const fallbackDescription = `Open trip ${trip.mountain} di ${trip.location}, ${formatTripCalendarDateRangeLong(trip.date, trip.endDate)}. Harga ${formatRupiah(trip.price)}/orang, max ${trip.maxParticipants} peserta. Gabung di ${siteConfig.name}.`;
+ const description =
+ trip.description?.replace(/\s+/g, " ").trim().slice(0, 160) ||
+ fallbackDescription;
+
+ // OG/Twitter image otomatis di-inject dari `opengraph-image.tsx` colocated.
+ return {
+ title,
+ description,
+ alternates: { canonical: `/trips/${id}` },
+ openGraph: {
+ type: "article",
+ title,
+ description,
+ url: `/trips/${id}`,
+ },
+ twitter: {
+ card: "summary_large_image",
+ title,
+ description,
+ },
+ };
+}
+
export default async function TripDetailPage({
params,
}: {
@@ -84,8 +127,99 @@ export default async function TripDetailPage({
(p) => p.markedPaidAt && !p.paymentConfirmedAt
);
+ const tripUrl = absoluteUrl(`/trips/${trip.id}`);
+ const eventStatus =
+ trip.status === "OPEN"
+ ? "https://schema.org/EventScheduled"
+ : trip.status === "CLOSED"
+ ? "https://schema.org/EventCancelled"
+ : "https://schema.org/EventScheduled";
+ const offerAvailability =
+ trip.status === "OPEN"
+ ? "https://schema.org/InStock"
+ : trip.status === "FULL"
+ ? "https://schema.org/SoldOut"
+ : "https://schema.org/Discontinued";
+
+ const jsonLd = {
+ "@context": "https://schema.org",
+ "@graph": [
+ {
+ "@type": "Event",
+ "@id": `${tripUrl}#event`,
+ name: trip.title,
+ description: trip.description ?? undefined,
+ startDate: trip.date.toISOString(),
+ endDate: (trip.endDate ?? trip.date).toISOString(),
+ eventStatus,
+ eventAttendanceMode: "https://schema.org/OfflineEventAttendanceMode",
+ location: {
+ "@type": "Place",
+ name: trip.mountain,
+ address: {
+ "@type": "PostalAddress",
+ addressLocality: trip.location,
+ addressCountry: "ID",
+ },
+ },
+ image: trip.images.length
+ ? trip.images.map((i) => i.url)
+ : [absoluteUrl("/images/SeTrip.png")],
+ organizer: {
+ "@type": "Person",
+ name: trip.organizer.name,
+ },
+ offers: {
+ "@type": "Offer",
+ url: tripUrl,
+ price: trip.price,
+ priceCurrency: "IDR",
+ availability: offerAvailability,
+ validFrom: trip.createdAt.toISOString(),
+ },
+ maximumAttendeeCapacity: trip.maxParticipants,
+ ...(averageRating && trip.reviews.length > 0
+ ? {
+ aggregateRating: {
+ "@type": "AggregateRating",
+ ratingValue: averageRating,
+ reviewCount: trip.reviews.length,
+ bestRating: 5,
+ worstRating: 1,
+ },
+ }
+ : {}),
+ isAccessibleForFree: false,
+ inLanguage: "id-ID",
+ },
+ {
+ "@type": "BreadcrumbList",
+ "@id": `${tripUrl}#breadcrumbs`,
+ itemListElement: [
+ { "@type": "ListItem", position: 1, name: "Beranda", item: siteUrl },
+ {
+ "@type": "ListItem",
+ position: 2,
+ name: "Open Trip",
+ item: absoluteUrl("/trips"),
+ },
+ {
+ "@type": "ListItem",
+ position: 3,
+ name: trip.mountain,
+ item: tripUrl,
+ },
+ ],
+ },
+ ],
+ };
+
return (
+
{/* Breadcrumb */}
diff --git a/app/trips/page.tsx b/app/trips/page.tsx
index 5096447..e250031 100644
--- a/app/trips/page.tsx
+++ b/app/trips/page.tsx
@@ -1,13 +1,33 @@
+import type { Metadata } from "next";
import Link from "next/link";
import { Suspense } from "react";
import { tripService } from "@/server/services/trip.service";
import { TripCard } from "@/features/trip/components/trip-card";
import { TripFilter } from "@/features/trip/components/trip-filter";
+import { siteConfig } from "@/lib/site";
interface TripsPageProps {
searchParams: Promise<{ q?: string; from?: string; to?: string }>;
}
+export async function generateMetadata({
+ searchParams,
+}: TripsPageProps): Promise
{
+ const { q } = await searchParams;
+ const title = q
+ ? `Open Trip "${q}" — Pendakian Bareng`
+ : "Open Trip Pendakian Gunung — Daftar Trip Aktif";
+ const description = q
+ ? `Hasil pencarian open trip "${q}" di ${siteConfig.name}. Cari open trip pendakian, lihat tanggal, harga, & langsung gabung.`
+ : `Daftar open trip pendakian gunung yang sedang dibuka di ${siteConfig.name}. Pilih trip, lihat itinerary, dan langsung gabung mendaki bareng.`;
+ return {
+ title,
+ description,
+ alternates: { canonical: "/trips" },
+ openGraph: { title, description, url: "/trips" },
+ };
+}
+
export default async function TripsPage({ searchParams }: TripsPageProps) {
const params = await searchParams;
const hasFilters = params.q || params.from || params.to;
diff --git a/lib/site.ts b/lib/site.ts
new file mode 100644
index 0000000..81892fc
--- /dev/null
+++ b/lib/site.ts
@@ -0,0 +1,39 @@
+export const siteConfig = {
+ name: "SeTrip",
+ brand: "SeTrip",
+ slogan: "Masa cowok sejati, cewek seimut, nggak SeTrip bareng?",
+ description:
+ "SeTrip adalah platform open trip pendakian gunung yang menyatukan open trip dari berbagai sosial media ke satu tempat. Cari, gabung, dan mendaki bareng — dari pemula sampai pendaki rutin.",
+ keywords: [
+ "setrip",
+ "se trip",
+ "open trip",
+ "open trip gunung",
+ "open trip pendakian",
+ "open trip jawa barat",
+ "hiking",
+ "hiking bareng",
+ "mendaki bersama",
+ "naik gunung bareng",
+ "pendakian gunung",
+ "trip gunung",
+ "trip pendakian",
+ "gabung open trip",
+ "cari open trip",
+ "papandayan",
+ "ciremai",
+ "gunung gede",
+ "gunung pangrango",
+ "gunung guntur",
+ "gunung malabar",
+ "gunung tangkuban parahu",
+ ],
+} as const;
+
+export const siteUrl = (
+ process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000"
+).replace(/\/$/, "");
+
+export function absoluteUrl(path = "/"): string {
+ return `${siteUrl}${path.startsWith("/") ? path : `/${path}`}`;
+}
diff --git a/prisma/seed.ts b/prisma/seed.ts
index 36db44f..81b9c96 100644
--- a/prisma/seed.ts
+++ b/prisma/seed.ts
@@ -107,6 +107,31 @@ async function main() {
const utc = (y: number, m0: number, d: number, h = 12, min = 0) =>
new Date(Date.UTC(y, m0, d, h, min, 0, 0));
+ // Unsplash mountain photos (URL CDN publik, gratis, stabil).
+ // Slug ID di komentar = id di unsplash.com/photos/{slug} buat ditelusuri ulang.
+ const img = (id: string) =>
+ `https://images.unsplash.com/photo-${id}?w=1200&q=80&auto=format&fit=crop`;
+ const MOUNTAIN_PHOTOS = {
+ papandayan1: img("1554629947-334ff61d85dc"), // xfngap_DToE
+ papandayan2: img("1464822759023-fed622ff2c3b"), // Bkci_8qcdvQ
+ papandayan3: img("1454496522488-7a8e488e8606"), // 9wg5jCEPBsw
+ ciremai1: img("1480497490787-505ec076689f"), // 6bKxagnIDtk
+ ciremai2: img("1483728642387-6c3bdd6c93e5"), // YFFGkE3y4F8
+ ciremai3: img("1502085671122-2d218cd434e6"), // NNmiv6zcFvk
+ gede1: img("1478059299873-f047d8c5fe1a"), // DXQB5D1njMY
+ gede2: img("1519681393784-d120267933ba"), // z8ct_Q3oCqM
+ gede3: img("1501785888041-af3ef285b470"), // T7K4aEPoGGk
+ gede4: img("1540979388789-6cee28a1cdc9"), // eUFfY6cwjSU
+ tangkuban1: img("1506905925346-21bda4d32df4"), // 1527pjeb6jg
+ tangkuban2: img("1490682143684-14369e18dce8"), // 8c6eS43iq1o
+ malabar1: img("1494548162494-384bba4ab999"), // xP_AGmeEa6s
+ malabar2: img("1500964757637-c85e8a162699"), // twukN12EN7c
+ malabar3: img("1549880181-56a44cf4a9a5"), // ePpaQC2c1xA
+ guntur1: img("1558883493-8b86ff880fec"), // vaG8rOJLDHo
+ guntur2: img("1554629947-334ff61d85dc"), // reuse — xfngap_DToE
+ guntur3: img("1464822759023-fed622ff2c3b"), // reuse — Bkci_8qcdvQ
+ } as const;
+
// --- Trip 1: Papandayan (by Dede Inoen) — 2 hari ---
const trip1 = await prisma.trip.create({
data: {
@@ -144,9 +169,9 @@ Minggu
organizerId: dede.id,
images: {
create: [
- { url: "/images/seed/papandayan-1.svg", caption: "Kawah Papandayan", order: 0 },
- { url: "/images/seed/papandayan-2.svg", caption: "Track menuju puncak", order: 1 },
- { url: "/images/seed/papandayan-3.svg", caption: "Camping ground Pondok Salada", order: 2 },
+ { url: MOUNTAIN_PHOTOS.papandayan1, caption: "Kawah Papandayan", order: 0 },
+ { url: MOUNTAIN_PHOTOS.papandayan2, caption: "Track menuju puncak", order: 1 },
+ { url: MOUNTAIN_PHOTOS.papandayan3, caption: "Camping ground Pondok Salada", order: 2 },
],
},
},
@@ -175,9 +200,9 @@ Itinerary:
organizerId: panji.id,
images: {
create: [
- { url: "/images/seed/ciremai-1.svg", caption: "Puncak Ciremai 3.078 mdpl", order: 0 },
- { url: "/images/seed/ciremai-2.svg", caption: "Jalur pendakian via Apuy", order: 1 },
- { url: "/images/seed/ciremai-3.svg", caption: "Sunrise dari puncak", order: 2 },
+ { url: MOUNTAIN_PHOTOS.ciremai1, caption: "Puncak Ciremai 3.078 mdpl", order: 0 },
+ { url: MOUNTAIN_PHOTOS.ciremai2, caption: "Jalur pendakian via Apuy", order: 1 },
+ { url: MOUNTAIN_PHOTOS.ciremai3, caption: "Sunrise dari puncak", order: 2 },
],
},
},
@@ -204,10 +229,10 @@ Start malam, summit saat sunrise. View epic dijamin!`,
organizerId: fiersa.id,
images: {
create: [
- { url: "/images/seed/gede-1.svg", caption: "Puncak Gunung Gede", order: 0 },
- { url: "/images/seed/gede-2.svg", caption: "Surya Kencana padang edelweis", order: 1 },
- { url: "/images/seed/gede-3.svg", caption: "Blue lake / Danau Biru", order: 2 },
- { url: "/images/seed/gede-4.svg", caption: "Night hike track Cibodas", order: 3 },
+ { url: MOUNTAIN_PHOTOS.gede1, caption: "Puncak Gunung Gede", order: 0 },
+ { url: MOUNTAIN_PHOTOS.gede2, caption: "Surya Kencana padang edelweis", order: 1 },
+ { url: MOUNTAIN_PHOTOS.gede3, caption: "Blue lake / Danau Biru", order: 2 },
+ { url: MOUNTAIN_PHOTOS.gede4, caption: "Night hike track Cibodas", order: 3 },
],
},
},
@@ -234,8 +259,8 @@ Explore Kawah Ratu, Kawah Domas, foto-foto, terus makan sate maranggi!`,
organizerId: dede.id,
images: {
create: [
- { url: "/images/seed/tangkuban-1.svg", caption: "Kawah Ratu", order: 0 },
- { url: "/images/seed/tangkuban-2.svg", caption: "Kawah Domas", order: 1 },
+ { url: MOUNTAIN_PHOTOS.tangkuban1, caption: "Kawah Ratu", order: 0 },
+ { url: MOUNTAIN_PHOTOS.tangkuban2, caption: "Kawah Domas", order: 1 },
],
},
},
@@ -262,9 +287,9 @@ Trip ringan, 3-4 jam naik. Cocok buat yang mau healing malam-malam.`,
organizerId: fiersa.id,
images: {
create: [
- { url: "/images/seed/malabar-1.svg", caption: "Puncak Malabar malam hari", order: 0 },
- { url: "/images/seed/malabar-2.svg", caption: "View Bandung dari atas", order: 1 },
- { url: "/images/seed/malabar-3.svg", caption: "Track pendakian", order: 2 },
+ { url: MOUNTAIN_PHOTOS.malabar1, caption: "Puncak Malabar malam hari", order: 0 },
+ { url: MOUNTAIN_PHOTOS.malabar2, caption: "View Bandung dari atas", order: 1 },
+ { url: MOUNTAIN_PHOTOS.malabar3, caption: "Track pendakian", order: 2 },
],
},
},
@@ -291,9 +316,9 @@ Buat yang suka challenge. Pemandangan kawah aktif dari dekat!`,
organizerId: panji.id,
images: {
create: [
- { url: "/images/seed/guntur-1.svg", caption: "Kawah aktif Gunung Guntur", order: 0 },
- { url: "/images/seed/guntur-2.svg", caption: "Jalur berbatu menuju puncak", order: 1 },
- { url: "/images/seed/guntur-3.svg", caption: "View dari puncak", order: 2 },
+ { url: MOUNTAIN_PHOTOS.guntur1, caption: "Kawah aktif Gunung Guntur", order: 0 },
+ { url: MOUNTAIN_PHOTOS.guntur2, caption: "Jalur berbatu menuju puncak", order: 1 },
+ { url: MOUNTAIN_PHOTOS.guntur3, caption: "View dari puncak", order: 2 },
],
},
},
diff --git a/public/images/seed/ciremai-1.svg b/public/images/seed/ciremai-1.svg
deleted file mode 100644
index 9f3a310..0000000
--- a/public/images/seed/ciremai-1.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/ciremai-2.svg b/public/images/seed/ciremai-2.svg
deleted file mode 100644
index d4fcc14..0000000
--- a/public/images/seed/ciremai-2.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/ciremai-3.svg b/public/images/seed/ciremai-3.svg
deleted file mode 100644
index 8da47b5..0000000
--- a/public/images/seed/ciremai-3.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/gede-1.svg b/public/images/seed/gede-1.svg
deleted file mode 100644
index 263d4ae..0000000
--- a/public/images/seed/gede-1.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/gede-2.svg b/public/images/seed/gede-2.svg
deleted file mode 100644
index fdce14e..0000000
--- a/public/images/seed/gede-2.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/gede-3.svg b/public/images/seed/gede-3.svg
deleted file mode 100644
index c758333..0000000
--- a/public/images/seed/gede-3.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/gede-4.svg b/public/images/seed/gede-4.svg
deleted file mode 100644
index 5dfe1ad..0000000
--- a/public/images/seed/gede-4.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/guntur-1.svg b/public/images/seed/guntur-1.svg
deleted file mode 100644
index 9fe1b33..0000000
--- a/public/images/seed/guntur-1.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/guntur-2.svg b/public/images/seed/guntur-2.svg
deleted file mode 100644
index e570ae7..0000000
--- a/public/images/seed/guntur-2.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/guntur-3.svg b/public/images/seed/guntur-3.svg
deleted file mode 100644
index 7fcdcb1..0000000
--- a/public/images/seed/guntur-3.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/malabar-1.svg b/public/images/seed/malabar-1.svg
deleted file mode 100644
index 55cdf0d..0000000
--- a/public/images/seed/malabar-1.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/malabar-2.svg b/public/images/seed/malabar-2.svg
deleted file mode 100644
index c2205c3..0000000
--- a/public/images/seed/malabar-2.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/malabar-3.svg b/public/images/seed/malabar-3.svg
deleted file mode 100644
index 75053a9..0000000
--- a/public/images/seed/malabar-3.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/papandayan-1.svg b/public/images/seed/papandayan-1.svg
deleted file mode 100644
index d858580..0000000
--- a/public/images/seed/papandayan-1.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/papandayan-2.svg b/public/images/seed/papandayan-2.svg
deleted file mode 100644
index 23ccae9..0000000
--- a/public/images/seed/papandayan-2.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/papandayan-3.svg b/public/images/seed/papandayan-3.svg
deleted file mode 100644
index adf116e..0000000
--- a/public/images/seed/papandayan-3.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/tangkuban-1.svg b/public/images/seed/tangkuban-1.svg
deleted file mode 100644
index 9e1261b..0000000
--- a/public/images/seed/tangkuban-1.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file
diff --git a/public/images/seed/tangkuban-2.svg b/public/images/seed/tangkuban-2.svg
deleted file mode 100644
index 5f1838c..0000000
--- a/public/images/seed/tangkuban-2.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
\ No newline at end of file