add payment, trust badge, handle race condition, fix booking schema
This commit is contained in:
@@ -213,6 +213,29 @@ Database
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Phase 3+ (SeTrip saat ini — booking, detail, trust)
|
||||||
|
|
||||||
|
Alur data mengikuti pola yang sama: **UI (`app/`) → server actions (`features/*/actions.ts`) → service (`server/services`) → repository (`server/repositories`)**.
|
||||||
|
|
||||||
|
### Booking & pembayaran manual (`features/booking/`)
|
||||||
|
|
||||||
|
- **Peserta:** tombol *Saya sudah bayar* menulis `TripParticipant.markedPaidAt` (komitmen transfer manual).
|
||||||
|
- **Organizer:** panel *Konfirmasi pembayaran* memanggil service yang mengisi `paymentConfirmedAt`.
|
||||||
|
- Tetap **tanpa payment gateway**; bukti transfer bisa di luar app (WA) sesuai kebutuhan.
|
||||||
|
|
||||||
|
### Detail trip kuat (`Trip` + halaman detail)
|
||||||
|
|
||||||
|
- Field terstruktur: `meetingPoint`, `itinerary`, `whatsIncluded`, `whatsExcluded` (teks bebas / bullet).
|
||||||
|
- Form buat trip: `features/trip/schemas.ts` + `app/create-trip/page.tsx`.
|
||||||
|
|
||||||
|
### Trust & organizer (`server/services/trust.service.ts`)
|
||||||
|
|
||||||
|
- **Verified:** kolom `User.isVerified` (default false; set manual / seed / admin ke depan).
|
||||||
|
- **Trip leader:** heuristik `jumlah trip dibuat ≥ TRIP_LEADER_MIN_TRIPS` (`lib/trust.ts`).
|
||||||
|
- **Jumlah trip dibuat & rating organizer:** dihitung agregat dari DB (rating = rata-rata `TripReview` pada semua trip sang organizer).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# 🧠 Final Principle
|
# 🧠 Final Principle
|
||||||
|
|
||||||
> Build fast → validate → refactor later
|
> Build fast → validate → refactor later
|
||||||
|
|||||||
@@ -9,43 +9,93 @@ Stack: [Next.js](https://nextjs.org) (App Router), NextAuth, Prisma (PostgreSQL)
|
|||||||
### 1. Autentikasi
|
### 1. Autentikasi
|
||||||
|
|
||||||
- Pengguna baru mendaftar di `/register` (nama, email, password disimpan di database).
|
- Pengguna baru mendaftar di `/register` (nama, email, password disimpan di database).
|
||||||
- Login di `/login` melalui NextAuth; sesi dipakai di server action dan di halaman client (misalnya navbar, form buat trip).
|
- Login di `/login` melalui NextAuth; sesi dipakai di server action dan di halaman client (navbar, form buat trip, join).
|
||||||
|
|
||||||
Tanpa login, pengguna tetap bisa melihat daftar trip dan detail trip, tetapi tidak bisa membuat trip atau join.
|
Tanpa login, pengguna tetap bisa melihat daftar trip dan detail trip, tetapi tidak bisa membuat trip atau join.
|
||||||
|
|
||||||
### 2. Organizer: membuat trip
|
### 2. Organizer: membuat trip
|
||||||
|
|
||||||
1. Setelah login, organizer membuka **Buat Trip** (`/create-trip`) dari navbar, halaman `/trips`, beranda, atau tombol mengambang (+).
|
1. Setelah login, organizer membuka **Buat Trip** (`/create-trip`) dari navbar, `/trips`, beranda, atau tombol (+).
|
||||||
2. Halaman form (`app/create-trip/page.tsx`) memvalidasi sesi di client; jika belum login, ditampilkan ajakan login.
|
2. Form memvalidasi sesi; jika belum login, ditampilkan ajakan login.
|
||||||
3. Organizer mengisi judul, gunung, lokasi, deskripsi (opsional), rentang tanggal (DatePicker), maks peserta, harga (format Rupiah), dan URL gambar opsional (`ImageUrlInput`).
|
3. Organizer mengisi judul, gunung, lokasi, deskripsi (opsional), **meeting point**, **itinerary**, **termasuk / tidak termasuk** (opsional), rentang tanggal berangkat–pulang, maks peserta, harga (Rupiah), dan URL gambar opsional.
|
||||||
4. Submit memanggil server action `createTripAction` (`features/trip/actions.ts`):
|
4. Submit → `createTripAction` → validasi Zod → `tripService.createTrip` menulis `Trip` ke database (status default **OPEN**) beserta gambar jika ada.
|
||||||
- Memastikan ada sesi.
|
5. Pengguna diarahkan ke detail trip `/trips/[id]`.
|
||||||
- Mem-parse dan memvalidasi input dengan Zod (`features/trip/schemas.ts`).
|
|
||||||
- `tripService.createTrip` menulis trip baru ke database lewat `tripRepo.create`, menghubungkan `organizerId` ke user yang login, dan menyimpan gambar jika ada.
|
|
||||||
5. Trip baru berstatus **OPEN** (default schema), lalu pengguna diarahkan ke detail trip `/trips/[id]`.
|
|
||||||
|
|
||||||
Organizer **tidak** bisa join trip sendiri; di detail trip tombol join diganti pesan bahwa user adalah organizer.
|
Organizer **tidak** bisa join trip sendiri; di detail trip ditampilkan bahwa dia adalah organizer trip ini.
|
||||||
|
|
||||||
### 3. Peserta: mencari trip dan join
|
### 3. Peserta: mencari trip
|
||||||
|
|
||||||
1. **Beranda** (`/`) dan **Open Trip** (`/trips`) menampilkan trip dengan status **OPEN** dan tanggal berangkat tidak di masa lalu (`tripService.getOpenTrips` + filter di repository).
|
1. **Beranda** (`/`) dan **Open Trip** (`/trips`) menampilkan trip **OPEN** dengan tanggal berangkat yang masih relevan (`tripService.getOpenTrips`).
|
||||||
2. Filter pencarian (`TripFilter`) mengirim query string; daftar trip disaring di server.
|
2. Filter pencarian (`TripFilter`) mengirim query string (`q`, `from`, `to`); penyaringan dilakukan di server.
|
||||||
3. Dari kartu trip (`TripCard`), pengguna membuka **detail** `/trips/[id]` (`app/trips/[id]/page.tsx`):
|
3. Dari **TripCard**, pengguna membuka **detail** `/trips/[id]`: melihat info trip, kuota, panel kepercayaan organizer (jumlah trip, rating, badge jika ada), daftar peserta yang sudah disetujui, dan ulasan.
|
||||||
- Peserta aktif = baris `TripParticipant` yang statusnya bukan `CANCELLED`.
|
|
||||||
- Slot tersisa dan progress bar memakai jumlah peserta aktif tersebut.
|
|
||||||
4. **Join** (`JoinTripButton` + `joinTripAction`):
|
|
||||||
- Jika belum login: tautan ke `/login`.
|
|
||||||
- Jika trip bukan `OPEN` dan user belum join: pendaftaran ditutup (kecuali user sudah terdaftar dan ingin membatalkan, mengikuti logika UI).
|
|
||||||
- `tripService.joinTrip` memeriksa: trip ada, status `OPEN`, bukan organizer, belum terdaftar aktif, kapasitas belum penuh; lalu menambah atau mengaktifkan kembali partisipasi (lihat bagian perbaikan bug di bawah).
|
|
||||||
5. Jika jumlah peserta aktif mencapai `maxParticipants`, status trip diperbarui menjadi **FULL**.
|
|
||||||
6. **Batal ikut** memanggil `cancelJoinAction` → `tripService.cancelJoin`: partisipasi ditandai `CANCELLED`; jika trip sebelumnya `FULL` dan setelah batal slot kosong lagi, status dikembalikan ke **OPEN**.
|
|
||||||
|
|
||||||
### 4. Ringkasan peran data
|
---
|
||||||
|
|
||||||
|
### 4. Alur lengkap: dari join hingga pembayaran sukses
|
||||||
|
|
||||||
|
Alur ini menggambarkan satu peserta dari pertama kali mendaftar sampai pembayaran dianggap selesai di aplikasi (pembayaran **manual** / transfer di luar gateway).
|
||||||
|
|
||||||
|
```text
|
||||||
|
[Peserta] [Sistem] [Organizer]
|
||||||
|
| | |
|
||||||
|
|-- buka detail trip ------>| |
|
||||||
|
| | |
|
||||||
|
|-- "Join Trip" ------------>| status partisipasi: PENDING |
|
||||||
|
| | (mengisi slot kuota trip) |
|
||||||
|
|<-- menunggu persetujuan ---| |
|
||||||
|
| |<-- lihat "Permintaan join" ------|
|
||||||
|
| | |
|
||||||
|
| |<-- "Setujui" atau "Tolak" -------|
|
||||||
|
| | Setujui -> CONFIRMED |
|
||||||
|
| | Tolak -> CANCELLED |
|
||||||
|
|<-- terkonfirmasi ikut -----| (jika disetujui) |
|
||||||
|
| | |
|
||||||
|
|-- transfer uang (WA/rek) --| (di luar app) |
|
||||||
|
| | |
|
||||||
|
|-- "Saya sudah bayar" ----->| markedPaidAt = sekarang |
|
||||||
|
|<-- menunggu konfirmasi ----| |
|
||||||
|
| | |
|
||||||
|
| |<-- "Konfirmasi pembayaran" ------|
|
||||||
|
| | paymentConfirmedAt = sekarang |
|
||||||
|
|<-- pembayaran dikonfirmasi-| |
|
||||||
|
```
|
||||||
|
|
||||||
|
**Langkah per langkah**
|
||||||
|
|
||||||
|
1. **Join trip**
|
||||||
|
Di halaman detail, peserta login menekan **Join Trip Sekarang** → `joinTripAction` → `tripService.joinTrip`.
|
||||||
|
Dibuat atau diaktifkan kembali baris `TripParticipant` dengan status **`PENDING`**. Kuota trip (peserta aktif: PENDING + CONFIRMED) bertambah; trip bisa menjadi **FULL** jika slot habis.
|
||||||
|
|
||||||
|
2. **Menunggu organizer**
|
||||||
|
Peserta melihat status bahwa permintaan **menunggu persetujuan organizer**. Dia bisa **Batal ikut** selama tanggal berangkat belum lewat (status menjadi `CANCELLED`, slot bisa longgar lagi).
|
||||||
|
|
||||||
|
3. **Organizer menyetujui atau menolak**
|
||||||
|
Di blok **Permintaan join**, organizer menekan **Setujui** → status partisipasi menjadi **`CONFIRMED`**, atau **Tolak** → **`CANCELLED`**.
|
||||||
|
Jika ada peserta yang sudah menandai bayar sebelum disetujui, penolakan juga membersihkan data tandai bayar pada baris itu.
|
||||||
|
|
||||||
|
4. **Peserta terkonfirmasi**
|
||||||
|
Setelah **CONFIRMED**, peserta dianggap bagian dari daftar “peserta terkonfirmasi” di halaman trip. Fitur ulasan trip setelah selesai hanya relevan untuk partisipasi terkonfirmasi (sesuai aturan di service).
|
||||||
|
|
||||||
|
5. **Menandai sudah membayar**
|
||||||
|
Peserta mentransfer sesuai instruksi organizer (di luar app). Di app dia menekan **Saya sudah bayar** → kolom **`markedPaidAt`** diisi. Tombol ini tidak muncul jika pembayaran sudah dikonfirmasi atau tanggal trip sudah lewat.
|
||||||
|
Aksi ini **atomik** (aman dari double klik).
|
||||||
|
|
||||||
|
6. **Organizer mengonfirmasi pembayaran**
|
||||||
|
Di blok **Konfirmasi pembayaran**, organizer mengecek mutasi/bukti lalu menekan **Konfirmasi pembayaran** untuk peserta bersangkutan → kolom **`paymentConfirmedAt`** diisi.
|
||||||
|
Ini **idempoten** (konfirmasi ganda tidak mengubah hasil akhir yang salah).
|
||||||
|
|
||||||
|
7. **Selesai (sukses payment di app)**
|
||||||
|
Peserta melihat bahwa pembayaran **sudah dikonfirmasi organizer**. Di sini alur “commit” peserta + uang dalam konteks SeTrip dianggap lengkap dari sisi data aplikasi.
|
||||||
|
|
||||||
|
**Catatan produk:** tidak ada payment gateway; bukti transfer dan nominal final tetap komunikasi organizer–peserta (misalnya WA).
|
||||||
|
|
||||||
|
### 5. Ringkasan peran data
|
||||||
|
|
||||||
| Konsep | Penyimpanan |
|
| Konsep | Penyimpanan |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| Trip | Model `Trip` (judul, gunung, lokasi, tanggal, kuota, harga, status, relasi ke organizer) |
|
| Trip | `Trip`: judul, gunung, lokasi, tanggal, kuota, harga, status trip (`OPEN` / `FULL` / …), meeting point, itinerary, termasuk/tidak termasuk, relasi ke organizer |
|
||||||
| Peserta | `TripParticipant` unik per `(tripId, userId)` dengan status `CONFIRMED` / `CANCELLED` (default schema juga mengenal `PENDING`; alur UI saat ini memakai `CONFIRMED` saat join) |
|
| Peserta | `TripParticipant` unik per `(tripId, userId)`: status **`PENDING`** / **`CONFIRMED`** / **`CANCELLED`**, serta **`markedPaidAt`** & **`paymentConfirmedAt`** untuk alur bayar manual |
|
||||||
|
| Organizer (kepercayaan) | `User.isVerified`; agregat rating & jumlah trip dibuat dihitung dari data ulasan & trip |
|
||||||
|
|
||||||
## Menjalankan secara lokal
|
## Menjalankan secara lokal
|
||||||
|
|
||||||
@@ -63,13 +113,13 @@ Buka [http://localhost:3000](http://localhost:3000).
|
|||||||
## Perbaikan bug (yang relevan dengan join & listing)
|
## Perbaikan bug (yang relevan dengan join & listing)
|
||||||
|
|
||||||
1. **Join lagi setelah “Batal ikut”**
|
1. **Join lagi setelah “Batal ikut”**
|
||||||
Satu user hanya boleh satu baris partisipasi per trip (`@@unique([tripId, userId])`). Kode lama mencoba `create` lagi setelah status `CANCELLED`, sehingga bisa gagal dengan pelanggaran unik. Sekarang jika sudah ada baris `CANCELLED`, partisipasi **diaktifkan kembali** (`CONFIRMED`) lewat `participantRepo.reactivate`, bukan insert baru.
|
Satu user hanya satu baris per trip (`@@unique([tripId, userId])`). Jika baris sudah `CANCELLED`, join berikutnya **mengaktifkan kembali** partisipasi ke **`PENDING`** (bukan insert baru).
|
||||||
|
|
||||||
2. **Jumlah peserta di kartu / daftar**
|
2. **Jumlah peserta di kartu / daftar**
|
||||||
`_count.participants` di query listing sebelumnya menghitung semua baris termasuk yang `CANCELLED`, sehingga “slot tersisa” di `TripCard` bisa salah. Count sekarang hanya menghitung peserta dengan status **bukan** `CANCELLED`.
|
`_count.participants` hanya menghitung status **bukan** `CANCELLED`, agar slot dan label “penuh” konsisten.
|
||||||
|
|
||||||
3. **Segar halaman setelah join/batal/buat trip**
|
3. **Segar halaman setelah aksi**
|
||||||
Setelah aksi trip, cache halaman `/trips` dan `/` ikut di-`revalidatePath` agar jumlah slot dan daftar di beranda konsisten tanpa harus refresh manual.
|
`revalidatePath` dipanggil setelah join, batal, buat trip, setujui/tolak peserta, dan konfirmasi pembayaran agar daftar dan detail konsisten.
|
||||||
|
|
||||||
## Learn More
|
## Learn More
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default function CreateTripPage() {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
const formData = new FormData(e.currentTarget);
|
const formData = new FormData(e.currentTarget);
|
||||||
// Hari kalender lokal → YYYY-MM-DD (bukan toISOString, supaya tidak geser ke UTC)
|
// Tanggal dari picker → string tanggal untuk server action
|
||||||
formData.set("date", formatLocalCalendarYmd(startDate));
|
formData.set("date", formatLocalCalendarYmd(startDate));
|
||||||
if (endDate) {
|
if (endDate) {
|
||||||
const startYmd = formatLocalCalendarYmd(startDate);
|
const startYmd = formatLocalCalendarYmd(startDate);
|
||||||
@@ -215,10 +215,63 @@ export default function CreateTripPage() {
|
|||||||
name="description"
|
name="description"
|
||||||
rows={4}
|
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"
|
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..."
|
placeholder="Ringkasan trip, vibe, level kesulitan..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="meetingPoint" className="mb-1.5 block text-sm font-semibold text-neutral-700">
|
||||||
|
Meeting point
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="meetingPoint"
|
||||||
|
name="meetingPoint"
|
||||||
|
type="text"
|
||||||
|
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: Alfamart Cicaheum, 05:00 WIB"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="itinerary" className="mb-1.5 block text-sm font-semibold text-neutral-700">
|
||||||
|
Itinerary
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
id="itinerary"
|
||||||
|
name="itinerary"
|
||||||
|
rows={5}
|
||||||
|
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={"Hari 1: …\nHari 2: …"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-4 sm:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label htmlFor="whatsIncluded" className="mb-1.5 block text-sm font-semibold text-neutral-700">
|
||||||
|
Termasuk
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
id="whatsIncluded"
|
||||||
|
name="whatsIncluded"
|
||||||
|
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="Transport, konsumsi, tenda, …"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="whatsExcluded" className="mb-1.5 block text-sm font-semibold text-neutral-700">
|
||||||
|
Tidak termasuk
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
id="whatsExcluded"
|
||||||
|
name="whatsExcluded"
|
||||||
|
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="Tiket masuk TN, sleeping bag, …"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ImageUrlInput />
|
<ImageUrlInput />
|
||||||
|
|
||||||
{/* Date Range & Participants & Price */}
|
{/* Date Range & Participants & Price */}
|
||||||
@@ -226,14 +279,8 @@ export default function CreateTripPage() {
|
|||||||
{/* Date Range Picker */}
|
{/* Date Range Picker */}
|
||||||
<div>
|
<div>
|
||||||
<label className="mb-1.5 block text-sm font-semibold text-neutral-700">
|
<label className="mb-1.5 block text-sm font-semibold text-neutral-700">
|
||||||
Tanggal Berangkat — Pulang
|
Tanggal berangkat — pulang
|
||||||
</label>
|
</label>
|
||||||
<p className="mb-1.5 text-[11px] leading-snug text-neutral-500 sm:text-xs">
|
|
||||||
Pilih satu tanggal untuk trip <span className="font-medium">satu hari</span>
|
|
||||||
. Pilih rentang untuk trip <span className="font-medium">lebih dari satu hari</span>
|
|
||||||
. Tanggal disimpan sebagai hari kalender yang kamu klik; filter Open Trip memakai{" "}
|
|
||||||
<span className="font-medium">UTC</span> yang sama.
|
|
||||||
</p>
|
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<span className="absolute left-3 top-1/2 z-10 -translate-y-1/2 text-neutral-400">
|
<span className="absolute left-3 top-1/2 z-10 -translate-y-1/2 text-neutral-400">
|
||||||
<svg
|
<svg
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ export type StringNullableFilter<$PrismaModel = never> = {
|
|||||||
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BoolFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||||
|
}
|
||||||
|
|
||||||
export type DateTimeFilter<$PrismaModel = never> = {
|
export type DateTimeFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
@@ -96,6 +101,14 @@ export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
|||||||
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
@@ -224,6 +237,11 @@ export type NestedStringNullableFilter<$PrismaModel = never> = {
|
|||||||
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type NestedBoolFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||||
|
}
|
||||||
|
|
||||||
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
@@ -291,6 +309,14 @@ export type NestedIntNullableFilter<$PrismaModel = never> = {
|
|||||||
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
|
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -823,6 +823,7 @@ export const UserScalarFieldEnum = {
|
|||||||
email: 'email',
|
email: 'email',
|
||||||
password: 'password',
|
password: 'password',
|
||||||
image: 'image',
|
image: 'image',
|
||||||
|
isVerified: 'isVerified',
|
||||||
createdAt: 'createdAt',
|
createdAt: 'createdAt',
|
||||||
updatedAt: 'updatedAt'
|
updatedAt: 'updatedAt'
|
||||||
} as const
|
} as const
|
||||||
@@ -836,6 +837,10 @@ export const TripScalarFieldEnum = {
|
|||||||
description: 'description',
|
description: 'description',
|
||||||
mountain: 'mountain',
|
mountain: 'mountain',
|
||||||
location: 'location',
|
location: 'location',
|
||||||
|
meetingPoint: 'meetingPoint',
|
||||||
|
itinerary: 'itinerary',
|
||||||
|
whatsIncluded: 'whatsIncluded',
|
||||||
|
whatsExcluded: 'whatsExcluded',
|
||||||
date: 'date',
|
date: 'date',
|
||||||
endDate: 'endDate',
|
endDate: 'endDate',
|
||||||
maxParticipants: 'maxParticipants',
|
maxParticipants: 'maxParticipants',
|
||||||
@@ -877,6 +882,8 @@ export const TripParticipantScalarFieldEnum = {
|
|||||||
id: 'id',
|
id: 'id',
|
||||||
status: 'status',
|
status: 'status',
|
||||||
createdAt: 'createdAt',
|
createdAt: 'createdAt',
|
||||||
|
markedPaidAt: 'markedPaidAt',
|
||||||
|
paymentConfirmedAt: 'paymentConfirmedAt',
|
||||||
tripId: 'tripId',
|
tripId: 'tripId',
|
||||||
userId: 'userId'
|
userId: 'userId'
|
||||||
} as const
|
} as const
|
||||||
@@ -928,6 +935,13 @@ export type ListStringFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaMod
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to a field of type 'Boolean'
|
||||||
|
*/
|
||||||
|
export type BooleanFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Boolean'>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to a field of type 'DateTime'
|
* Reference to a field of type 'DateTime'
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export const UserScalarFieldEnum = {
|
|||||||
email: 'email',
|
email: 'email',
|
||||||
password: 'password',
|
password: 'password',
|
||||||
image: 'image',
|
image: 'image',
|
||||||
|
isVerified: 'isVerified',
|
||||||
createdAt: 'createdAt',
|
createdAt: 'createdAt',
|
||||||
updatedAt: 'updatedAt'
|
updatedAt: 'updatedAt'
|
||||||
} as const
|
} as const
|
||||||
@@ -93,6 +94,10 @@ export const TripScalarFieldEnum = {
|
|||||||
description: 'description',
|
description: 'description',
|
||||||
mountain: 'mountain',
|
mountain: 'mountain',
|
||||||
location: 'location',
|
location: 'location',
|
||||||
|
meetingPoint: 'meetingPoint',
|
||||||
|
itinerary: 'itinerary',
|
||||||
|
whatsIncluded: 'whatsIncluded',
|
||||||
|
whatsExcluded: 'whatsExcluded',
|
||||||
date: 'date',
|
date: 'date',
|
||||||
endDate: 'endDate',
|
endDate: 'endDate',
|
||||||
maxParticipants: 'maxParticipants',
|
maxParticipants: 'maxParticipants',
|
||||||
@@ -134,6 +139,8 @@ export const TripParticipantScalarFieldEnum = {
|
|||||||
id: 'id',
|
id: 'id',
|
||||||
status: 'status',
|
status: 'status',
|
||||||
createdAt: 'createdAt',
|
createdAt: 'createdAt',
|
||||||
|
markedPaidAt: 'markedPaidAt',
|
||||||
|
paymentConfirmedAt: 'paymentConfirmedAt',
|
||||||
tripId: 'tripId',
|
tripId: 'tripId',
|
||||||
userId: 'userId'
|
userId: 'userId'
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ export type TripMinAggregateOutputType = {
|
|||||||
description: string | null
|
description: string | null
|
||||||
mountain: string | null
|
mountain: string | null
|
||||||
location: string | null
|
location: string | null
|
||||||
|
meetingPoint: string | null
|
||||||
|
itinerary: string | null
|
||||||
|
whatsIncluded: string | null
|
||||||
|
whatsExcluded: string | null
|
||||||
date: Date | null
|
date: Date | null
|
||||||
endDate: Date | null
|
endDate: Date | null
|
||||||
maxParticipants: number | null
|
maxParticipants: number | null
|
||||||
@@ -58,6 +62,10 @@ export type TripMaxAggregateOutputType = {
|
|||||||
description: string | null
|
description: string | null
|
||||||
mountain: string | null
|
mountain: string | null
|
||||||
location: string | null
|
location: string | null
|
||||||
|
meetingPoint: string | null
|
||||||
|
itinerary: string | null
|
||||||
|
whatsIncluded: string | null
|
||||||
|
whatsExcluded: string | null
|
||||||
date: Date | null
|
date: Date | null
|
||||||
endDate: Date | null
|
endDate: Date | null
|
||||||
maxParticipants: number | null
|
maxParticipants: number | null
|
||||||
@@ -74,6 +82,10 @@ export type TripCountAggregateOutputType = {
|
|||||||
description: number
|
description: number
|
||||||
mountain: number
|
mountain: number
|
||||||
location: number
|
location: number
|
||||||
|
meetingPoint: number
|
||||||
|
itinerary: number
|
||||||
|
whatsIncluded: number
|
||||||
|
whatsExcluded: number
|
||||||
date: number
|
date: number
|
||||||
endDate: number
|
endDate: number
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -102,6 +114,10 @@ export type TripMinAggregateInputType = {
|
|||||||
description?: true
|
description?: true
|
||||||
mountain?: true
|
mountain?: true
|
||||||
location?: true
|
location?: true
|
||||||
|
meetingPoint?: true
|
||||||
|
itinerary?: true
|
||||||
|
whatsIncluded?: true
|
||||||
|
whatsExcluded?: true
|
||||||
date?: true
|
date?: true
|
||||||
endDate?: true
|
endDate?: true
|
||||||
maxParticipants?: true
|
maxParticipants?: true
|
||||||
@@ -118,6 +134,10 @@ export type TripMaxAggregateInputType = {
|
|||||||
description?: true
|
description?: true
|
||||||
mountain?: true
|
mountain?: true
|
||||||
location?: true
|
location?: true
|
||||||
|
meetingPoint?: true
|
||||||
|
itinerary?: true
|
||||||
|
whatsIncluded?: true
|
||||||
|
whatsExcluded?: true
|
||||||
date?: true
|
date?: true
|
||||||
endDate?: true
|
endDate?: true
|
||||||
maxParticipants?: true
|
maxParticipants?: true
|
||||||
@@ -134,6 +154,10 @@ export type TripCountAggregateInputType = {
|
|||||||
description?: true
|
description?: true
|
||||||
mountain?: true
|
mountain?: true
|
||||||
location?: true
|
location?: true
|
||||||
|
meetingPoint?: true
|
||||||
|
itinerary?: true
|
||||||
|
whatsIncluded?: true
|
||||||
|
whatsExcluded?: true
|
||||||
date?: true
|
date?: true
|
||||||
endDate?: true
|
endDate?: true
|
||||||
maxParticipants?: true
|
maxParticipants?: true
|
||||||
@@ -237,6 +261,10 @@ export type TripGroupByOutputType = {
|
|||||||
description: string | null
|
description: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint: string | null
|
||||||
|
itinerary: string | null
|
||||||
|
whatsIncluded: string | null
|
||||||
|
whatsExcluded: string | null
|
||||||
date: Date
|
date: Date
|
||||||
endDate: Date | null
|
endDate: Date | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -276,6 +304,10 @@ export type TripWhereInput = {
|
|||||||
description?: Prisma.StringNullableFilter<"Trip"> | string | null
|
description?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
mountain?: Prisma.StringFilter<"Trip"> | string
|
mountain?: Prisma.StringFilter<"Trip"> | string
|
||||||
location?: Prisma.StringFilter<"Trip"> | string
|
location?: Prisma.StringFilter<"Trip"> | string
|
||||||
|
meetingPoint?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
itinerary?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
whatsIncluded?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
whatsExcluded?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
date?: Prisma.DateTimeFilter<"Trip"> | Date | string
|
date?: Prisma.DateTimeFilter<"Trip"> | Date | string
|
||||||
endDate?: Prisma.DateTimeNullableFilter<"Trip"> | Date | string | null
|
endDate?: Prisma.DateTimeNullableFilter<"Trip"> | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFilter<"Trip"> | number
|
maxParticipants?: Prisma.IntFilter<"Trip"> | number
|
||||||
@@ -296,6 +328,10 @@ export type TripOrderByWithRelationInput = {
|
|||||||
description?: Prisma.SortOrderInput | Prisma.SortOrder
|
description?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
mountain?: Prisma.SortOrder
|
mountain?: Prisma.SortOrder
|
||||||
location?: Prisma.SortOrder
|
location?: Prisma.SortOrder
|
||||||
|
meetingPoint?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
itinerary?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
whatsIncluded?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
whatsExcluded?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
date?: Prisma.SortOrder
|
date?: Prisma.SortOrder
|
||||||
endDate?: Prisma.SortOrderInput | Prisma.SortOrder
|
endDate?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
maxParticipants?: Prisma.SortOrder
|
maxParticipants?: Prisma.SortOrder
|
||||||
@@ -319,6 +355,10 @@ export type TripWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
description?: Prisma.StringNullableFilter<"Trip"> | string | null
|
description?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
mountain?: Prisma.StringFilter<"Trip"> | string
|
mountain?: Prisma.StringFilter<"Trip"> | string
|
||||||
location?: Prisma.StringFilter<"Trip"> | string
|
location?: Prisma.StringFilter<"Trip"> | string
|
||||||
|
meetingPoint?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
itinerary?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
whatsIncluded?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
whatsExcluded?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
date?: Prisma.DateTimeFilter<"Trip"> | Date | string
|
date?: Prisma.DateTimeFilter<"Trip"> | Date | string
|
||||||
endDate?: Prisma.DateTimeNullableFilter<"Trip"> | Date | string | null
|
endDate?: Prisma.DateTimeNullableFilter<"Trip"> | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFilter<"Trip"> | number
|
maxParticipants?: Prisma.IntFilter<"Trip"> | number
|
||||||
@@ -339,6 +379,10 @@ export type TripOrderByWithAggregationInput = {
|
|||||||
description?: Prisma.SortOrderInput | Prisma.SortOrder
|
description?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
mountain?: Prisma.SortOrder
|
mountain?: Prisma.SortOrder
|
||||||
location?: Prisma.SortOrder
|
location?: Prisma.SortOrder
|
||||||
|
meetingPoint?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
itinerary?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
whatsIncluded?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
whatsExcluded?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
date?: Prisma.SortOrder
|
date?: Prisma.SortOrder
|
||||||
endDate?: Prisma.SortOrderInput | Prisma.SortOrder
|
endDate?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
maxParticipants?: Prisma.SortOrder
|
maxParticipants?: Prisma.SortOrder
|
||||||
@@ -363,6 +407,10 @@ export type TripScalarWhereWithAggregatesInput = {
|
|||||||
description?: Prisma.StringNullableWithAggregatesFilter<"Trip"> | string | null
|
description?: Prisma.StringNullableWithAggregatesFilter<"Trip"> | string | null
|
||||||
mountain?: Prisma.StringWithAggregatesFilter<"Trip"> | string
|
mountain?: Prisma.StringWithAggregatesFilter<"Trip"> | string
|
||||||
location?: Prisma.StringWithAggregatesFilter<"Trip"> | string
|
location?: Prisma.StringWithAggregatesFilter<"Trip"> | string
|
||||||
|
meetingPoint?: Prisma.StringNullableWithAggregatesFilter<"Trip"> | string | null
|
||||||
|
itinerary?: Prisma.StringNullableWithAggregatesFilter<"Trip"> | string | null
|
||||||
|
whatsIncluded?: Prisma.StringNullableWithAggregatesFilter<"Trip"> | string | null
|
||||||
|
whatsExcluded?: Prisma.StringNullableWithAggregatesFilter<"Trip"> | string | null
|
||||||
date?: Prisma.DateTimeWithAggregatesFilter<"Trip"> | Date | string
|
date?: Prisma.DateTimeWithAggregatesFilter<"Trip"> | Date | string
|
||||||
endDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Trip"> | Date | string | null
|
endDate?: Prisma.DateTimeNullableWithAggregatesFilter<"Trip"> | Date | string | null
|
||||||
maxParticipants?: Prisma.IntWithAggregatesFilter<"Trip"> | number
|
maxParticipants?: Prisma.IntWithAggregatesFilter<"Trip"> | number
|
||||||
@@ -379,6 +427,10 @@ export type TripCreateInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -398,6 +450,10 @@ export type TripUncheckedCreateInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -417,6 +473,10 @@ export type TripUpdateInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -436,6 +496,10 @@ export type TripUncheckedUpdateInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -455,6 +519,10 @@ export type TripCreateManyInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -471,6 +539,10 @@ export type TripUpdateManyMutationInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -486,6 +558,10 @@ export type TripUncheckedUpdateManyInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -512,6 +588,10 @@ export type TripCountOrderByAggregateInput = {
|
|||||||
description?: Prisma.SortOrder
|
description?: Prisma.SortOrder
|
||||||
mountain?: Prisma.SortOrder
|
mountain?: Prisma.SortOrder
|
||||||
location?: Prisma.SortOrder
|
location?: Prisma.SortOrder
|
||||||
|
meetingPoint?: Prisma.SortOrder
|
||||||
|
itinerary?: Prisma.SortOrder
|
||||||
|
whatsIncluded?: Prisma.SortOrder
|
||||||
|
whatsExcluded?: Prisma.SortOrder
|
||||||
date?: Prisma.SortOrder
|
date?: Prisma.SortOrder
|
||||||
endDate?: Prisma.SortOrder
|
endDate?: Prisma.SortOrder
|
||||||
maxParticipants?: Prisma.SortOrder
|
maxParticipants?: Prisma.SortOrder
|
||||||
@@ -533,6 +613,10 @@ export type TripMaxOrderByAggregateInput = {
|
|||||||
description?: Prisma.SortOrder
|
description?: Prisma.SortOrder
|
||||||
mountain?: Prisma.SortOrder
|
mountain?: Prisma.SortOrder
|
||||||
location?: Prisma.SortOrder
|
location?: Prisma.SortOrder
|
||||||
|
meetingPoint?: Prisma.SortOrder
|
||||||
|
itinerary?: Prisma.SortOrder
|
||||||
|
whatsIncluded?: Prisma.SortOrder
|
||||||
|
whatsExcluded?: Prisma.SortOrder
|
||||||
date?: Prisma.SortOrder
|
date?: Prisma.SortOrder
|
||||||
endDate?: Prisma.SortOrder
|
endDate?: Prisma.SortOrder
|
||||||
maxParticipants?: Prisma.SortOrder
|
maxParticipants?: Prisma.SortOrder
|
||||||
@@ -549,6 +633,10 @@ export type TripMinOrderByAggregateInput = {
|
|||||||
description?: Prisma.SortOrder
|
description?: Prisma.SortOrder
|
||||||
mountain?: Prisma.SortOrder
|
mountain?: Prisma.SortOrder
|
||||||
location?: Prisma.SortOrder
|
location?: Prisma.SortOrder
|
||||||
|
meetingPoint?: Prisma.SortOrder
|
||||||
|
itinerary?: Prisma.SortOrder
|
||||||
|
whatsIncluded?: Prisma.SortOrder
|
||||||
|
whatsExcluded?: Prisma.SortOrder
|
||||||
date?: Prisma.SortOrder
|
date?: Prisma.SortOrder
|
||||||
endDate?: Prisma.SortOrder
|
endDate?: Prisma.SortOrder
|
||||||
maxParticipants?: Prisma.SortOrder
|
maxParticipants?: Prisma.SortOrder
|
||||||
@@ -675,6 +763,10 @@ export type TripCreateWithoutOrganizerInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -693,6 +785,10 @@ export type TripUncheckedCreateWithoutOrganizerInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -740,6 +836,10 @@ export type TripScalarWhereInput = {
|
|||||||
description?: Prisma.StringNullableFilter<"Trip"> | string | null
|
description?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
mountain?: Prisma.StringFilter<"Trip"> | string
|
mountain?: Prisma.StringFilter<"Trip"> | string
|
||||||
location?: Prisma.StringFilter<"Trip"> | string
|
location?: Prisma.StringFilter<"Trip"> | string
|
||||||
|
meetingPoint?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
itinerary?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
whatsIncluded?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
|
whatsExcluded?: Prisma.StringNullableFilter<"Trip"> | string | null
|
||||||
date?: Prisma.DateTimeFilter<"Trip"> | Date | string
|
date?: Prisma.DateTimeFilter<"Trip"> | Date | string
|
||||||
endDate?: Prisma.DateTimeNullableFilter<"Trip"> | Date | string | null
|
endDate?: Prisma.DateTimeNullableFilter<"Trip"> | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFilter<"Trip"> | number
|
maxParticipants?: Prisma.IntFilter<"Trip"> | number
|
||||||
@@ -756,6 +856,10 @@ export type TripCreateWithoutReviewsInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -774,6 +878,10 @@ export type TripUncheckedCreateWithoutReviewsInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -808,6 +916,10 @@ export type TripUpdateWithoutReviewsInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -826,6 +938,10 @@ export type TripUncheckedUpdateWithoutReviewsInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -844,6 +960,10 @@ export type TripCreateWithoutImagesInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -862,6 +982,10 @@ export type TripUncheckedCreateWithoutImagesInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -896,6 +1020,10 @@ export type TripUpdateWithoutImagesInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -914,6 +1042,10 @@ export type TripUncheckedUpdateWithoutImagesInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -932,6 +1064,10 @@ export type TripCreateWithoutParticipantsInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -950,6 +1086,10 @@ export type TripUncheckedCreateWithoutParticipantsInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -984,6 +1124,10 @@ export type TripUpdateWithoutParticipantsInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -1002,6 +1146,10 @@ export type TripUncheckedUpdateWithoutParticipantsInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -1020,6 +1168,10 @@ export type TripCreateManyOrganizerInput = {
|
|||||||
description?: string | null
|
description?: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
meetingPoint?: string | null
|
||||||
|
itinerary?: string | null
|
||||||
|
whatsIncluded?: string | null
|
||||||
|
whatsExcluded?: string | null
|
||||||
date: Date | string
|
date: Date | string
|
||||||
endDate?: Date | string | null
|
endDate?: Date | string | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -1035,6 +1187,10 @@ export type TripUpdateWithoutOrganizerInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -1053,6 +1209,10 @@ export type TripUncheckedUpdateWithoutOrganizerInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -1071,6 +1231,10 @@ export type TripUncheckedUpdateManyWithoutOrganizerInput = {
|
|||||||
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
mountain?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
location?: Prisma.StringFieldUpdateOperationsInput | string
|
location?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
|
meetingPoint?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
itinerary?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsIncluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
whatsExcluded?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
date?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
endDate?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
maxParticipants?: Prisma.IntFieldUpdateOperationsInput | number
|
||||||
@@ -1135,6 +1299,10 @@ export type TripSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = r
|
|||||||
description?: boolean
|
description?: boolean
|
||||||
mountain?: boolean
|
mountain?: boolean
|
||||||
location?: boolean
|
location?: boolean
|
||||||
|
meetingPoint?: boolean
|
||||||
|
itinerary?: boolean
|
||||||
|
whatsIncluded?: boolean
|
||||||
|
whatsExcluded?: boolean
|
||||||
date?: boolean
|
date?: boolean
|
||||||
endDate?: boolean
|
endDate?: boolean
|
||||||
maxParticipants?: boolean
|
maxParticipants?: boolean
|
||||||
@@ -1156,6 +1324,10 @@ export type TripSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensio
|
|||||||
description?: boolean
|
description?: boolean
|
||||||
mountain?: boolean
|
mountain?: boolean
|
||||||
location?: boolean
|
location?: boolean
|
||||||
|
meetingPoint?: boolean
|
||||||
|
itinerary?: boolean
|
||||||
|
whatsIncluded?: boolean
|
||||||
|
whatsExcluded?: boolean
|
||||||
date?: boolean
|
date?: boolean
|
||||||
endDate?: boolean
|
endDate?: boolean
|
||||||
maxParticipants?: boolean
|
maxParticipants?: boolean
|
||||||
@@ -1173,6 +1345,10 @@ export type TripSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensio
|
|||||||
description?: boolean
|
description?: boolean
|
||||||
mountain?: boolean
|
mountain?: boolean
|
||||||
location?: boolean
|
location?: boolean
|
||||||
|
meetingPoint?: boolean
|
||||||
|
itinerary?: boolean
|
||||||
|
whatsIncluded?: boolean
|
||||||
|
whatsExcluded?: boolean
|
||||||
date?: boolean
|
date?: boolean
|
||||||
endDate?: boolean
|
endDate?: boolean
|
||||||
maxParticipants?: boolean
|
maxParticipants?: boolean
|
||||||
@@ -1190,6 +1366,10 @@ export type TripSelectScalar = {
|
|||||||
description?: boolean
|
description?: boolean
|
||||||
mountain?: boolean
|
mountain?: boolean
|
||||||
location?: boolean
|
location?: boolean
|
||||||
|
meetingPoint?: boolean
|
||||||
|
itinerary?: boolean
|
||||||
|
whatsIncluded?: boolean
|
||||||
|
whatsExcluded?: boolean
|
||||||
date?: boolean
|
date?: boolean
|
||||||
endDate?: boolean
|
endDate?: boolean
|
||||||
maxParticipants?: boolean
|
maxParticipants?: boolean
|
||||||
@@ -1200,7 +1380,7 @@ export type TripSelectScalar = {
|
|||||||
organizerId?: boolean
|
organizerId?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TripOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "title" | "description" | "mountain" | "location" | "date" | "endDate" | "maxParticipants" | "price" | "status" | "createdAt" | "updatedAt" | "organizerId", ExtArgs["result"]["trip"]>
|
export type TripOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "title" | "description" | "mountain" | "location" | "meetingPoint" | "itinerary" | "whatsIncluded" | "whatsExcluded" | "date" | "endDate" | "maxParticipants" | "price" | "status" | "createdAt" | "updatedAt" | "organizerId", ExtArgs["result"]["trip"]>
|
||||||
export type TripInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type TripInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
organizer?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
organizer?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||||
participants?: boolean | Prisma.Trip$participantsArgs<ExtArgs>
|
participants?: boolean | Prisma.Trip$participantsArgs<ExtArgs>
|
||||||
@@ -1229,6 +1409,22 @@ export type $TripPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs =
|
|||||||
description: string | null
|
description: string | null
|
||||||
mountain: string
|
mountain: string
|
||||||
location: string
|
location: string
|
||||||
|
/**
|
||||||
|
* Titik kumpul / meeting point (teks bebas)
|
||||||
|
*/
|
||||||
|
meetingPoint: string | null
|
||||||
|
/**
|
||||||
|
* Itinerary hari per hari (teks bebas, bullet OK)
|
||||||
|
*/
|
||||||
|
itinerary: string | null
|
||||||
|
/**
|
||||||
|
* Yang termasuk harga (teks bebas)
|
||||||
|
*/
|
||||||
|
whatsIncluded: string | null
|
||||||
|
/**
|
||||||
|
* Yang tidak termasuk (teks bebas)
|
||||||
|
*/
|
||||||
|
whatsExcluded: string | null
|
||||||
date: Date
|
date: Date
|
||||||
endDate: Date | null
|
endDate: Date | null
|
||||||
maxParticipants: number
|
maxParticipants: number
|
||||||
@@ -1669,6 +1865,10 @@ export interface TripFieldRefs {
|
|||||||
readonly description: Prisma.FieldRef<"Trip", 'String'>
|
readonly description: Prisma.FieldRef<"Trip", 'String'>
|
||||||
readonly mountain: Prisma.FieldRef<"Trip", 'String'>
|
readonly mountain: Prisma.FieldRef<"Trip", 'String'>
|
||||||
readonly location: Prisma.FieldRef<"Trip", 'String'>
|
readonly location: Prisma.FieldRef<"Trip", 'String'>
|
||||||
|
readonly meetingPoint: Prisma.FieldRef<"Trip", 'String'>
|
||||||
|
readonly itinerary: Prisma.FieldRef<"Trip", 'String'>
|
||||||
|
readonly whatsIncluded: Prisma.FieldRef<"Trip", 'String'>
|
||||||
|
readonly whatsExcluded: Prisma.FieldRef<"Trip", 'String'>
|
||||||
readonly date: Prisma.FieldRef<"Trip", 'DateTime'>
|
readonly date: Prisma.FieldRef<"Trip", 'DateTime'>
|
||||||
readonly endDate: Prisma.FieldRef<"Trip", 'DateTime'>
|
readonly endDate: Prisma.FieldRef<"Trip", 'DateTime'>
|
||||||
readonly maxParticipants: Prisma.FieldRef<"Trip", 'Int'>
|
readonly maxParticipants: Prisma.FieldRef<"Trip", 'Int'>
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ export type TripParticipantMinAggregateOutputType = {
|
|||||||
id: string | null
|
id: string | null
|
||||||
status: $Enums.ParticipantStatus | null
|
status: $Enums.ParticipantStatus | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
|
markedPaidAt: Date | null
|
||||||
|
paymentConfirmedAt: Date | null
|
||||||
tripId: string | null
|
tripId: string | null
|
||||||
userId: string | null
|
userId: string | null
|
||||||
}
|
}
|
||||||
@@ -36,6 +38,8 @@ export type TripParticipantMaxAggregateOutputType = {
|
|||||||
id: string | null
|
id: string | null
|
||||||
status: $Enums.ParticipantStatus | null
|
status: $Enums.ParticipantStatus | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
|
markedPaidAt: Date | null
|
||||||
|
paymentConfirmedAt: Date | null
|
||||||
tripId: string | null
|
tripId: string | null
|
||||||
userId: string | null
|
userId: string | null
|
||||||
}
|
}
|
||||||
@@ -44,6 +48,8 @@ export type TripParticipantCountAggregateOutputType = {
|
|||||||
id: number
|
id: number
|
||||||
status: number
|
status: number
|
||||||
createdAt: number
|
createdAt: number
|
||||||
|
markedPaidAt: number
|
||||||
|
paymentConfirmedAt: number
|
||||||
tripId: number
|
tripId: number
|
||||||
userId: number
|
userId: number
|
||||||
_all: number
|
_all: number
|
||||||
@@ -54,6 +60,8 @@ export type TripParticipantMinAggregateInputType = {
|
|||||||
id?: true
|
id?: true
|
||||||
status?: true
|
status?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
|
markedPaidAt?: true
|
||||||
|
paymentConfirmedAt?: true
|
||||||
tripId?: true
|
tripId?: true
|
||||||
userId?: true
|
userId?: true
|
||||||
}
|
}
|
||||||
@@ -62,6 +70,8 @@ export type TripParticipantMaxAggregateInputType = {
|
|||||||
id?: true
|
id?: true
|
||||||
status?: true
|
status?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
|
markedPaidAt?: true
|
||||||
|
paymentConfirmedAt?: true
|
||||||
tripId?: true
|
tripId?: true
|
||||||
userId?: true
|
userId?: true
|
||||||
}
|
}
|
||||||
@@ -70,6 +80,8 @@ export type TripParticipantCountAggregateInputType = {
|
|||||||
id?: true
|
id?: true
|
||||||
status?: true
|
status?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
|
markedPaidAt?: true
|
||||||
|
paymentConfirmedAt?: true
|
||||||
tripId?: true
|
tripId?: true
|
||||||
userId?: true
|
userId?: true
|
||||||
_all?: true
|
_all?: true
|
||||||
@@ -151,6 +163,8 @@ export type TripParticipantGroupByOutputType = {
|
|||||||
id: string
|
id: string
|
||||||
status: $Enums.ParticipantStatus
|
status: $Enums.ParticipantStatus
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
markedPaidAt: Date | null
|
||||||
|
paymentConfirmedAt: Date | null
|
||||||
tripId: string
|
tripId: string
|
||||||
userId: string
|
userId: string
|
||||||
_count: TripParticipantCountAggregateOutputType | null
|
_count: TripParticipantCountAggregateOutputType | null
|
||||||
@@ -180,6 +194,8 @@ export type TripParticipantWhereInput = {
|
|||||||
id?: Prisma.StringFilter<"TripParticipant"> | string
|
id?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
status?: Prisma.EnumParticipantStatusFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFilter<"TripParticipant"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"TripParticipant"> | Date | string
|
||||||
|
markedPaidAt?: Prisma.DateTimeNullableFilter<"TripParticipant"> | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.DateTimeNullableFilter<"TripParticipant"> | Date | string | null
|
||||||
tripId?: Prisma.StringFilter<"TripParticipant"> | string
|
tripId?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
userId?: Prisma.StringFilter<"TripParticipant"> | string
|
userId?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
trip?: Prisma.XOR<Prisma.TripScalarRelationFilter, Prisma.TripWhereInput>
|
trip?: Prisma.XOR<Prisma.TripScalarRelationFilter, Prisma.TripWhereInput>
|
||||||
@@ -190,6 +206,8 @@ export type TripParticipantOrderByWithRelationInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
|
markedPaidAt?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
paymentConfirmedAt?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
tripId?: Prisma.SortOrder
|
tripId?: Prisma.SortOrder
|
||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
trip?: Prisma.TripOrderByWithRelationInput
|
trip?: Prisma.TripOrderByWithRelationInput
|
||||||
@@ -204,6 +222,8 @@ export type TripParticipantWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
NOT?: Prisma.TripParticipantWhereInput | Prisma.TripParticipantWhereInput[]
|
NOT?: Prisma.TripParticipantWhereInput | Prisma.TripParticipantWhereInput[]
|
||||||
status?: Prisma.EnumParticipantStatusFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFilter<"TripParticipant"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"TripParticipant"> | Date | string
|
||||||
|
markedPaidAt?: Prisma.DateTimeNullableFilter<"TripParticipant"> | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.DateTimeNullableFilter<"TripParticipant"> | Date | string | null
|
||||||
tripId?: Prisma.StringFilter<"TripParticipant"> | string
|
tripId?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
userId?: Prisma.StringFilter<"TripParticipant"> | string
|
userId?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
trip?: Prisma.XOR<Prisma.TripScalarRelationFilter, Prisma.TripWhereInput>
|
trip?: Prisma.XOR<Prisma.TripScalarRelationFilter, Prisma.TripWhereInput>
|
||||||
@@ -214,6 +234,8 @@ export type TripParticipantOrderByWithAggregationInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
|
markedPaidAt?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
paymentConfirmedAt?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
tripId?: Prisma.SortOrder
|
tripId?: Prisma.SortOrder
|
||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
_count?: Prisma.TripParticipantCountOrderByAggregateInput
|
_count?: Prisma.TripParticipantCountOrderByAggregateInput
|
||||||
@@ -228,6 +250,8 @@ export type TripParticipantScalarWhereWithAggregatesInput = {
|
|||||||
id?: Prisma.StringWithAggregatesFilter<"TripParticipant"> | string
|
id?: Prisma.StringWithAggregatesFilter<"TripParticipant"> | string
|
||||||
status?: Prisma.EnumParticipantStatusWithAggregatesFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusWithAggregatesFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeWithAggregatesFilter<"TripParticipant"> | Date | string
|
createdAt?: Prisma.DateTimeWithAggregatesFilter<"TripParticipant"> | Date | string
|
||||||
|
markedPaidAt?: Prisma.DateTimeNullableWithAggregatesFilter<"TripParticipant"> | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"TripParticipant"> | Date | string | null
|
||||||
tripId?: Prisma.StringWithAggregatesFilter<"TripParticipant"> | string
|
tripId?: Prisma.StringWithAggregatesFilter<"TripParticipant"> | string
|
||||||
userId?: Prisma.StringWithAggregatesFilter<"TripParticipant"> | string
|
userId?: Prisma.StringWithAggregatesFilter<"TripParticipant"> | string
|
||||||
}
|
}
|
||||||
@@ -236,6 +260,8 @@ export type TripParticipantCreateInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
trip: Prisma.TripCreateNestedOneWithoutParticipantsInput
|
trip: Prisma.TripCreateNestedOneWithoutParticipantsInput
|
||||||
user: Prisma.UserCreateNestedOneWithoutParticipationsInput
|
user: Prisma.UserCreateNestedOneWithoutParticipationsInput
|
||||||
}
|
}
|
||||||
@@ -244,6 +270,8 @@ export type TripParticipantUncheckedCreateInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
tripId: string
|
tripId: string
|
||||||
userId: string
|
userId: string
|
||||||
}
|
}
|
||||||
@@ -252,6 +280,8 @@ export type TripParticipantUpdateInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
trip?: Prisma.TripUpdateOneRequiredWithoutParticipantsNestedInput
|
trip?: Prisma.TripUpdateOneRequiredWithoutParticipantsNestedInput
|
||||||
user?: Prisma.UserUpdateOneRequiredWithoutParticipationsNestedInput
|
user?: Prisma.UserUpdateOneRequiredWithoutParticipationsNestedInput
|
||||||
}
|
}
|
||||||
@@ -260,6 +290,8 @@ export type TripParticipantUncheckedUpdateInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
}
|
}
|
||||||
@@ -268,6 +300,8 @@ export type TripParticipantCreateManyInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
tripId: string
|
tripId: string
|
||||||
userId: string
|
userId: string
|
||||||
}
|
}
|
||||||
@@ -276,12 +310,16 @@ export type TripParticipantUpdateManyMutationInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TripParticipantUncheckedUpdateManyInput = {
|
export type TripParticipantUncheckedUpdateManyInput = {
|
||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
}
|
}
|
||||||
@@ -305,6 +343,8 @@ export type TripParticipantCountOrderByAggregateInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
|
markedPaidAt?: Prisma.SortOrder
|
||||||
|
paymentConfirmedAt?: Prisma.SortOrder
|
||||||
tripId?: Prisma.SortOrder
|
tripId?: Prisma.SortOrder
|
||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -313,6 +353,8 @@ export type TripParticipantMaxOrderByAggregateInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
|
markedPaidAt?: Prisma.SortOrder
|
||||||
|
paymentConfirmedAt?: Prisma.SortOrder
|
||||||
tripId?: Prisma.SortOrder
|
tripId?: Prisma.SortOrder
|
||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -321,6 +363,8 @@ export type TripParticipantMinOrderByAggregateInput = {
|
|||||||
id?: Prisma.SortOrder
|
id?: Prisma.SortOrder
|
||||||
status?: Prisma.SortOrder
|
status?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
|
markedPaidAt?: Prisma.SortOrder
|
||||||
|
paymentConfirmedAt?: Prisma.SortOrder
|
||||||
tripId?: Prisma.SortOrder
|
tripId?: Prisma.SortOrder
|
||||||
userId?: Prisma.SortOrder
|
userId?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -417,6 +461,8 @@ export type TripParticipantCreateWithoutUserInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
trip: Prisma.TripCreateNestedOneWithoutParticipantsInput
|
trip: Prisma.TripCreateNestedOneWithoutParticipantsInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,6 +470,8 @@ export type TripParticipantUncheckedCreateWithoutUserInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
tripId: string
|
tripId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,6 +508,8 @@ export type TripParticipantScalarWhereInput = {
|
|||||||
id?: Prisma.StringFilter<"TripParticipant"> | string
|
id?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
status?: Prisma.EnumParticipantStatusFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFilter<"TripParticipant"> | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFilter<"TripParticipant"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"TripParticipant"> | Date | string
|
||||||
|
markedPaidAt?: Prisma.DateTimeNullableFilter<"TripParticipant"> | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.DateTimeNullableFilter<"TripParticipant"> | Date | string | null
|
||||||
tripId?: Prisma.StringFilter<"TripParticipant"> | string
|
tripId?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
userId?: Prisma.StringFilter<"TripParticipant"> | string
|
userId?: Prisma.StringFilter<"TripParticipant"> | string
|
||||||
}
|
}
|
||||||
@@ -468,6 +518,8 @@ export type TripParticipantCreateWithoutTripInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
user: Prisma.UserCreateNestedOneWithoutParticipationsInput
|
user: Prisma.UserCreateNestedOneWithoutParticipationsInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,6 +527,8 @@ export type TripParticipantUncheckedCreateWithoutTripInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
userId: string
|
userId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,6 +562,8 @@ export type TripParticipantCreateManyUserInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
tripId: string
|
tripId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,6 +571,8 @@ export type TripParticipantUpdateWithoutUserInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
trip?: Prisma.TripUpdateOneRequiredWithoutParticipantsNestedInput
|
trip?: Prisma.TripUpdateOneRequiredWithoutParticipantsNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,6 +580,8 @@ export type TripParticipantUncheckedUpdateWithoutUserInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,6 +589,8 @@ export type TripParticipantUncheckedUpdateManyWithoutUserInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
tripId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,6 +598,8 @@ export type TripParticipantCreateManyTripInput = {
|
|||||||
id?: string
|
id?: string
|
||||||
status?: $Enums.ParticipantStatus
|
status?: $Enums.ParticipantStatus
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
|
markedPaidAt?: Date | string | null
|
||||||
|
paymentConfirmedAt?: Date | string | null
|
||||||
userId: string
|
userId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,6 +607,8 @@ export type TripParticipantUpdateWithoutTripInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
user?: Prisma.UserUpdateOneRequiredWithoutParticipationsNestedInput
|
user?: Prisma.UserUpdateOneRequiredWithoutParticipationsNestedInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,6 +616,8 @@ export type TripParticipantUncheckedUpdateWithoutTripInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,6 +625,8 @@ export type TripParticipantUncheckedUpdateManyWithoutTripInput = {
|
|||||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
status?: Prisma.EnumParticipantStatusFieldUpdateOperationsInput | $Enums.ParticipantStatus
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
|
markedPaidAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
|
paymentConfirmedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,6 +636,8 @@ export type TripParticipantSelect<ExtArgs extends runtime.Types.Extensions.Inter
|
|||||||
id?: boolean
|
id?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
|
markedPaidAt?: boolean
|
||||||
|
paymentConfirmedAt?: boolean
|
||||||
tripId?: boolean
|
tripId?: boolean
|
||||||
userId?: boolean
|
userId?: boolean
|
||||||
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
||||||
@@ -576,6 +648,8 @@ export type TripParticipantSelectCreateManyAndReturn<ExtArgs extends runtime.Typ
|
|||||||
id?: boolean
|
id?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
|
markedPaidAt?: boolean
|
||||||
|
paymentConfirmedAt?: boolean
|
||||||
tripId?: boolean
|
tripId?: boolean
|
||||||
userId?: boolean
|
userId?: boolean
|
||||||
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
||||||
@@ -586,6 +660,8 @@ export type TripParticipantSelectUpdateManyAndReturn<ExtArgs extends runtime.Typ
|
|||||||
id?: boolean
|
id?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
|
markedPaidAt?: boolean
|
||||||
|
paymentConfirmedAt?: boolean
|
||||||
tripId?: boolean
|
tripId?: boolean
|
||||||
userId?: boolean
|
userId?: boolean
|
||||||
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
||||||
@@ -596,11 +672,13 @@ export type TripParticipantSelectScalar = {
|
|||||||
id?: boolean
|
id?: boolean
|
||||||
status?: boolean
|
status?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
|
markedPaidAt?: boolean
|
||||||
|
paymentConfirmedAt?: boolean
|
||||||
tripId?: boolean
|
tripId?: boolean
|
||||||
userId?: boolean
|
userId?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TripParticipantOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "status" | "createdAt" | "tripId" | "userId", ExtArgs["result"]["tripParticipant"]>
|
export type TripParticipantOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "status" | "createdAt" | "markedPaidAt" | "paymentConfirmedAt" | "tripId" | "userId", ExtArgs["result"]["tripParticipant"]>
|
||||||
export type TripParticipantInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type TripParticipantInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
trip?: boolean | Prisma.TripDefaultArgs<ExtArgs>
|
||||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||||
@@ -624,6 +702,14 @@ export type $TripParticipantPayload<ExtArgs extends runtime.Types.Extensions.Int
|
|||||||
id: string
|
id: string
|
||||||
status: $Enums.ParticipantStatus
|
status: $Enums.ParticipantStatus
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
|
/**
|
||||||
|
* Peserta menekan "Saya sudah bayar" (pembayaran manual)
|
||||||
|
*/
|
||||||
|
markedPaidAt: Date | null
|
||||||
|
/**
|
||||||
|
* Organizer mengonfirmasi uang sudah masuk
|
||||||
|
*/
|
||||||
|
paymentConfirmedAt: Date | null
|
||||||
tripId: string
|
tripId: string
|
||||||
userId: string
|
userId: string
|
||||||
}, ExtArgs["result"]["tripParticipant"]>
|
}, ExtArgs["result"]["tripParticipant"]>
|
||||||
@@ -1054,6 +1140,8 @@ export interface TripParticipantFieldRefs {
|
|||||||
readonly id: Prisma.FieldRef<"TripParticipant", 'String'>
|
readonly id: Prisma.FieldRef<"TripParticipant", 'String'>
|
||||||
readonly status: Prisma.FieldRef<"TripParticipant", 'ParticipantStatus'>
|
readonly status: Prisma.FieldRef<"TripParticipant", 'ParticipantStatus'>
|
||||||
readonly createdAt: Prisma.FieldRef<"TripParticipant", 'DateTime'>
|
readonly createdAt: Prisma.FieldRef<"TripParticipant", 'DateTime'>
|
||||||
|
readonly markedPaidAt: Prisma.FieldRef<"TripParticipant", 'DateTime'>
|
||||||
|
readonly paymentConfirmedAt: Prisma.FieldRef<"TripParticipant", 'DateTime'>
|
||||||
readonly tripId: Prisma.FieldRef<"TripParticipant", 'String'>
|
readonly tripId: Prisma.FieldRef<"TripParticipant", 'String'>
|
||||||
readonly userId: Prisma.FieldRef<"TripParticipant", 'String'>
|
readonly userId: Prisma.FieldRef<"TripParticipant", 'String'>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export type UserMinAggregateOutputType = {
|
|||||||
email: string | null
|
email: string | null
|
||||||
password: string | null
|
password: string | null
|
||||||
image: string | null
|
image: string | null
|
||||||
|
isVerified: boolean | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
updatedAt: Date | null
|
updatedAt: Date | null
|
||||||
}
|
}
|
||||||
@@ -40,6 +41,7 @@ export type UserMaxAggregateOutputType = {
|
|||||||
email: string | null
|
email: string | null
|
||||||
password: string | null
|
password: string | null
|
||||||
image: string | null
|
image: string | null
|
||||||
|
isVerified: boolean | null
|
||||||
createdAt: Date | null
|
createdAt: Date | null
|
||||||
updatedAt: Date | null
|
updatedAt: Date | null
|
||||||
}
|
}
|
||||||
@@ -50,6 +52,7 @@ export type UserCountAggregateOutputType = {
|
|||||||
email: number
|
email: number
|
||||||
password: number
|
password: number
|
||||||
image: number
|
image: number
|
||||||
|
isVerified: number
|
||||||
createdAt: number
|
createdAt: number
|
||||||
updatedAt: number
|
updatedAt: number
|
||||||
_all: number
|
_all: number
|
||||||
@@ -62,6 +65,7 @@ export type UserMinAggregateInputType = {
|
|||||||
email?: true
|
email?: true
|
||||||
password?: true
|
password?: true
|
||||||
image?: true
|
image?: true
|
||||||
|
isVerified?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
updatedAt?: true
|
updatedAt?: true
|
||||||
}
|
}
|
||||||
@@ -72,6 +76,7 @@ export type UserMaxAggregateInputType = {
|
|||||||
email?: true
|
email?: true
|
||||||
password?: true
|
password?: true
|
||||||
image?: true
|
image?: true
|
||||||
|
isVerified?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
updatedAt?: true
|
updatedAt?: true
|
||||||
}
|
}
|
||||||
@@ -82,6 +87,7 @@ export type UserCountAggregateInputType = {
|
|||||||
email?: true
|
email?: true
|
||||||
password?: true
|
password?: true
|
||||||
image?: true
|
image?: true
|
||||||
|
isVerified?: true
|
||||||
createdAt?: true
|
createdAt?: true
|
||||||
updatedAt?: true
|
updatedAt?: true
|
||||||
_all?: true
|
_all?: true
|
||||||
@@ -165,6 +171,7 @@ export type UserGroupByOutputType = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image: string | null
|
image: string | null
|
||||||
|
isVerified: boolean
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
_count: UserCountAggregateOutputType | null
|
_count: UserCountAggregateOutputType | null
|
||||||
@@ -196,6 +203,7 @@ export type UserWhereInput = {
|
|||||||
email?: Prisma.StringFilter<"User"> | string
|
email?: Prisma.StringFilter<"User"> | string
|
||||||
password?: Prisma.StringFilter<"User"> | string
|
password?: Prisma.StringFilter<"User"> | string
|
||||||
image?: Prisma.StringNullableFilter<"User"> | string | null
|
image?: Prisma.StringNullableFilter<"User"> | string | null
|
||||||
|
isVerified?: Prisma.BoolFilter<"User"> | boolean
|
||||||
createdAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
||||||
trips?: Prisma.TripListRelationFilter
|
trips?: Prisma.TripListRelationFilter
|
||||||
@@ -209,6 +217,7 @@ export type UserOrderByWithRelationInput = {
|
|||||||
email?: Prisma.SortOrder
|
email?: Prisma.SortOrder
|
||||||
password?: Prisma.SortOrder
|
password?: Prisma.SortOrder
|
||||||
image?: Prisma.SortOrderInput | Prisma.SortOrder
|
image?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
isVerified?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
trips?: Prisma.TripOrderByRelationAggregateInput
|
trips?: Prisma.TripOrderByRelationAggregateInput
|
||||||
@@ -225,6 +234,7 @@ export type UserWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
name?: Prisma.StringFilter<"User"> | string
|
name?: Prisma.StringFilter<"User"> | string
|
||||||
password?: Prisma.StringFilter<"User"> | string
|
password?: Prisma.StringFilter<"User"> | string
|
||||||
image?: Prisma.StringNullableFilter<"User"> | string | null
|
image?: Prisma.StringNullableFilter<"User"> | string | null
|
||||||
|
isVerified?: Prisma.BoolFilter<"User"> | boolean
|
||||||
createdAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
createdAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
||||||
trips?: Prisma.TripListRelationFilter
|
trips?: Prisma.TripListRelationFilter
|
||||||
@@ -238,6 +248,7 @@ export type UserOrderByWithAggregationInput = {
|
|||||||
email?: Prisma.SortOrder
|
email?: Prisma.SortOrder
|
||||||
password?: Prisma.SortOrder
|
password?: Prisma.SortOrder
|
||||||
image?: Prisma.SortOrderInput | Prisma.SortOrder
|
image?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||||
|
isVerified?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
_count?: Prisma.UserCountOrderByAggregateInput
|
_count?: Prisma.UserCountOrderByAggregateInput
|
||||||
@@ -254,6 +265,7 @@ export type UserScalarWhereWithAggregatesInput = {
|
|||||||
email?: Prisma.StringWithAggregatesFilter<"User"> | string
|
email?: Prisma.StringWithAggregatesFilter<"User"> | string
|
||||||
password?: Prisma.StringWithAggregatesFilter<"User"> | string
|
password?: Prisma.StringWithAggregatesFilter<"User"> | string
|
||||||
image?: Prisma.StringNullableWithAggregatesFilter<"User"> | string | null
|
image?: Prisma.StringNullableWithAggregatesFilter<"User"> | string | null
|
||||||
|
isVerified?: Prisma.BoolWithAggregatesFilter<"User"> | boolean
|
||||||
createdAt?: Prisma.DateTimeWithAggregatesFilter<"User"> | Date | string
|
createdAt?: Prisma.DateTimeWithAggregatesFilter<"User"> | Date | string
|
||||||
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"User"> | Date | string
|
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"User"> | Date | string
|
||||||
}
|
}
|
||||||
@@ -264,6 +276,7 @@ export type UserCreateInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
trips?: Prisma.TripCreateNestedManyWithoutOrganizerInput
|
trips?: Prisma.TripCreateNestedManyWithoutOrganizerInput
|
||||||
@@ -277,6 +290,7 @@ export type UserUncheckedCreateInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
trips?: Prisma.TripUncheckedCreateNestedManyWithoutOrganizerInput
|
trips?: Prisma.TripUncheckedCreateNestedManyWithoutOrganizerInput
|
||||||
@@ -290,6 +304,7 @@ export type UserUpdateInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
trips?: Prisma.TripUpdateManyWithoutOrganizerNestedInput
|
trips?: Prisma.TripUpdateManyWithoutOrganizerNestedInput
|
||||||
@@ -303,6 +318,7 @@ export type UserUncheckedUpdateInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
trips?: Prisma.TripUncheckedUpdateManyWithoutOrganizerNestedInput
|
trips?: Prisma.TripUncheckedUpdateManyWithoutOrganizerNestedInput
|
||||||
@@ -316,6 +332,7 @@ export type UserCreateManyInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
}
|
}
|
||||||
@@ -326,6 +343,7 @@ export type UserUpdateManyMutationInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
}
|
}
|
||||||
@@ -336,6 +354,7 @@ export type UserUncheckedUpdateManyInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
}
|
}
|
||||||
@@ -346,6 +365,7 @@ export type UserCountOrderByAggregateInput = {
|
|||||||
email?: Prisma.SortOrder
|
email?: Prisma.SortOrder
|
||||||
password?: Prisma.SortOrder
|
password?: Prisma.SortOrder
|
||||||
image?: Prisma.SortOrder
|
image?: Prisma.SortOrder
|
||||||
|
isVerified?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -356,6 +376,7 @@ export type UserMaxOrderByAggregateInput = {
|
|||||||
email?: Prisma.SortOrder
|
email?: Prisma.SortOrder
|
||||||
password?: Prisma.SortOrder
|
password?: Prisma.SortOrder
|
||||||
image?: Prisma.SortOrder
|
image?: Prisma.SortOrder
|
||||||
|
isVerified?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -366,6 +387,7 @@ export type UserMinOrderByAggregateInput = {
|
|||||||
email?: Prisma.SortOrder
|
email?: Prisma.SortOrder
|
||||||
password?: Prisma.SortOrder
|
password?: Prisma.SortOrder
|
||||||
image?: Prisma.SortOrder
|
image?: Prisma.SortOrder
|
||||||
|
isVerified?: Prisma.SortOrder
|
||||||
createdAt?: Prisma.SortOrder
|
createdAt?: Prisma.SortOrder
|
||||||
updatedAt?: Prisma.SortOrder
|
updatedAt?: Prisma.SortOrder
|
||||||
}
|
}
|
||||||
@@ -383,6 +405,10 @@ export type NullableStringFieldUpdateOperationsInput = {
|
|||||||
set?: string | null
|
set?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BoolFieldUpdateOperationsInput = {
|
||||||
|
set?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export type DateTimeFieldUpdateOperationsInput = {
|
export type DateTimeFieldUpdateOperationsInput = {
|
||||||
set?: Date | string
|
set?: Date | string
|
||||||
}
|
}
|
||||||
@@ -435,6 +461,7 @@ export type UserCreateWithoutTripsInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
participations?: Prisma.TripParticipantCreateNestedManyWithoutUserInput
|
participations?: Prisma.TripParticipantCreateNestedManyWithoutUserInput
|
||||||
@@ -447,6 +474,7 @@ export type UserUncheckedCreateWithoutTripsInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
participations?: Prisma.TripParticipantUncheckedCreateNestedManyWithoutUserInput
|
participations?: Prisma.TripParticipantUncheckedCreateNestedManyWithoutUserInput
|
||||||
@@ -475,6 +503,7 @@ export type UserUpdateWithoutTripsInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
participations?: Prisma.TripParticipantUpdateManyWithoutUserNestedInput
|
participations?: Prisma.TripParticipantUpdateManyWithoutUserNestedInput
|
||||||
@@ -487,6 +516,7 @@ export type UserUncheckedUpdateWithoutTripsInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
participations?: Prisma.TripParticipantUncheckedUpdateManyWithoutUserNestedInput
|
participations?: Prisma.TripParticipantUncheckedUpdateManyWithoutUserNestedInput
|
||||||
@@ -499,6 +529,7 @@ export type UserCreateWithoutTripReviewsInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
trips?: Prisma.TripCreateNestedManyWithoutOrganizerInput
|
trips?: Prisma.TripCreateNestedManyWithoutOrganizerInput
|
||||||
@@ -511,6 +542,7 @@ export type UserUncheckedCreateWithoutTripReviewsInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
trips?: Prisma.TripUncheckedCreateNestedManyWithoutOrganizerInput
|
trips?: Prisma.TripUncheckedCreateNestedManyWithoutOrganizerInput
|
||||||
@@ -539,6 +571,7 @@ export type UserUpdateWithoutTripReviewsInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
trips?: Prisma.TripUpdateManyWithoutOrganizerNestedInput
|
trips?: Prisma.TripUpdateManyWithoutOrganizerNestedInput
|
||||||
@@ -551,6 +584,7 @@ export type UserUncheckedUpdateWithoutTripReviewsInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
trips?: Prisma.TripUncheckedUpdateManyWithoutOrganizerNestedInput
|
trips?: Prisma.TripUncheckedUpdateManyWithoutOrganizerNestedInput
|
||||||
@@ -563,6 +597,7 @@ export type UserCreateWithoutParticipationsInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
trips?: Prisma.TripCreateNestedManyWithoutOrganizerInput
|
trips?: Prisma.TripCreateNestedManyWithoutOrganizerInput
|
||||||
@@ -575,6 +610,7 @@ export type UserUncheckedCreateWithoutParticipationsInput = {
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image?: string | null
|
image?: string | null
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: Date | string
|
createdAt?: Date | string
|
||||||
updatedAt?: Date | string
|
updatedAt?: Date | string
|
||||||
trips?: Prisma.TripUncheckedCreateNestedManyWithoutOrganizerInput
|
trips?: Prisma.TripUncheckedCreateNestedManyWithoutOrganizerInput
|
||||||
@@ -603,6 +639,7 @@ export type UserUpdateWithoutParticipationsInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
trips?: Prisma.TripUpdateManyWithoutOrganizerNestedInput
|
trips?: Prisma.TripUpdateManyWithoutOrganizerNestedInput
|
||||||
@@ -615,6 +652,7 @@ export type UserUncheckedUpdateWithoutParticipationsInput = {
|
|||||||
email?: Prisma.StringFieldUpdateOperationsInput | string
|
email?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
image?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||||
|
isVerified?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
trips?: Prisma.TripUncheckedUpdateManyWithoutOrganizerNestedInput
|
trips?: Prisma.TripUncheckedUpdateManyWithoutOrganizerNestedInput
|
||||||
@@ -676,6 +714,7 @@ export type UserSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = r
|
|||||||
email?: boolean
|
email?: boolean
|
||||||
password?: boolean
|
password?: boolean
|
||||||
image?: boolean
|
image?: boolean
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
trips?: boolean | Prisma.User$tripsArgs<ExtArgs>
|
trips?: boolean | Prisma.User$tripsArgs<ExtArgs>
|
||||||
@@ -690,6 +729,7 @@ export type UserSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensio
|
|||||||
email?: boolean
|
email?: boolean
|
||||||
password?: boolean
|
password?: boolean
|
||||||
image?: boolean
|
image?: boolean
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
}, ExtArgs["result"]["user"]>
|
}, ExtArgs["result"]["user"]>
|
||||||
@@ -700,6 +740,7 @@ export type UserSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensio
|
|||||||
email?: boolean
|
email?: boolean
|
||||||
password?: boolean
|
password?: boolean
|
||||||
image?: boolean
|
image?: boolean
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
}, ExtArgs["result"]["user"]>
|
}, ExtArgs["result"]["user"]>
|
||||||
@@ -710,11 +751,12 @@ export type UserSelectScalar = {
|
|||||||
email?: boolean
|
email?: boolean
|
||||||
password?: boolean
|
password?: boolean
|
||||||
image?: boolean
|
image?: boolean
|
||||||
|
isVerified?: boolean
|
||||||
createdAt?: boolean
|
createdAt?: boolean
|
||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UserOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "email" | "password" | "image" | "createdAt" | "updatedAt", ExtArgs["result"]["user"]>
|
export type UserOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "email" | "password" | "image" | "isVerified" | "createdAt" | "updatedAt", ExtArgs["result"]["user"]>
|
||||||
export type UserInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type UserInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
trips?: boolean | Prisma.User$tripsArgs<ExtArgs>
|
trips?: boolean | Prisma.User$tripsArgs<ExtArgs>
|
||||||
participations?: boolean | Prisma.User$participationsArgs<ExtArgs>
|
participations?: boolean | Prisma.User$participationsArgs<ExtArgs>
|
||||||
@@ -737,6 +779,10 @@ export type $UserPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs =
|
|||||||
email: string
|
email: string
|
||||||
password: string
|
password: string
|
||||||
image: string | null
|
image: string | null
|
||||||
|
/**
|
||||||
|
* Akun diverifikasi tim SeTrip (manual / admin) — tampil sebagai badge kepercayaan
|
||||||
|
*/
|
||||||
|
isVerified: boolean
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
}, ExtArgs["result"]["user"]>
|
}, ExtArgs["result"]["user"]>
|
||||||
@@ -1170,6 +1216,7 @@ export interface UserFieldRefs {
|
|||||||
readonly email: Prisma.FieldRef<"User", 'String'>
|
readonly email: Prisma.FieldRef<"User", 'String'>
|
||||||
readonly password: Prisma.FieldRef<"User", 'String'>
|
readonly password: Prisma.FieldRef<"User", 'String'>
|
||||||
readonly image: Prisma.FieldRef<"User", 'String'>
|
readonly image: Prisma.FieldRef<"User", 'String'>
|
||||||
|
readonly isVerified: Prisma.FieldRef<"User", 'Boolean'>
|
||||||
readonly createdAt: Prisma.FieldRef<"User", 'DateTime'>
|
readonly createdAt: Prisma.FieldRef<"User", 'DateTime'>
|
||||||
readonly updatedAt: Prisma.FieldRef<"User", 'DateTime'>
|
readonly updatedAt: Prisma.FieldRef<"User", 'DateTime'>
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-2
@@ -173,8 +173,18 @@ export default async function ProfilePage() {
|
|||||||
date={t.date}
|
date={t.date}
|
||||||
endDate={t.endDate}
|
endDate={t.endDate}
|
||||||
rightSlot={
|
rightSlot={
|
||||||
<span className="text-neutral-400">
|
<span
|
||||||
{p.status === "CONFIRMED" ? "Terdaftar" : p.status}
|
className={
|
||||||
|
p.status === "PENDING"
|
||||||
|
? "font-medium text-amber-700"
|
||||||
|
: "text-neutral-400"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{p.status === "CONFIRMED"
|
||||||
|
? "Terkonfirmasi"
|
||||||
|
: p.status === "PENDING"
|
||||||
|
? "Menunggu organizer"
|
||||||
|
: p.status}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+94
-8
@@ -3,8 +3,14 @@ import { getServerSession } from "next-auth";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { authOptions } from "@/lib/auth";
|
import { authOptions } from "@/lib/auth";
|
||||||
import { tripService } from "@/server/services/trip.service";
|
import { tripService } from "@/server/services/trip.service";
|
||||||
import { formatRupiah, formatDateRange } from "@/lib/utils";
|
import { trustService } from "@/server/services/trust.service";
|
||||||
|
import { formatRupiah } from "@/lib/utils";
|
||||||
|
import { formatTripCalendarDateRangeLong } from "@/lib/trip-dates";
|
||||||
import { JoinTripButton } from "@/features/trip/components/join-trip-button";
|
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";
|
||||||
|
import { TripProgramBlock } from "@/features/trip/components/trip-program-block";
|
||||||
|
import { OrganizerPaymentQueue } from "@/features/booking/components/organizer-payment-queue";
|
||||||
import { ImageGallery } from "@/features/trip/components/image-gallery";
|
import { ImageGallery } from "@/features/trip/components/image-gallery";
|
||||||
import { TripReviewSection } from "@/features/review/components/trip-review-section";
|
import { TripReviewSection } from "@/features/review/components/trip-review-section";
|
||||||
import {
|
import {
|
||||||
@@ -27,10 +33,21 @@ export default async function TripDetailPage({
|
|||||||
notFound();
|
notFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const organizerTrust = await trustService.getOrganizerTrust(
|
||||||
|
trip.organizerId
|
||||||
|
);
|
||||||
|
|
||||||
const activeParticipants = trip.participants.filter(
|
const activeParticipants = trip.participants.filter(
|
||||||
(p) => p.status !== "CANCELLED"
|
(p) => p.status !== "CANCELLED"
|
||||||
);
|
);
|
||||||
|
const confirmedParticipants = activeParticipants.filter(
|
||||||
|
(p) => p.status === "CONFIRMED"
|
||||||
|
);
|
||||||
|
const pendingParticipants = activeParticipants.filter(
|
||||||
|
(p) => p.status === "PENDING"
|
||||||
|
);
|
||||||
const participantCount = activeParticipants.length;
|
const participantCount = activeParticipants.length;
|
||||||
|
const confirmedCount = confirmedParticipants.length;
|
||||||
const spotsLeft = trip.maxParticipants - participantCount;
|
const spotsLeft = trip.maxParticipants - participantCount;
|
||||||
const fillPercent = Math.min(
|
const fillPercent = Math.min(
|
||||||
(participantCount / trip.maxParticipants) * 100,
|
(participantCount / trip.maxParticipants) * 100,
|
||||||
@@ -63,6 +80,10 @@ export default async function TripDetailPage({
|
|||||||
) / 10
|
) / 10
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
const paymentPendingParticipants = activeParticipants.filter(
|
||||||
|
(p) => p.markedPaidAt && !p.paymentConfirmedAt
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto max-w-3xl px-4 py-4 sm:py-8">
|
<div className="mx-auto max-w-3xl px-4 py-4 sm:py-8">
|
||||||
{/* Breadcrumb */}
|
{/* Breadcrumb */}
|
||||||
@@ -123,7 +144,7 @@ export default async function TripDetailPage({
|
|||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<p className="text-[10px] font-medium text-neutral-400 sm:text-xs">Tanggal</p>
|
<p className="text-[10px] font-medium text-neutral-400 sm:text-xs">Tanggal</p>
|
||||||
<p className="truncate text-xs font-semibold text-neutral-800 sm:text-sm">
|
<p className="truncate text-xs font-semibold text-neutral-800 sm:text-sm">
|
||||||
{formatDateRange(trip.date, trip.endDate)}
|
{formatTripCalendarDateRangeLong(trip.date, trip.endDate)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -153,6 +174,12 @@ export default async function TripDetailPage({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<OrganizerTrustPanel
|
||||||
|
name={trip.organizer.name}
|
||||||
|
image={trip.organizer.image}
|
||||||
|
trust={organizerTrust}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Participant Progress */}
|
{/* Participant Progress */}
|
||||||
<div className="rounded-xl border border-neutral-200 p-3 sm:p-4">
|
<div className="rounded-xl border border-neutral-200 p-3 sm:p-4">
|
||||||
<div className="mb-2 flex items-center justify-between">
|
<div className="mb-2 flex items-center justify-between">
|
||||||
@@ -179,12 +206,30 @@ export default async function TripDetailPage({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-1.5 text-[11px] text-neutral-500 sm:text-xs">
|
<p className="mt-1.5 text-[11px] text-neutral-500 sm:text-xs">
|
||||||
|
Maksimal {trip.maxParticipants} orang. Saat ini {participantCount}{" "}
|
||||||
|
mendaftar, {confirmedCount} sudah disetujui organizer.
|
||||||
|
</p>
|
||||||
|
<p className="mt-1 text-[11px] text-neutral-500 sm:text-xs">
|
||||||
{spotsLeft > 0
|
{spotsLeft > 0
|
||||||
? `${spotsLeft} slot tersisa — yuk gabung!`
|
? `Masih ada ${spotsLeft} tempat — yuk gabung!`
|
||||||
: "Trip sudah penuh"}
|
: "Trip sudah penuh"}
|
||||||
|
{confirmedCount < participantCount && (
|
||||||
|
<>
|
||||||
|
{" "}
|
||||||
|
· {participantCount - confirmedCount} menunggu persetujuan
|
||||||
|
organizer
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<TripProgramBlock
|
||||||
|
meetingPoint={trip.meetingPoint}
|
||||||
|
itinerary={trip.itinerary}
|
||||||
|
whatsIncluded={trip.whatsIncluded}
|
||||||
|
whatsExcluded={trip.whatsExcluded}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
{trip.description && (
|
{trip.description && (
|
||||||
<div>
|
<div>
|
||||||
@@ -197,12 +242,50 @@ export default async function TripDetailPage({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{isOrganizer && pendingParticipants.length > 0 && (
|
||||||
|
<OrganizerJoinRequests
|
||||||
|
tripId={trip.id}
|
||||||
|
pending={pendingParticipants.map((p) => ({
|
||||||
|
id: p.id,
|
||||||
|
user: p.user,
|
||||||
|
markedPaidAt: p.markedPaidAt,
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isOrganizer && paymentPendingParticipants.length > 0 && (
|
||||||
|
<OrganizerPaymentQueue
|
||||||
|
tripId={trip.id}
|
||||||
|
items={paymentPendingParticipants.map((p) => ({
|
||||||
|
id: p.id,
|
||||||
|
user: p.user,
|
||||||
|
joinStatus:
|
||||||
|
p.status === "PENDING" ? ("PENDING" as const) : ("CONFIRMED" as const),
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Action */}
|
{/* Action */}
|
||||||
<JoinTripButton
|
<JoinTripButton
|
||||||
tripId={trip.id}
|
tripId={trip.id}
|
||||||
isLoggedIn={!!session?.user}
|
isLoggedIn={!!session?.user}
|
||||||
isOrganizer={isOrganizer}
|
isOrganizer={isOrganizer}
|
||||||
isJoined={!!currentParticipation}
|
isJoined={!!currentParticipation}
|
||||||
|
participationStatus={
|
||||||
|
currentParticipation?.status === "PENDING" ||
|
||||||
|
currentParticipation?.status === "CONFIRMED"
|
||||||
|
? currentParticipation.status
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
participantPayment={
|
||||||
|
currentParticipation
|
||||||
|
? {
|
||||||
|
markedPaidAt: currentParticipation.markedPaidAt,
|
||||||
|
paymentConfirmedAt:
|
||||||
|
currentParticipation.paymentConfirmedAt,
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
}
|
||||||
isFull={spotsLeft <= 0}
|
isFull={spotsLeft <= 0}
|
||||||
tripStatus={trip.status}
|
tripStatus={trip.status}
|
||||||
isDeparturePast={isDeparturePast}
|
isDeparturePast={isDeparturePast}
|
||||||
@@ -226,18 +309,21 @@ export default async function TripDetailPage({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Participants List */}
|
{/* Peserta yang sudah disetujui organizer (publik) */}
|
||||||
<div>
|
<div>
|
||||||
<h2 className="mb-3 text-xs font-bold text-neutral-700 sm:text-sm">
|
<h2 className="mb-3 text-xs font-bold text-neutral-700 sm:text-sm">
|
||||||
Peserta ({participantCount})
|
Peserta terkonfirmasi ({confirmedCount})
|
||||||
</h2>
|
</h2>
|
||||||
{participantCount === 0 ? (
|
{confirmedCount === 0 ? (
|
||||||
<p className="text-xs text-neutral-400 sm:text-sm">
|
<p className="text-xs text-neutral-400 sm:text-sm">
|
||||||
Belum ada peserta. Jadilah yang pertama! 🎒
|
Belum ada peserta yang dikonfirmasi.{" "}
|
||||||
|
{pendingParticipants.length > 0
|
||||||
|
? "Cek permintaan join di atas untuk menyetujui peserta."
|
||||||
|
: "Jadilah yang pertama mendaftar! 🎒"}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-wrap gap-1.5 sm:gap-2">
|
<div className="flex flex-wrap gap-1.5 sm:gap-2">
|
||||||
{activeParticipants.map((p) => (
|
{confirmedParticipants.map((p) => (
|
||||||
<div
|
<div
|
||||||
key={p.id}
|
key={p.id}
|
||||||
className="flex items-center gap-1.5 rounded-full bg-neutral-100 px-2.5 py-1 sm:gap-2 sm:px-3 sm:py-1.5"
|
className="flex items-center gap-1.5 rounded-full bg-neutral-100 px-2.5 py-1 sm:gap-2 sm:px-3 sm:py-1.5"
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import { getServerSession } from "next-auth";
|
||||||
|
import { authOptions } from "@/lib/auth";
|
||||||
|
import { tripService } from "@/server/services/trip.service";
|
||||||
|
import { revalidatePath } from "next/cache";
|
||||||
|
|
||||||
|
export async function markParticipantPaidAction(tripId: string) {
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
if (!session?.user) {
|
||||||
|
return { error: "Kamu harus login terlebih dahulu" };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await tripService.markParticipantPayment(tripId, session.user.id);
|
||||||
|
revalidatePath(`/trips/${tripId}`);
|
||||||
|
revalidatePath("/trips");
|
||||||
|
revalidatePath("/");
|
||||||
|
revalidatePath("/profile");
|
||||||
|
return { success: true };
|
||||||
|
} catch (err) {
|
||||||
|
return { error: (err as Error).message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function confirmParticipantPaymentAction(
|
||||||
|
tripId: string,
|
||||||
|
participantId: string
|
||||||
|
) {
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
if (!session?.user) {
|
||||||
|
return { error: "Kamu harus login terlebih dahulu" };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await tripService.confirmParticipantPayment(
|
||||||
|
tripId,
|
||||||
|
participantId,
|
||||||
|
session.user.id
|
||||||
|
);
|
||||||
|
revalidatePath(`/trips/${tripId}`);
|
||||||
|
revalidatePath("/trips");
|
||||||
|
revalidatePath("/");
|
||||||
|
revalidatePath("/profile");
|
||||||
|
return { success: true };
|
||||||
|
} catch (err) {
|
||||||
|
return { error: (err as Error).message };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { confirmParticipantPaymentAction } from "@/features/booking/actions";
|
||||||
|
|
||||||
|
export interface PaymentPendingParticipant {
|
||||||
|
id: string;
|
||||||
|
user: { name: string; image: string | null };
|
||||||
|
/** PENDING atau CONFIRMED (join) — keduanya bisa sudah tandai bayar */
|
||||||
|
joinStatus: "PENDING" | "CONFIRMED";
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OrganizerPaymentQueueProps {
|
||||||
|
tripId: string;
|
||||||
|
items: PaymentPendingParticipant[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OrganizerPaymentQueue({
|
||||||
|
tripId,
|
||||||
|
items,
|
||||||
|
}: OrganizerPaymentQueueProps) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [loadingId, setLoadingId] = useState<string | null>(null);
|
||||||
|
const [error, setError] = useState("");
|
||||||
|
|
||||||
|
async function confirm(participantId: string) {
|
||||||
|
setLoadingId(participantId);
|
||||||
|
setError("");
|
||||||
|
const result = await confirmParticipantPaymentAction(tripId, participantId);
|
||||||
|
setLoadingId(null);
|
||||||
|
if (result.error) {
|
||||||
|
setError(result.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
router.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rounded-xl border border-primary-200 bg-primary-50/60 p-4 sm:p-5">
|
||||||
|
<h2 className="text-sm font-bold text-primary-950 sm:text-base">
|
||||||
|
Konfirmasi pembayaran ({items.length})
|
||||||
|
</h2>
|
||||||
|
<p className="mt-1 text-xs text-primary-900/85 sm:text-sm">
|
||||||
|
Peserta sudah menandai pembayaran. Cek rekening atau bukti transfer,
|
||||||
|
lalu konfirmasi.
|
||||||
|
</p>
|
||||||
|
{error && (
|
||||||
|
<p className="mt-3 rounded-lg bg-red-50 px-3 py-2 text-xs font-medium text-red-700 sm:text-sm">
|
||||||
|
{error}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
<ul className="mt-4 space-y-3">
|
||||||
|
{items.map((p) => (
|
||||||
|
<li
|
||||||
|
key={p.id}
|
||||||
|
className="flex flex-col gap-3 rounded-xl border border-primary-100 bg-white/95 p-3 sm:flex-row sm:items-center sm:justify-between"
|
||||||
|
>
|
||||||
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
|
{p.user.image ? (
|
||||||
|
<Image
|
||||||
|
src={p.user.image}
|
||||||
|
alt=""
|
||||||
|
width={40}
|
||||||
|
height={40}
|
||||||
|
className="h-10 w-10 shrink-0 rounded-full object-cover"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-primary-600 text-sm font-bold text-white">
|
||||||
|
{p.user.name.charAt(0).toUpperCase()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="min-w-0">
|
||||||
|
<p className="truncate text-sm font-semibold text-neutral-800">
|
||||||
|
{p.user.name}
|
||||||
|
</p>
|
||||||
|
<p className="text-xs text-primary-800/90">
|
||||||
|
Menunggu konfirmasi pembayaran
|
||||||
|
{p.joinStatus === "PENDING" && (
|
||||||
|
<span className="text-neutral-500">
|
||||||
|
{" "}
|
||||||
|
· belum disetujui ikut trip
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={loadingId !== null}
|
||||||
|
onClick={() => confirm(p.id)}
|
||||||
|
className="shrink-0 rounded-lg bg-primary-600 px-4 py-2 text-xs font-semibold text-white shadow-sm hover:bg-primary-700 disabled:opacity-50 sm:text-sm"
|
||||||
|
>
|
||||||
|
{loadingId === p.id ? "Memproses…" : "Konfirmasi pembayaran"}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { formatDateRange } from "@/lib/utils";
|
import { formatTripCalendarDateRangeLong } from "@/lib/trip-dates";
|
||||||
|
|
||||||
interface ProfileTripRowProps {
|
interface ProfileTripRowProps {
|
||||||
href: string;
|
href: string;
|
||||||
@@ -28,7 +28,7 @@ export function ProfileTripRow({
|
|||||||
<p className="truncate text-sm font-semibold text-neutral-800">{title}</p>
|
<p className="truncate text-sm font-semibold text-neutral-800">{title}</p>
|
||||||
<p className="truncate text-xs text-neutral-500">{mountain}</p>
|
<p className="truncate text-xs text-neutral-500">{mountain}</p>
|
||||||
<p className="mt-0.5 text-[11px] text-neutral-400 sm:text-xs">
|
<p className="mt-0.5 text-[11px] text-neutral-400 sm:text-xs">
|
||||||
{formatDateRange(date, endDate)}
|
{formatTripCalendarDateRangeLong(date, endDate)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{rightSlot && (
|
{rightSlot && (
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ export async function createTripAction(formData: FormData) {
|
|||||||
description: formData.get("description") as string,
|
description: formData.get("description") as string,
|
||||||
mountain: formData.get("mountain") as string,
|
mountain: formData.get("mountain") as string,
|
||||||
location: formData.get("location") as string,
|
location: formData.get("location") as string,
|
||||||
|
meetingPoint: formData.get("meetingPoint") as string,
|
||||||
|
itinerary: formData.get("itinerary") as string,
|
||||||
|
whatsIncluded: formData.get("whatsIncluded") as string,
|
||||||
|
whatsExcluded: formData.get("whatsExcluded") as string,
|
||||||
date: formData.get("date") as string,
|
date: formData.get("date") as string,
|
||||||
endDate: (formData.get("endDate") as string) || undefined,
|
endDate: (formData.get("endDate") as string) || undefined,
|
||||||
maxParticipants: formData.get("maxParticipants") as string,
|
maxParticipants: formData.get("maxParticipants") as string,
|
||||||
@@ -50,8 +54,20 @@ export async function createTripAction(formData: FormData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const {
|
||||||
|
meetingPoint,
|
||||||
|
itinerary,
|
||||||
|
whatsIncluded,
|
||||||
|
whatsExcluded,
|
||||||
|
...tripCore
|
||||||
|
} = result.data;
|
||||||
|
|
||||||
const trip = await tripService.createTrip({
|
const trip = await tripService.createTrip({
|
||||||
...result.data,
|
...tripCore,
|
||||||
|
meetingPoint,
|
||||||
|
itinerary,
|
||||||
|
whatsIncluded,
|
||||||
|
whatsExcluded,
|
||||||
date,
|
date,
|
||||||
endDate,
|
endDate,
|
||||||
organizerId: session.user.id,
|
organizerId: session.user.id,
|
||||||
@@ -101,3 +117,53 @@ export async function cancelJoinAction(tripId: string) {
|
|||||||
return { error: (err as Error).message };
|
return { error: (err as Error).message };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function confirmParticipantAction(
|
||||||
|
tripId: string,
|
||||||
|
participantId: string
|
||||||
|
) {
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
if (!session?.user) {
|
||||||
|
return { error: "Kamu harus login terlebih dahulu" };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await tripService.confirmParticipant(
|
||||||
|
tripId,
|
||||||
|
participantId,
|
||||||
|
session.user.id
|
||||||
|
);
|
||||||
|
revalidatePath(`/trips/${tripId}`);
|
||||||
|
revalidatePath("/trips");
|
||||||
|
revalidatePath("/");
|
||||||
|
revalidatePath("/profile");
|
||||||
|
return { success: true };
|
||||||
|
} catch (err) {
|
||||||
|
return { error: (err as Error).message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function rejectParticipantAction(
|
||||||
|
tripId: string,
|
||||||
|
participantId: string
|
||||||
|
) {
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
if (!session?.user) {
|
||||||
|
return { error: "Kamu harus login terlebih dahulu" };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await tripService.rejectParticipant(
|
||||||
|
tripId,
|
||||||
|
participantId,
|
||||||
|
session.user.id
|
||||||
|
);
|
||||||
|
revalidatePath(`/trips/${tripId}`);
|
||||||
|
revalidatePath("/trips");
|
||||||
|
revalidatePath("/");
|
||||||
|
revalidatePath("/profile");
|
||||||
|
return { success: true };
|
||||||
|
} catch (err) {
|
||||||
|
return { error: (err as Error).message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,15 +4,23 @@ import { useState } from "react";
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { joinTripAction, cancelJoinAction } from "@/features/trip/actions";
|
import { joinTripAction, cancelJoinAction } from "@/features/trip/actions";
|
||||||
|
import { markParticipantPaidAction } from "@/features/booking/actions";
|
||||||
|
|
||||||
interface JoinTripButtonProps {
|
interface JoinTripButtonProps {
|
||||||
tripId: string;
|
tripId: string;
|
||||||
isLoggedIn: boolean;
|
isLoggedIn: boolean;
|
||||||
isOrganizer: boolean;
|
isOrganizer: boolean;
|
||||||
isJoined: boolean;
|
isJoined: boolean;
|
||||||
|
/** Status partisipasi user saat isJoined (bukan organizer) */
|
||||||
|
participationStatus?: "PENDING" | "CONFIRMED" | null;
|
||||||
|
/** Status pembayaran manual (peserta) */
|
||||||
|
participantPayment?: {
|
||||||
|
markedPaidAt: string | Date | null;
|
||||||
|
paymentConfirmedAt: string | Date | null;
|
||||||
|
} | null;
|
||||||
isFull: boolean;
|
isFull: boolean;
|
||||||
tripStatus: string;
|
tripStatus: string;
|
||||||
/** Tanggal berangkat sudah lewat (hari kalender UTC) */
|
/** Tanggal berangkat trip sudah lewat */
|
||||||
isDeparturePast?: boolean;
|
isDeparturePast?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,6 +29,8 @@ export function JoinTripButton({
|
|||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
isOrganizer,
|
isOrganizer,
|
||||||
isJoined,
|
isJoined,
|
||||||
|
participationStatus,
|
||||||
|
participantPayment,
|
||||||
isFull,
|
isFull,
|
||||||
tripStatus,
|
tripStatus,
|
||||||
isDeparturePast,
|
isDeparturePast,
|
||||||
@@ -98,6 +108,29 @@ export function JoinTripButton({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleMarkPaid() {
|
||||||
|
setLoading(true);
|
||||||
|
setError("");
|
||||||
|
const result = await markParticipantPaidAction(tripId);
|
||||||
|
setLoading(false);
|
||||||
|
if (result.error) {
|
||||||
|
setError(result.error);
|
||||||
|
} else {
|
||||||
|
router.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pay = participantPayment;
|
||||||
|
const showMarkPaid =
|
||||||
|
isJoined &&
|
||||||
|
pay &&
|
||||||
|
!pay.paymentConfirmedAt &&
|
||||||
|
!pay.markedPaidAt &&
|
||||||
|
!isDeparturePast;
|
||||||
|
const waitingPaymentConfirm =
|
||||||
|
isJoined && pay && pay.markedPaidAt && !pay.paymentConfirmedAt;
|
||||||
|
const paymentDone = isJoined && pay && pay.paymentConfirmedAt;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{error && (
|
{error && (
|
||||||
@@ -105,6 +138,42 @@ export function JoinTripButton({
|
|||||||
{error}
|
{error}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{isJoined && participationStatus === "PENDING" && (
|
||||||
|
<div className="mb-3 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm font-medium leading-relaxed text-amber-900">
|
||||||
|
Permintaan ikut trip kamu{" "}
|
||||||
|
<span className="font-semibold">menunggu persetujuan organizer</span>.
|
||||||
|
Kamu bisa membatalkan kapan saja sebelum disetujui.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isJoined && participationStatus === "CONFIRMED" && (
|
||||||
|
<div className="mb-3 rounded-xl border border-secondary-200 bg-secondary-50 px-4 py-3 text-sm font-medium text-secondary-900">
|
||||||
|
Kamu sudah{" "}
|
||||||
|
<span className="font-semibold">terkonfirmasi</span> sebagai peserta
|
||||||
|
trip ini.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{waitingPaymentConfirm && (
|
||||||
|
<div className="mb-3 rounded-xl border border-primary-200 bg-primary-50 px-4 py-3 text-sm font-medium leading-relaxed text-primary-950">
|
||||||
|
Kamu sudah menandai <span className="font-semibold">sudah bayar</span>.
|
||||||
|
Tunggu organizer mengonfirmasi pembayaran.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{paymentDone && (
|
||||||
|
<div className="mb-3 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm font-medium text-emerald-900">
|
||||||
|
Pembayaran kamu sudah{" "}
|
||||||
|
<span className="font-semibold">dikonfirmasi organizer</span>.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showMarkPaid && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleMarkPaid}
|
||||||
|
disabled={loading}
|
||||||
|
className="mb-3 w-full rounded-xl border-2 border-primary-500 bg-white py-3 text-sm font-bold text-primary-700 transition-colors hover:bg-primary-50 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{loading ? "Memproses..." : "Saya sudah bayar"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
{isJoined ? (
|
{isJoined ? (
|
||||||
<button
|
<button
|
||||||
onClick={handleCancel}
|
onClick={handleCancel}
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import Image from "next/image";
|
||||||
|
import {
|
||||||
|
confirmParticipantAction,
|
||||||
|
rejectParticipantAction,
|
||||||
|
} from "@/features/trip/actions";
|
||||||
|
|
||||||
|
export interface PendingJoinRequest {
|
||||||
|
id: string;
|
||||||
|
user: { name: string; image: string | null };
|
||||||
|
/** Peserta sudah menekan "Saya sudah bayar" */
|
||||||
|
markedPaidAt?: string | Date | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OrganizerJoinRequestsProps {
|
||||||
|
tripId: string;
|
||||||
|
pending: PendingJoinRequest[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OrganizerJoinRequests({
|
||||||
|
tripId,
|
||||||
|
pending,
|
||||||
|
}: OrganizerJoinRequestsProps) {
|
||||||
|
const router = useRouter();
|
||||||
|
const [loadingId, setLoadingId] = useState<string | null>(null);
|
||||||
|
const [error, setError] = useState("");
|
||||||
|
|
||||||
|
async function run(
|
||||||
|
participantId: string,
|
||||||
|
action: "confirm" | "reject"
|
||||||
|
) {
|
||||||
|
setLoadingId(participantId);
|
||||||
|
setError("");
|
||||||
|
const result =
|
||||||
|
action === "confirm"
|
||||||
|
? await confirmParticipantAction(tripId, participantId)
|
||||||
|
: await rejectParticipantAction(tripId, participantId);
|
||||||
|
setLoadingId(null);
|
||||||
|
if (result.error) {
|
||||||
|
setError(result.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
router.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rounded-xl border border-amber-200 bg-amber-50/70 p-4 sm:p-5">
|
||||||
|
<h2 className="text-sm font-bold text-amber-950 sm:text-base">
|
||||||
|
Permintaan join ({pending.length})
|
||||||
|
</h2>
|
||||||
|
<p className="mt-1 text-xs text-amber-900/80 sm:text-sm">
|
||||||
|
Setujui atau tolak siapa yang boleh ikut trip ini.
|
||||||
|
</p>
|
||||||
|
{error && (
|
||||||
|
<p className="mt-3 rounded-lg bg-red-50 px-3 py-2 text-xs font-medium text-red-700 sm:text-sm">
|
||||||
|
{error}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
<ul className="mt-4 space-y-3">
|
||||||
|
{pending.map((p) => (
|
||||||
|
<li
|
||||||
|
key={p.id}
|
||||||
|
className="flex flex-col gap-3 rounded-xl border border-amber-100 bg-white/90 p-3 sm:flex-row sm:items-center sm:justify-between"
|
||||||
|
>
|
||||||
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
|
{p.user.image ? (
|
||||||
|
<Image
|
||||||
|
src={p.user.image}
|
||||||
|
alt=""
|
||||||
|
width={40}
|
||||||
|
height={40}
|
||||||
|
className="h-10 w-10 shrink-0 rounded-full object-cover"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-primary-600 text-sm font-bold text-white">
|
||||||
|
{p.user.name.charAt(0).toUpperCase()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="min-w-0">
|
||||||
|
<p className="truncate text-sm font-semibold text-neutral-800">
|
||||||
|
{p.user.name}
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-wrap items-center gap-1.5">
|
||||||
|
<p className="text-xs text-amber-800/80">Menunggu persetujuan</p>
|
||||||
|
{p.markedPaidAt ? (
|
||||||
|
<span className="rounded-full bg-primary-100 px-2 py-0.5 text-[10px] font-bold text-primary-800">
|
||||||
|
Sudah tandai bayar
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex shrink-0 gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={loadingId !== null}
|
||||||
|
onClick={() => run(p.id, "reject")}
|
||||||
|
className="rounded-lg border border-neutral-200 bg-white px-3 py-2 text-xs font-semibold text-neutral-600 hover:bg-neutral-50 disabled:opacity-50 sm:text-sm"
|
||||||
|
>
|
||||||
|
{loadingId === p.id ? "…" : "Tolak"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={loadingId !== null}
|
||||||
|
onClick={() => run(p.id, "confirm")}
|
||||||
|
className="rounded-lg bg-primary-600 px-3 py-2 text-xs font-semibold text-white shadow-sm hover:bg-primary-700 disabled:opacity-50 sm:text-sm"
|
||||||
|
>
|
||||||
|
{loadingId === p.id ? "Memproses…" : "Setujui"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import type { OrganizerTrust } from "@/server/services/trust.service";
|
||||||
|
|
||||||
|
interface OrganizerTrustPanelProps {
|
||||||
|
name: string;
|
||||||
|
image: string | null;
|
||||||
|
trust: OrganizerTrust;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OrganizerTrustPanel({
|
||||||
|
name,
|
||||||
|
image,
|
||||||
|
trust,
|
||||||
|
}: OrganizerTrustPanelProps) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-xl border border-neutral-200 bg-linear-to-br from-white to-neutral-50 p-4 sm:p-5">
|
||||||
|
<h2 className="mb-3 text-xs font-bold text-neutral-700 sm:text-sm">
|
||||||
|
Organizer & kepercayaan
|
||||||
|
</h2>
|
||||||
|
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:gap-4">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
{image ? (
|
||||||
|
<Image
|
||||||
|
src={image}
|
||||||
|
alt=""
|
||||||
|
width={48}
|
||||||
|
height={48}
|
||||||
|
className="h-12 w-12 shrink-0 rounded-full object-cover ring-2 ring-white shadow"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-primary-600 text-lg font-bold text-white shadow">
|
||||||
|
{name.charAt(0).toUpperCase()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="min-w-0">
|
||||||
|
<p className="truncate text-sm font-bold text-neutral-900 sm:text-base">
|
||||||
|
{name}
|
||||||
|
</p>
|
||||||
|
<div className="mt-1.5 flex flex-wrap gap-1.5">
|
||||||
|
{trust.isVerified && (
|
||||||
|
<span className="inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-blue-800 sm:text-xs">
|
||||||
|
Verified
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{trust.isTripLeader && (
|
||||||
|
<span className="inline-flex items-center rounded-full bg-secondary-100 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-secondary-900 sm:text-xs">
|
||||||
|
Trip leader
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-1 flex-wrap gap-3 border-t border-neutral-100 pt-3 sm:border-t-0 sm:border-l sm:pl-4 sm:pt-0">
|
||||||
|
<div className="min-w-[100px] rounded-lg bg-white/80 px-3 py-2 shadow-sm ring-1 ring-neutral-100">
|
||||||
|
<p className="text-[10px] font-medium text-neutral-500 sm:text-xs">
|
||||||
|
Trip dibuat
|
||||||
|
</p>
|
||||||
|
<p className="text-lg font-bold text-neutral-800">
|
||||||
|
{trust.tripsCreated}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="min-w-[100px] rounded-lg bg-white/80 px-3 py-2 shadow-sm ring-1 ring-neutral-100">
|
||||||
|
<p className="text-[10px] font-medium text-neutral-500 sm:text-xs">
|
||||||
|
Rating organizer
|
||||||
|
</p>
|
||||||
|
<p className="text-lg font-bold text-amber-700">
|
||||||
|
{trust.avgRating != null ? `${trust.avgRating} ★` : "—"}
|
||||||
|
</p>
|
||||||
|
{trust.reviewCount > 0 && (
|
||||||
|
<p className="text-[10px] text-neutral-400">
|
||||||
|
dari {trust.reviewCount} ulasan trip
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { formatRupiah, formatDateRange } from "@/lib/utils";
|
import { formatRupiah } from "@/lib/utils";
|
||||||
|
import { formatTripCalendarDateRangeLong } from "@/lib/trip-dates";
|
||||||
|
|
||||||
interface TripCardProps {
|
interface TripCardProps {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -80,7 +81,7 @@ export function TripCard({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="text-xs text-secondary-500">📅</span>{" "}
|
<span className="text-xs text-secondary-500">📅</span>{" "}
|
||||||
{formatDateRange(date, endDate)}
|
{formatTripCalendarDateRangeLong(date, endDate)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<span className="text-xs text-secondary-500">👤</span>{" "}
|
<span className="text-xs text-secondary-500">👤</span>{" "}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useRouter, useSearchParams } from "next/navigation";
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import DatePicker from "react-datepicker";
|
import DatePicker from "react-datepicker";
|
||||||
import "react-datepicker/dist/react-datepicker.css";
|
import "react-datepicker/dist/react-datepicker.css";
|
||||||
|
import { formatLocalCalendarYmd } from "@/lib/trip-dates";
|
||||||
|
|
||||||
export function TripFilter() {
|
export function TripFilter() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -35,8 +36,8 @@ export function TripFilter() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
if (query.trim()) params.set("q", query.trim());
|
if (query.trim()) params.set("q", query.trim());
|
||||||
if (startDate) params.set("from", startDate.toISOString().split("T")[0]);
|
if (startDate) params.set("from", formatLocalCalendarYmd(startDate));
|
||||||
if (endDate) params.set("to", endDate.toISOString().split("T")[0]);
|
if (endDate) params.set("to", formatLocalCalendarYmd(endDate));
|
||||||
|
|
||||||
const qs = params.toString();
|
const qs = params.toString();
|
||||||
router.push(`/trips${qs ? `?${qs}` : ""}`);
|
router.push(`/trips${qs ? `?${qs}` : ""}`);
|
||||||
@@ -90,12 +91,8 @@ export function TripFilter() {
|
|||||||
{/* Date range */}
|
{/* Date range */}
|
||||||
<div className="sm:w-64">
|
<div className="sm:w-64">
|
||||||
<label className="mb-1.5 block text-xs font-medium text-neutral-500">
|
<label className="mb-1.5 block text-xs font-medium text-neutral-500">
|
||||||
Rentang tanggal (UTC)
|
Tanggal
|
||||||
</label>
|
</label>
|
||||||
<p className="mb-1 text-[10px] leading-snug text-neutral-400 sm:text-xs">
|
|
||||||
Menampilkan trip yang jadwalnya overlap rentang ini: multi hari pakai
|
|
||||||
tanggal pulang; satu hari pakai tanggal berangkat saja.
|
|
||||||
</p>
|
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<span className="absolute left-3 top-1/2 z-10 -translate-y-1/2 text-neutral-400">
|
<span className="absolute left-3 top-1/2 z-10 -translate-y-1/2 text-neutral-400">
|
||||||
<svg
|
<svg
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
interface TripProgramBlockProps {
|
||||||
|
meetingPoint: string | null;
|
||||||
|
itinerary: string | null;
|
||||||
|
whatsIncluded: string | null;
|
||||||
|
whatsExcluded: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TripProgramBlock({
|
||||||
|
meetingPoint,
|
||||||
|
itinerary,
|
||||||
|
whatsIncluded,
|
||||||
|
whatsExcluded,
|
||||||
|
}: TripProgramBlockProps) {
|
||||||
|
const hasAny =
|
||||||
|
meetingPoint || itinerary || whatsIncluded || whatsExcluded;
|
||||||
|
if (!hasAny) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 rounded-xl border border-neutral-200 bg-neutral-50/50 p-4 sm:p-5">
|
||||||
|
<h2 className="text-xs font-bold text-neutral-800 sm:text-sm">
|
||||||
|
Detail perjalanan
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{meetingPoint && (
|
||||||
|
<div>
|
||||||
|
<h3 className="mb-1 text-[11px] font-bold uppercase tracking-wide text-primary-700 sm:text-xs">
|
||||||
|
Meeting point
|
||||||
|
</h3>
|
||||||
|
<p className="whitespace-pre-wrap text-xs leading-relaxed text-neutral-700 sm:text-sm">
|
||||||
|
{meetingPoint}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{itinerary && (
|
||||||
|
<div>
|
||||||
|
<h3 className="mb-1 text-[11px] font-bold uppercase tracking-wide text-primary-700 sm:text-xs">
|
||||||
|
Itinerary
|
||||||
|
</h3>
|
||||||
|
<p className="whitespace-pre-wrap text-xs leading-relaxed text-neutral-700 sm:text-sm">
|
||||||
|
{itinerary}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{(whatsIncluded || whatsExcluded) && (
|
||||||
|
<div className="grid gap-4 sm:grid-cols-2">
|
||||||
|
{whatsIncluded && (
|
||||||
|
<div className="rounded-lg border border-secondary-200 bg-white p-3">
|
||||||
|
<h3 className="mb-2 text-[11px] font-bold uppercase tracking-wide text-secondary-800 sm:text-xs">
|
||||||
|
Termasuk
|
||||||
|
</h3>
|
||||||
|
<p className="whitespace-pre-wrap text-xs leading-relaxed text-neutral-700 sm:text-sm">
|
||||||
|
{whatsIncluded}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{whatsExcluded && (
|
||||||
|
<div className="rounded-lg border border-neutral-200 bg-white p-3">
|
||||||
|
<h3 className="mb-2 text-[11px] font-bold uppercase tracking-wide text-neutral-600 sm:text-xs">
|
||||||
|
Tidak termasuk
|
||||||
|
</h3>
|
||||||
|
<p className="whitespace-pre-wrap text-xs leading-relaxed text-neutral-700 sm:text-sm">
|
||||||
|
{whatsExcluded}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -84,6 +84,62 @@ export const createTripSchema = z
|
|||||||
LIMITS.MAX_PRICE_IDR,
|
LIMITS.MAX_PRICE_IDR,
|
||||||
`Harga maksimal Rp ${LIMITS.MAX_PRICE_IDR.toLocaleString("id-ID")}`
|
`Harga maksimal Rp ${LIMITS.MAX_PRICE_IDR.toLocaleString("id-ID")}`
|
||||||
),
|
),
|
||||||
|
meetingPoint: z.preprocess(
|
||||||
|
(val) => {
|
||||||
|
if (val == null) return undefined;
|
||||||
|
const s = String(val).trim();
|
||||||
|
return s === "" ? undefined : s;
|
||||||
|
},
|
||||||
|
z
|
||||||
|
.string()
|
||||||
|
.max(
|
||||||
|
LIMITS.MAX_MEETING_POINT_LENGTH,
|
||||||
|
`Meeting point maksimal ${LIMITS.MAX_MEETING_POINT_LENGTH} karakter`
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
),
|
||||||
|
itinerary: z.preprocess(
|
||||||
|
(val) => {
|
||||||
|
if (val == null) return undefined;
|
||||||
|
const s = String(val).trim();
|
||||||
|
return s === "" ? undefined : s;
|
||||||
|
},
|
||||||
|
z
|
||||||
|
.string()
|
||||||
|
.max(
|
||||||
|
LIMITS.MAX_TRIP_ITINERARY_LENGTH,
|
||||||
|
`Itinerary maksimal ${LIMITS.MAX_TRIP_ITINERARY_LENGTH} karakter`
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
),
|
||||||
|
whatsIncluded: z.preprocess(
|
||||||
|
(val) => {
|
||||||
|
if (val == null) return undefined;
|
||||||
|
const s = String(val).trim();
|
||||||
|
return s === "" ? undefined : s;
|
||||||
|
},
|
||||||
|
z
|
||||||
|
.string()
|
||||||
|
.max(
|
||||||
|
LIMITS.MAX_TRIP_BULLET_SECTION_LENGTH,
|
||||||
|
`Bagian 'Termasuk' maksimal ${LIMITS.MAX_TRIP_BULLET_SECTION_LENGTH} karakter`
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
),
|
||||||
|
whatsExcluded: z.preprocess(
|
||||||
|
(val) => {
|
||||||
|
if (val == null) return undefined;
|
||||||
|
const s = String(val).trim();
|
||||||
|
return s === "" ? undefined : s;
|
||||||
|
},
|
||||||
|
z
|
||||||
|
.string()
|
||||||
|
.max(
|
||||||
|
LIMITS.MAX_TRIP_BULLET_SECTION_LENGTH,
|
||||||
|
`Bagian 'Tidak termasuk' maksimal ${LIMITS.MAX_TRIP_BULLET_SECTION_LENGTH} karakter`
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
),
|
||||||
})
|
})
|
||||||
.superRefine((data, ctx) => {
|
.superRefine((data, ctx) => {
|
||||||
const dep = tripStoredInstantFromYmd(data.date);
|
const dep = tripStoredInstantFromYmd(data.date);
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ export const LIMITS = {
|
|||||||
MAX_MOUNTAIN_LENGTH: 100,
|
MAX_MOUNTAIN_LENGTH: 100,
|
||||||
MAX_LOCATION_LENGTH: 120,
|
MAX_LOCATION_LENGTH: 120,
|
||||||
MAX_DESCRIPTION_LENGTH: 5000,
|
MAX_DESCRIPTION_LENGTH: 5000,
|
||||||
|
/** Meeting point & tiap blok include/exclude */
|
||||||
|
MAX_MEETING_POINT_LENGTH: 500,
|
||||||
|
MAX_TRIP_ITINERARY_LENGTH: 8000,
|
||||||
|
MAX_TRIP_BULLET_SECTION_LENGTH: 4000,
|
||||||
MAX_REVIEW_COMMENT: 500,
|
MAX_REVIEW_COMMENT: 500,
|
||||||
MAX_IMAGE_URLS: 5,
|
MAX_IMAGE_URLS: 5,
|
||||||
MAX_URL_LENGTH: 2048,
|
MAX_URL_LENGTH: 2048,
|
||||||
|
|||||||
@@ -81,3 +81,30 @@ export function isPastTripLastDayForReview(
|
|||||||
);
|
);
|
||||||
return Date.now() > endMs;
|
return Date.now() > endMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tampilkan tanggal trip untuk UI: pakai **kalender UTC** (sama dengan
|
||||||
|
* `tripStoredInstantFromYmd` & filter Open Trip), supaya tidak bergeser
|
||||||
|
* karena timezone runtime (server vs browser).
|
||||||
|
*/
|
||||||
|
export function formatTripCalendarDateLong(
|
||||||
|
d: Date | string,
|
||||||
|
locale = "id-ID"
|
||||||
|
): string {
|
||||||
|
const date = typeof d === "string" ? new Date(d) : d;
|
||||||
|
return new Intl.DateTimeFormat(locale, {
|
||||||
|
dateStyle: "long",
|
||||||
|
timeZone: "UTC",
|
||||||
|
}).format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatTripCalendarDateRangeLong(
|
||||||
|
start: Date | string,
|
||||||
|
end?: Date | string | null,
|
||||||
|
locale = "id-ID"
|
||||||
|
): string {
|
||||||
|
const startStr = formatTripCalendarDateLong(start, locale);
|
||||||
|
if (!end) return startStr;
|
||||||
|
const endStr = formatTripCalendarDateLong(end, locale);
|
||||||
|
return `${startStr} — ${endStr}`;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
/** Minimal trip sebagai organizer untuk badge "Trip leader" (heuristik MVP). */
|
||||||
|
export const TRIP_LEADER_MIN_TRIPS = 2;
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Trip" ADD COLUMN "itinerary" TEXT,
|
||||||
|
ADD COLUMN "meetingPoint" TEXT,
|
||||||
|
ADD COLUMN "whatsExcluded" TEXT,
|
||||||
|
ADD COLUMN "whatsIncluded" TEXT;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "TripParticipant" ADD COLUMN "markedPaidAt" TIMESTAMP(3),
|
||||||
|
ADD COLUMN "paymentConfirmedAt" TIMESTAMP(3);
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ADD COLUMN "isVerified" BOOLEAN NOT NULL DEFAULT false;
|
||||||
@@ -13,6 +13,8 @@ model User {
|
|||||||
email String @unique
|
email String @unique
|
||||||
password String
|
password String
|
||||||
image String?
|
image String?
|
||||||
|
/// Akun diverifikasi tim SeTrip (manual / admin) — tampil sebagai badge kepercayaan
|
||||||
|
isVerified Boolean @default(false)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
@@ -27,6 +29,14 @@ model Trip {
|
|||||||
description String?
|
description String?
|
||||||
mountain String
|
mountain String
|
||||||
location String
|
location String
|
||||||
|
/// Titik kumpul / meeting point (teks bebas)
|
||||||
|
meetingPoint String?
|
||||||
|
/// Itinerary hari per hari (teks bebas, bullet OK)
|
||||||
|
itinerary String?
|
||||||
|
/// Yang termasuk harga (teks bebas)
|
||||||
|
whatsIncluded String?
|
||||||
|
/// Yang tidak termasuk (teks bebas)
|
||||||
|
whatsExcluded String?
|
||||||
date DateTime
|
date DateTime
|
||||||
endDate DateTime?
|
endDate DateTime?
|
||||||
maxParticipants Int
|
maxParticipants Int
|
||||||
@@ -73,6 +83,10 @@ model TripParticipant {
|
|||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
status ParticipantStatus @default(PENDING)
|
status ParticipantStatus @default(PENDING)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
|
/// Peserta menekan "Saya sudah bayar" (pembayaran manual)
|
||||||
|
markedPaidAt DateTime?
|
||||||
|
/// Organizer mengonfirmasi uang sudah masuk
|
||||||
|
paymentConfirmedAt DateTime?
|
||||||
|
|
||||||
tripId String
|
tripId String
|
||||||
trip Trip @relation(fields: [tripId], references: [id])
|
trip Trip @relation(fields: [tripId], references: [id])
|
||||||
|
|||||||
+22
-6
@@ -28,6 +28,7 @@ async function main() {
|
|||||||
name: "Dede Inoen",
|
name: "Dede Inoen",
|
||||||
email: "dede.inoen@setrip.id",
|
email: "dede.inoen@setrip.id",
|
||||||
password,
|
password,
|
||||||
|
isVerified: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ async function main() {
|
|||||||
name: "Panji Petualang",
|
name: "Panji Petualang",
|
||||||
email: "panji@setrip.id",
|
email: "panji@setrip.id",
|
||||||
password,
|
password,
|
||||||
|
isVerified: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -111,13 +113,27 @@ async function main() {
|
|||||||
title: "Open Trip Papandayan Weekend",
|
title: "Open Trip Papandayan Weekend",
|
||||||
description: `Pendakian santai ke Gunung Papandayan, cocok untuk pemula!
|
description: `Pendakian santai ke Gunung Papandayan, cocok untuk pemula!
|
||||||
|
|
||||||
📍 Meeting Point: Alun-alun Garut, 05:00 WIB
|
⚠️ Bawa: Sleeping bag, jaket, headlamp, air 2L`,
|
||||||
🎒 Fasilitas: Transport PP, guide, tenda, makan 3x
|
meetingPoint:
|
||||||
⚠️ Bawa: Sleeping bag, jaket, headlamp, air 2L
|
"Alun-alun Garut (depan pendopo), Sabtu 05:00 WIB — detail grup WA.",
|
||||||
|
itinerary: `Sabtu
|
||||||
|
• 05:00 Meeting & briefing
|
||||||
|
• 07:00 Berangkat menuju basecamp
|
||||||
|
• 12:00 Makan siang trail
|
||||||
|
• 15:00 Camp area Pondok Salada
|
||||||
|
|
||||||
Itinerary:
|
Minggu
|
||||||
- Sabtu: Berangkat → Basecamp → Summit → Camp
|
• 04:00 Summit attack
|
||||||
- Minggu: Sunrise → Turun → Pulang`,
|
• 08:00 Sarap & packing
|
||||||
|
• 11:00 Turun
|
||||||
|
• 16:00 Estimasi kembali ke Garut`,
|
||||||
|
whatsIncluded: `• Transport PP Garut–basecamp
|
||||||
|
• Guide lokal
|
||||||
|
• Tenda tim (kapasitas sesuai muatan)
|
||||||
|
• Konsumsi: makan 3x + snack`,
|
||||||
|
whatsExcluded: `• Tiket masuk TNGGP
|
||||||
|
• Sleeping bag & matras pribadi
|
||||||
|
• Asuransi perjalanan`,
|
||||||
mountain: "Gunung Papandayan",
|
mountain: "Gunung Papandayan",
|
||||||
location: "Garut, Jawa Barat",
|
location: "Garut, Jawa Barat",
|
||||||
date: utc(2026, 3, 23, 8, 0),
|
date: utc(2026, 3, 23, 8, 0),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { prisma } from "@/lib/prisma";
|
import { prisma } from "@/lib/prisma";
|
||||||
|
import type { ParticipantStatus } from "@/app/generated/prisma/client";
|
||||||
|
|
||||||
export const participantRepo = {
|
export const participantRepo = {
|
||||||
async findByTripAndUser(tripId: string, userId: string) {
|
async findByTripAndUser(tripId: string, userId: string) {
|
||||||
@@ -7,9 +8,31 @@ export const participantRepo = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async findById(id: string) {
|
||||||
|
return prisma.tripParticipant.findUnique({ where: { id } });
|
||||||
|
},
|
||||||
|
|
||||||
async create(tripId: string, userId: string) {
|
async create(tripId: string, userId: string) {
|
||||||
return prisma.tripParticipant.create({
|
return prisma.tripParticipant.create({
|
||||||
data: { tripId, userId, status: "CONFIRMED" },
|
data: { tripId, userId, status: "PENDING" },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async setStatus(id: string, status: ParticipantStatus) {
|
||||||
|
return prisma.tripParticipant.update({
|
||||||
|
where: { id },
|
||||||
|
data: { status },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async setStatusAndClearPayment(id: string, status: ParticipantStatus) {
|
||||||
|
return prisma.tripParticipant.update({
|
||||||
|
where: { id },
|
||||||
|
data: {
|
||||||
|
status,
|
||||||
|
markedPaidAt: null,
|
||||||
|
paymentConfirmedAt: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -22,14 +45,65 @@ export const participantRepo = {
|
|||||||
async cancel(tripId: string, userId: string) {
|
async cancel(tripId: string, userId: string) {
|
||||||
return prisma.tripParticipant.update({
|
return prisma.tripParticipant.update({
|
||||||
where: { tripId_userId: { tripId, userId } },
|
where: { tripId_userId: { tripId, userId } },
|
||||||
data: { status: "CANCELLED" },
|
data: {
|
||||||
|
status: "CANCELLED",
|
||||||
|
markedPaidAt: null,
|
||||||
|
paymentConfirmedAt: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async reactivate(tripId: string, userId: string) {
|
async reactivate(tripId: string, userId: string) {
|
||||||
return prisma.tripParticipant.update({
|
return prisma.tripParticipant.update({
|
||||||
where: { tripId_userId: { tripId, userId } },
|
where: { tripId_userId: { tripId, userId } },
|
||||||
data: { status: "CONFIRMED" },
|
data: {
|
||||||
|
status: "PENDING",
|
||||||
|
markedPaidAt: null,
|
||||||
|
paymentConfirmedAt: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async markPaidByUser(tripId: string, userId: string) {
|
||||||
|
return prisma.tripParticipant.update({
|
||||||
|
where: { tripId_userId: { tripId, userId } },
|
||||||
|
data: { markedPaidAt: new Date() },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Satu baris update atomik — aman dari double-submit / race saat tandai bayar.
|
||||||
|
*/
|
||||||
|
async tryMarkPaidByUser(tripId: string, userId: string) {
|
||||||
|
return prisma.tripParticipant.updateMany({
|
||||||
|
where: {
|
||||||
|
tripId,
|
||||||
|
userId,
|
||||||
|
status: { not: "CANCELLED" },
|
||||||
|
markedPaidAt: null,
|
||||||
|
paymentConfirmedAt: null,
|
||||||
|
},
|
||||||
|
data: { markedPaidAt: new Date() },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async confirmPaymentByOrganizer(participantId: string) {
|
||||||
|
return prisma.tripParticipant.update({
|
||||||
|
where: { id: participantId },
|
||||||
|
data: { paymentConfirmedAt: new Date() },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Konfirmasi pembayaran hanya jika masih eligible — idempotent terhadap double klik. */
|
||||||
|
async tryConfirmPaymentByOrganizer(participantId: string) {
|
||||||
|
return prisma.tripParticipant.updateMany({
|
||||||
|
where: {
|
||||||
|
id: participantId,
|
||||||
|
markedPaidAt: { not: null },
|
||||||
|
paymentConfirmedAt: null,
|
||||||
|
status: { not: "CANCELLED" },
|
||||||
|
},
|
||||||
|
data: { paymentConfirmedAt: new Date() },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,15 @@ export const tripRepo = {
|
|||||||
return prisma.trip.findUnique({
|
return prisma.trip.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
include: {
|
include: {
|
||||||
organizer: { select: { id: true, name: true, email: true, image: true } },
|
organizer: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
email: true,
|
||||||
|
image: true,
|
||||||
|
isVerified: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
images: { orderBy: { order: "asc" } },
|
images: { orderBy: { order: "asc" } },
|
||||||
participants: {
|
participants: {
|
||||||
include: { user: { select: { id: true, name: true, image: true } } },
|
include: { user: { select: { id: true, name: true, image: true } } },
|
||||||
|
|||||||
+262
-23
@@ -1,13 +1,30 @@
|
|||||||
|
import { Prisma } from "@/app/generated/prisma/client";
|
||||||
|
import { prisma } from "@/lib/prisma";
|
||||||
import { tripRepo } from "@/server/repositories/trip.repo";
|
import { tripRepo } from "@/server/repositories/trip.repo";
|
||||||
import { participantRepo } from "@/server/repositories/participant.repo";
|
import { participantRepo } from "@/server/repositories/participant.repo";
|
||||||
import { LIMITS } from "@/lib/limits";
|
import { LIMITS } from "@/lib/limits";
|
||||||
import { utcStartOfDay, isTripDepartureDayPast } from "@/lib/trip-dates";
|
import { utcStartOfDay, isTripDepartureDayPast } from "@/lib/trip-dates";
|
||||||
|
|
||||||
|
const SERIAL_TX_ATTEMPTS = 6;
|
||||||
|
|
||||||
|
function isSerializationConflict(err: unknown): boolean {
|
||||||
|
return (
|
||||||
|
typeof err === "object" &&
|
||||||
|
err !== null &&
|
||||||
|
"code" in err &&
|
||||||
|
(err as { code: string }).code === "P2034"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
interface CreateTripInput {
|
interface CreateTripInput {
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
mountain: string;
|
mountain: string;
|
||||||
location: string;
|
location: string;
|
||||||
|
meetingPoint?: string;
|
||||||
|
itinerary?: string;
|
||||||
|
whatsIncluded?: string;
|
||||||
|
whatsExcluded?: string;
|
||||||
date: Date;
|
date: Date;
|
||||||
endDate?: Date;
|
endDate?: Date;
|
||||||
maxParticipants: number;
|
maxParticipants: number;
|
||||||
@@ -34,17 +51,6 @@ export const tripService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async createTrip(input: CreateTripInput) {
|
async createTrip(input: CreateTripInput) {
|
||||||
const since = utcStartOfDay(new Date());
|
|
||||||
const todayCount = await tripRepo.countByOrganizerSince(
|
|
||||||
input.organizerId,
|
|
||||||
since
|
|
||||||
);
|
|
||||||
if (todayCount >= LIMITS.MAX_TRIPS_PER_ORGANIZER_PER_DAY) {
|
|
||||||
throw new Error(
|
|
||||||
`Batas harian: maksimal ${LIMITS.MAX_TRIPS_PER_ORGANIZER_PER_DAY} trip per hari (UTC). Coba lagi besok.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTripDepartureDayPast(input.date)) {
|
if (isTripDepartureDayPast(input.date)) {
|
||||||
throw new Error("Tanggal berangkat tidak boleh di masa lalu");
|
throw new Error("Tanggal berangkat tidak boleh di masa lalu");
|
||||||
}
|
}
|
||||||
@@ -53,69 +59,157 @@ export const tripService = {
|
|||||||
throw new Error("Tanggal pulang tidak boleh sebelum tanggal berangkat");
|
throw new Error("Tanggal pulang tidak boleh sebelum tanggal berangkat");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const since = utcStartOfDay(new Date());
|
||||||
const images = input.imageUrls?.length
|
const images = input.imageUrls?.length
|
||||||
? {
|
? {
|
||||||
create: input.imageUrls.map((url, i) => ({ url, order: i })),
|
create: input.imageUrls.map((url, i) => ({ url, order: i })),
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
return tripRepo.create({
|
const tripData = {
|
||||||
title: input.title,
|
title: input.title,
|
||||||
description: input.description,
|
description: input.description,
|
||||||
mountain: input.mountain,
|
mountain: input.mountain,
|
||||||
location: input.location,
|
location: input.location,
|
||||||
|
meetingPoint: input.meetingPoint,
|
||||||
|
itinerary: input.itinerary,
|
||||||
|
whatsIncluded: input.whatsIncluded,
|
||||||
|
whatsExcluded: input.whatsExcluded,
|
||||||
date: input.date,
|
date: input.date,
|
||||||
endDate: input.endDate,
|
endDate: input.endDate,
|
||||||
maxParticipants: input.maxParticipants,
|
maxParticipants: input.maxParticipants,
|
||||||
price: input.price,
|
price: input.price,
|
||||||
organizer: { connect: { id: input.organizerId } },
|
organizer: { connect: { id: input.organizerId } },
|
||||||
images,
|
images,
|
||||||
|
} satisfies Prisma.TripCreateInput;
|
||||||
|
|
||||||
|
let lastErr: unknown;
|
||||||
|
for (let attempt = 0; attempt < SERIAL_TX_ATTEMPTS; attempt++) {
|
||||||
|
try {
|
||||||
|
return await prisma.$transaction(
|
||||||
|
async (tx) => {
|
||||||
|
const todayCount = await tx.trip.count({
|
||||||
|
where: {
|
||||||
|
organizerId: input.organizerId,
|
||||||
|
createdAt: { gte: since },
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
if (todayCount >= LIMITS.MAX_TRIPS_PER_ORGANIZER_PER_DAY) {
|
||||||
|
throw new Error(
|
||||||
|
`Batas harian: maksimal ${LIMITS.MAX_TRIPS_PER_ORGANIZER_PER_DAY} trip per hari. Coba lagi besok.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return tx.trip.create({ data: tripData });
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
|
||||||
|
maxWait: 5000,
|
||||||
|
timeout: 15000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
lastErr = e;
|
||||||
|
if (isSerializationConflict(e) && attempt < SERIAL_TX_ATTEMPTS - 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw lastErr instanceof Error
|
||||||
|
? lastErr
|
||||||
|
: new Error("Gagal membuat trip. Coba lagi sebentar.");
|
||||||
},
|
},
|
||||||
|
|
||||||
async joinTrip(tripId: string, userId: string) {
|
async joinTrip(tripId: string, userId: string) {
|
||||||
const trip = await tripRepo.findById(tripId);
|
let lastErr: unknown;
|
||||||
|
for (let attempt = 0; attempt < SERIAL_TX_ATTEMPTS; attempt++) {
|
||||||
|
try {
|
||||||
|
return await prisma.$transaction(
|
||||||
|
async (tx) => {
|
||||||
|
const trip = await tx.trip.findUnique({
|
||||||
|
where: { id: tripId },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
status: true,
|
||||||
|
date: true,
|
||||||
|
organizerId: true,
|
||||||
|
maxParticipants: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (!trip) {
|
if (!trip) {
|
||||||
throw new Error("Trip tidak ditemukan");
|
throw new Error("Trip tidak ditemukan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trip.status !== "OPEN") {
|
if (trip.status !== "OPEN") {
|
||||||
throw new Error("Trip tidak tersedia untuk pendaftaran");
|
throw new Error("Trip tidak tersedia untuk pendaftaran");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTripDepartureDayPast(trip.date)) {
|
if (isTripDepartureDayPast(trip.date)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Trip sudah melewati tanggal berangkat, tidak bisa mendaftar"
|
"Trip sudah melewati tanggal berangkat, tidak bisa mendaftar"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trip.organizerId === userId) {
|
if (trip.organizerId === userId) {
|
||||||
throw new Error("Organizer tidak bisa join trip sendiri");
|
throw new Error("Organizer tidak bisa join trip sendiri");
|
||||||
}
|
}
|
||||||
|
|
||||||
const existing = await participantRepo.findByTripAndUser(tripId, userId);
|
const existing = await tx.tripParticipant.findUnique({
|
||||||
|
where: { tripId_userId: { tripId, userId } },
|
||||||
|
});
|
||||||
if (existing && existing.status !== "CANCELLED") {
|
if (existing && existing.status !== "CANCELLED") {
|
||||||
throw new Error("Kamu sudah terdaftar di trip ini");
|
throw new Error("Kamu sudah terdaftar di trip ini");
|
||||||
}
|
}
|
||||||
|
|
||||||
const participantCount = await participantRepo.countByTrip(tripId);
|
const participantCount = await tx.tripParticipant.count({
|
||||||
|
where: { tripId, status: { not: "CANCELLED" } },
|
||||||
|
});
|
||||||
if (participantCount >= trip.maxParticipants) {
|
if (participantCount >= trip.maxParticipants) {
|
||||||
await tripRepo.updateStatus(tripId, "FULL");
|
|
||||||
throw new Error("Trip sudah penuh");
|
throw new Error("Trip sudah penuh");
|
||||||
}
|
}
|
||||||
|
|
||||||
const participant =
|
const participant =
|
||||||
existing?.status === "CANCELLED"
|
existing?.status === "CANCELLED"
|
||||||
? await participantRepo.reactivate(tripId, userId)
|
? await tx.tripParticipant.update({
|
||||||
: await participantRepo.create(tripId, userId);
|
where: { tripId_userId: { tripId, userId } },
|
||||||
|
data: {
|
||||||
|
status: "PENDING",
|
||||||
|
markedPaidAt: null,
|
||||||
|
paymentConfirmedAt: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: await tx.tripParticipant.create({
|
||||||
|
data: { tripId, userId, status: "PENDING" },
|
||||||
|
});
|
||||||
|
|
||||||
const newCount = await participantRepo.countByTrip(tripId);
|
const newCount = await tx.tripParticipant.count({
|
||||||
|
where: { tripId, status: { not: "CANCELLED" } },
|
||||||
|
});
|
||||||
if (newCount >= trip.maxParticipants) {
|
if (newCount >= trip.maxParticipants) {
|
||||||
await tripRepo.updateStatus(tripId, "FULL");
|
await tx.trip.update({
|
||||||
|
where: { id: tripId },
|
||||||
|
data: { status: "FULL" },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return participant;
|
return participant;
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
|
||||||
|
maxWait: 5000,
|
||||||
|
timeout: 15000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
lastErr = e;
|
||||||
|
if (isSerializationConflict(e) && attempt < SERIAL_TX_ATTEMPTS - 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw lastErr instanceof Error
|
||||||
|
? lastErr
|
||||||
|
: new Error("Pendaftaran sedang ramai. Coba lagi sebentar.");
|
||||||
|
},
|
||||||
|
|
||||||
async cancelJoin(tripId: string, userId: string) {
|
async cancelJoin(tripId: string, userId: string) {
|
||||||
const trip = await tripRepo.findById(tripId);
|
const trip = await tripRepo.findById(tripId);
|
||||||
@@ -145,4 +239,149 @@ export const tripService = {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async confirmParticipant(
|
||||||
|
tripId: string,
|
||||||
|
participantId: string,
|
||||||
|
organizerId: string
|
||||||
|
) {
|
||||||
|
const trip = await tripRepo.findById(tripId);
|
||||||
|
if (!trip) {
|
||||||
|
throw new Error("Trip tidak ditemukan");
|
||||||
|
}
|
||||||
|
if (trip.organizerId !== organizerId) {
|
||||||
|
throw new Error("Hanya organizer trip ini yang bisa mengonfirmasi peserta");
|
||||||
|
}
|
||||||
|
|
||||||
|
const participant = await participantRepo.findById(participantId);
|
||||||
|
if (!participant || participant.tripId !== tripId) {
|
||||||
|
throw new Error("Peserta tidak ditemukan");
|
||||||
|
}
|
||||||
|
if (participant.status !== "PENDING") {
|
||||||
|
throw new Error("Peserta ini tidak dalam status menunggu persetujuan");
|
||||||
|
}
|
||||||
|
|
||||||
|
return participantRepo.setStatus(participantId, "CONFIRMED");
|
||||||
|
},
|
||||||
|
|
||||||
|
async rejectParticipant(
|
||||||
|
tripId: string,
|
||||||
|
participantId: string,
|
||||||
|
organizerId: string
|
||||||
|
) {
|
||||||
|
const trip = await tripRepo.findById(tripId);
|
||||||
|
if (!trip) {
|
||||||
|
throw new Error("Trip tidak ditemukan");
|
||||||
|
}
|
||||||
|
if (trip.organizerId !== organizerId) {
|
||||||
|
throw new Error("Hanya organizer trip ini yang bisa menolak permintaan bergabung");
|
||||||
|
}
|
||||||
|
|
||||||
|
const participant = await participantRepo.findById(participantId);
|
||||||
|
if (!participant || participant.tripId !== tripId) {
|
||||||
|
throw new Error("Peserta tidak ditemukan");
|
||||||
|
}
|
||||||
|
if (participant.status !== "PENDING") {
|
||||||
|
throw new Error("Hanya permintaan yang masih menunggu yang bisa ditolak");
|
||||||
|
}
|
||||||
|
|
||||||
|
await participantRepo.setStatusAndClearPayment(
|
||||||
|
participantId,
|
||||||
|
"CANCELLED"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (trip.status === "FULL") {
|
||||||
|
const count = await participantRepo.countByTrip(tripId);
|
||||||
|
if (count < trip.maxParticipants) {
|
||||||
|
await tripRepo.updateStatus(tripId, "OPEN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ok: true as const };
|
||||||
|
},
|
||||||
|
|
||||||
|
async markParticipantPayment(tripId: string, userId: string) {
|
||||||
|
const trip = await tripRepo.findById(tripId);
|
||||||
|
if (!trip) {
|
||||||
|
throw new Error("Trip tidak ditemukan");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTripDepartureDayPast(trip.date)) {
|
||||||
|
throw new Error("Trip sudah lewat — pembayaran tidak perlu ditandai");
|
||||||
|
}
|
||||||
|
|
||||||
|
const p = await participantRepo.findByTripAndUser(tripId, userId);
|
||||||
|
if (!p || p.status === "CANCELLED") {
|
||||||
|
throw new Error("Kamu tidak terdaftar di trip ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.paymentConfirmedAt) {
|
||||||
|
throw new Error("Pembayaran kamu sudah dikonfirmasi organizer");
|
||||||
|
}
|
||||||
|
if (p.markedPaidAt) {
|
||||||
|
throw new Error("Kamu sudah menandai sudah bayar — tunggu konfirmasi organizer");
|
||||||
|
}
|
||||||
|
|
||||||
|
const updated = await participantRepo.tryMarkPaidByUser(tripId, userId);
|
||||||
|
if (updated.count === 0) {
|
||||||
|
const again = await participantRepo.findByTripAndUser(tripId, userId);
|
||||||
|
if (!again || again.status === "CANCELLED") {
|
||||||
|
throw new Error("Kamu tidak terdaftar di trip ini");
|
||||||
|
}
|
||||||
|
if (again.paymentConfirmedAt) {
|
||||||
|
throw new Error("Pembayaran kamu sudah dikonfirmasi organizer");
|
||||||
|
}
|
||||||
|
if (again.markedPaidAt) {
|
||||||
|
throw new Error(
|
||||||
|
"Kamu sudah menandai sudah bayar — tunggu konfirmasi organizer"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw new Error("Tidak bisa menandai pembayaran. Coba lagi sebentar.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const row = await participantRepo.findByTripAndUser(tripId, userId);
|
||||||
|
if (!row) {
|
||||||
|
throw new Error("Data peserta tidak ditemukan setelah update");
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
},
|
||||||
|
|
||||||
|
async confirmParticipantPayment(
|
||||||
|
tripId: string,
|
||||||
|
participantId: string,
|
||||||
|
organizerId: string
|
||||||
|
) {
|
||||||
|
const trip = await tripRepo.findById(tripId);
|
||||||
|
if (!trip) {
|
||||||
|
throw new Error("Trip tidak ditemukan");
|
||||||
|
}
|
||||||
|
if (trip.organizerId !== organizerId) {
|
||||||
|
throw new Error("Hanya organizer yang bisa mengonfirmasi pembayaran");
|
||||||
|
}
|
||||||
|
|
||||||
|
const participant = await participantRepo.findById(participantId);
|
||||||
|
if (!participant || participant.tripId !== tripId) {
|
||||||
|
throw new Error("Peserta tidak ditemukan");
|
||||||
|
}
|
||||||
|
if (participant.status === "CANCELLED") {
|
||||||
|
throw new Error("Peserta sudah tidak aktif");
|
||||||
|
}
|
||||||
|
if (!participant.markedPaidAt) {
|
||||||
|
throw new Error("Peserta belum menandai sudah membayar");
|
||||||
|
}
|
||||||
|
if (participant.paymentConfirmedAt) {
|
||||||
|
throw new Error("Pembayaran peserta ini sudah dikonfirmasi");
|
||||||
|
}
|
||||||
|
|
||||||
|
const updated = await participantRepo.tryConfirmPaymentByOrganizer(
|
||||||
|
participantId
|
||||||
|
);
|
||||||
|
if (updated.count === 0) {
|
||||||
|
throw new Error(
|
||||||
|
"Konfirmasi tidak diproses — mungkin sudah dikonfirmasi atau pembayaran belum ditandai peserta."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return participantRepo.findById(participantId);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { prisma } from "@/lib/prisma";
|
||||||
|
import { TRIP_LEADER_MIN_TRIPS } from "@/lib/trust";
|
||||||
|
|
||||||
|
export type OrganizerTrust = {
|
||||||
|
isVerified: boolean;
|
||||||
|
tripsCreated: number;
|
||||||
|
avgRating: number | null;
|
||||||
|
reviewCount: number;
|
||||||
|
isTripLeader: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const trustService = {
|
||||||
|
async getOrganizerTrust(organizerId: string): Promise<OrganizerTrust> {
|
||||||
|
const [user, tripsCreated, reviewAgg] = await Promise.all([
|
||||||
|
prisma.user.findUnique({
|
||||||
|
where: { id: organizerId },
|
||||||
|
select: { isVerified: true },
|
||||||
|
}),
|
||||||
|
prisma.trip.count({ where: { organizerId } }),
|
||||||
|
prisma.tripReview.aggregate({
|
||||||
|
where: {
|
||||||
|
trip: { organizerId },
|
||||||
|
},
|
||||||
|
_avg: { rating: true },
|
||||||
|
_count: { _all: true },
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const avg = reviewAgg._avg.rating;
|
||||||
|
return {
|
||||||
|
isVerified: user?.isVerified ?? false,
|
||||||
|
tripsCreated,
|
||||||
|
avgRating:
|
||||||
|
avg != null ? Math.round(Number(avg) * 10) / 10 : null,
|
||||||
|
reviewCount: reviewAgg._count._all,
|
||||||
|
isTripLeader: tripsCreated >= TRIP_LEADER_MIN_TRIPS,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user