changes / ios

MPC iOS — Version Changelog

Versi aktif berikutnya: v1.10 (current v1.9). Chat sama → jangan bump, update bullet saja.

Independen dari Android/POS. Indeks: mpc-dev/docs/versions/README.md.


v1.9 — 2026-08-20

  • OTP verify (parity Android v1.20): "Verify & Continue" morph bouncing ball + splash "Let's Start!" ke Home setelah register verify sukses.
  • Reset password via OTP: morph loading lalu ke Login (tanpa splash), parity Android.

v1.8 — 2026-08-15

  • Login Sign In (parity Android v1.19): morph rounded-rect → circle bouncing saat loading; sukses splash primary + "Let's Start!" 1 detik lalu Home.
  • Secondary actions disembunyikan selama loading/splash; gagal morph kembali + error.
  • Setelah API sukses, tunggu minimal 1 full bounce baru splash (parity Android).
  • Bounce diganti hop fisik naik–turun (bukan pulse), parity Android.
  • Secondary actions fade opacity (layout tetap) supaya Sign In tidak loncat.
  • Bounce dihaluskan: keyframeAnimator hop kontinu; squash impact-based cepat saat mendarat (parity Android).
  • Lingkaran loading 40; tinggi tombol idle tetap 56; lompatan bola 96, siklus ~0.76s, squash impact tipis (0.88) dan instan ~30ms (parity).
  • Log Out: spinner + "Logging out…" saat revoke token; klik ganda dicegah (parity Android).
  • Field password: ikon mata toggle show/hide password (parity Android).
  • Login gagal: bounce 1 siklus dulu + pesan error manusiawi (parity Android).
  • Bottom tab bar redesign (parity Android): warna unselected diganti dari textSecondary abu-abu (mismatch) jadi primary opacity 42%; tap feedback sekarang mendimkan seluruh tab (icon + label) via ButtonStyle kustom, bukan cuma default highlight icon.
  • Lock orientasi ke portrait (Info.plist + AppDelegate .portrait; iPad landscape dihapus, UIRequiresFullScreen).
  • Home welcome (parity Android): sapaan → kartu upcoming → Quick Actions satu-satu → sisa halaman; sekali per sesi, reset setelah logout.
  • Home header (parity Android): kartu "Upcoming Match" diganti PromoCarousel gambar looping (auto-advance ~4.5s, swipe, dot indicator) — hanya promo dengan imageUrl, urut displayOrder; header lebih ringkas bila tidak ada promo bergambar.
  • "Upcoming Match" dipindah ke kartu tersendiri di atas "Quick Actions"; tombol "Play Live" → "Play", hanya tampil selama jam main (cek ulang tiap 30s), parity Android.
  • Section "Promotions" (banner teks/emoji) dihapus dari Home, parity Android.
  • Kartu "Upcoming Match" di body Home disembunyikan sementara (flag showUpcomingMatchCard = false, mudah dinyalakan lagi), parity Android — carousel promo di header tetap tampil.
  • Pull-to-refresh (.refreshable) ditambahkan di Home (reload home content + upcoming booking) dan Time Slot Booking (reload daftar court + availability slot berjalan, tanpa reset pilihan tanggal/durasi/court aktif), parity Android.
  • Promo carousel (parity Android): tinggi diubah dari fixed 128 jadi rasio 16:9 (aspectRatio(16/9, contentMode: .fit)) — mengikuti cek langsung ke project mtix_lumiere (cinema chain) yang memakai formula tinggi banner (lebar layar - 32) / 3.6 + 96; 16:9 dipilih karena hasilnya nyaris identik pada lebar device umum sekaligus cocok dengan aspek rasio gambar promo yang baru. Header Home yang menampung carousel ikut menyesuaikan tinggi secara dinamis (bukan konstanta 228 tetap).
  • Nama promo + badge diskon sekarang digambar native di atas foto (scrim gradient bawah) berdasarkan data live PromoDto.name/type/value, parity Android — dot indicator dipindah ke pojok kanan-atas.
  • Regenerate 5 foto promo (real photography, tanpa teks/watermark) di rasio 16:9, parity Android — replace file lama yang aspect ratio-nya kependekan (1.5:1).
  • Promo carousel dikecilkan lagi (parity Android): tinggi dikurangi 24pt dari hasil rasio 16:9 (bukan bikin foto baru — file lama tetap dipakai, SmartImage fill crop yang menangani sisa crop di bagian bawah). Tinggi dihitung sekali di HomeScreen lalu diteruskan sebagai height eksplisit ke PromoCarousel (bukan lagi .aspectRatio mandiri), jadi header ikut menyusut pas sama besar.

v1.7 — 2026-08-15

  • UI Notifications (parity Android): hapus swipe-delete merah; kartu tenang, unread dot primer, loading/empty elegan, ikon per kategori + NotificationDto.category.
  • Tanggal notifikasi hari ini: relatif (Just now / 10 minutes ago / 1 hour ago); ticker 30 detik supaya label tidak stuck saat halaman tetap terbuka.

v1.6 — 2026-08-13

  • Resto reservations (parity Android v1.17, api_contract §14): fitur reservasi space resto (Room VIP privat & dining area) end-to-end.
  • Home: Quick Action baru "Resto" (ikon utensils) → Resto landing.
  • RestoScreen baru: intro "Dine at the Club", kartu space dari GET /spaces urut display_order (foto / placeholder elegan, label "Private room"/"Dining area", "Up to N guests", "Minimum spend Rp X"), row sekunder "Order food & drinks" → F&B.
  • SpaceReserveScreen baru: date picker forward-only (pola sama dengan time-slot court), stepper Guests 1..max_party_pax + note "For larger groups, please contact us.", grid slot mulai 30-menit dengan copy "N-minute seating", slot penuh/lewat disabled; dialog konfirmasi (space, date, time range, guests, note minimum spend "settled through food & beverage purchases at the venue") → POST /spaces/reservations → success state dengan kode reservasi; error 400/409 ditampilkan sopan + slots di-refresh diam-diam.
  • History "My Bookings": segmented filter Courts / Resto; tab Resto dari GET /spaces/reservations/me (space, tanggal, jam, guests, badge status Confirmed/Seated/Completed/Cancelled/No-show, minimum spend); Cancel dengan dialog konfirmasi hanya untuk Confirmed + future + source ≠ CourtBundle (POST /spaces/reservations/:id/cancel), penolakan API ditampilkan inline.
  • Court Detail: callout "Includes Private VIP Room — {name}" (+ "Minimum spend Rp X applies, settled through F&B.") di atas perk chips saat bundled_space ada; bundled_space ditambahkan ke CourtDto/model Court.
  • Data layer: DTO/model/mapper/repo untuk Spaces (SpaceDto, SpaceAvailabilityDto, SpaceReservationDto, CreateSpaceReservationBody, RestoSpace, SpaceSlot, SpaceAvailability, SpaceReservation), cache RuntimeCatalog.spaces, ikon Lucide utensils.
  • Court Detail: copy callout VIP room disesuaikan bundling best-effort — "Included when the room is available for your slot".
  • Resto landing: hapus row "Order food & drinks" — order F&B hanya ditawarkan setelah reservasi berhasil (tombol "Order food & drinks" di success state).
  • Dialog konfirmasi reservasi diganti bottom sheet (.sheet, foto space, nama, tipe, tanggal/jam/guests/durasi, note minimum spend) — 1:1 dengan Android.
  • Flow reservasi dirombak berurutan: pilih tanggal di landing Resto (date strip dipindah dari SpaceReserveScreen, dibawa via restoReserve(spaceId:isoDate:)) → pilih ruangan+pax → pilih jam saja di reserve screen; landing tambah section "Your reservations" (quiet reminder + link "See all" ke History) via MainTabState/Router.goHistory().
  • Pre-order F&B terikat ke reservasi: tombol "Order food & drinks" di success state membuka katalog F&B mode pre-order (foodDrinks(reservationId:)) — CheckoutState dimulai bersih + tag spaceReservationId, checkout langsung ke Payment (tanpa alur cart court booking); schema baru transactions.space_reservation_id (migration 021) + POST /orders terima space_reservation_id + GET /spaces/reservations/me sertakan orders[].
  • History tab Resto: card reservasi menampilkan pesanan F&B yang terikat (ReservationOrdersSummary — item, qty, status, total) di bawah detail reservasi, bukan entri terpisah.
  • Copy "No minimum spend" (bukan diam saja) di kartu space, ringkasan reserve screen, bottom sheet konfirmasi, success state, dan History saat space/reservasi tidak punya minimum spend.
  • Fix compile: router.navigate(.foodDrinks).foodDrinks() di HomeScreen/BookingScreen mengikuti signature route baru.
  • Fitur Tip di booking history (parity Android v1.17): order Completed menampilkan section Tip di bawah Payment Summary (BookingDetailScreen) — belum pernah tip → CTA "Give a Tip"; sudah pernah → kartu "Thank you for your generosity" dengan nominal (1x per order). TipScreen baru (route .tip(transactionId:)): chip Rp 5rb/10rb/20rb/30rb/50rb (single-select) atau input manual (min Rp 5.000, tanpa batas atas) → POST /orders/:id/tip → lanjut ke PaymentScreen lewat OrderResultState.payExistingTransaction (flow sama seperti reschedule fee).
  • PaymentScreen: infra baru title & kartu invoice dinamis untuk existing-invoice pay — judul jadi "Pay {nama item}" dan kartu ringkasan nominal ditampilkan di atas metode pembayaran (sebelumnya statis "Payment" tanpa info nominal, termasuk untuk reschedule fee yang sudah ada sebelumnya).
  • OrderSummaryScreen: saat transaksi bertipe Tip, hero copy jadi "Thank You!" + pesan apresiasi, tombol jadi "Back to My Bookings" (Router.goHistory()) — berlaku juga untuk reschedule fee (deteksi via transactionType != "Mixed"), selain itu tetap "Booking Confirmed!" / "Back to Home".
  • Data layer: TransactionDto.tipAmount + CreateTipRequestDto, BookingHistoryItem.tipAmount (di-map dari transaksi saat getBookingHistory()), MpcApi.createOrderTip (POST orders/{id}/tip), MpcRepository.createOrderTip.

v1.5 — 2026-08-11

  • API-only: hapus Developer Mode / dummy data source; catalog selalu dari mpc-be.
  • Matchplay sync: DTO + MpcApi (detail, join, participants, generate, update game, leaderboard).
  • Create Match → create + add guests + generate session dari API; skor game sync ke BE.
  • Community players dari GET /users/players; Home open matches / top players tanpa fallback dummy.
  • Google Sign-In: tampilkan "belum tersedia" (tolak mock token).
  • FnB Pick-up time: GET /settings/fnb-pickup, picker Order Summary, fnb_pickup_time di checkout (parity Android).
  • Court Detail showcase (parity Android v1.16): CourtDetailScreen immersive (hero gallery full-bleed + scrim, back/share/favorite melayang, perk chips, About, Specifications, sticky bar "Book This Court"); Home CourtCard tanpa tombol Book → tap card buka detail; timeSlot(courtId:) preselect By court; GET /courts/:id + field description/gallery/specs/perks.
  • Order Complete & Booking Details: baris FnB "Pick-up time" (normalisasi offset TZ), history split item F&B vs Rent via katalog, Payment Summary lengkap (subtotal per kategori + breakdown PPN/PB1/service bila cocok tax_amount server).

v1.4 — 2026-08-10

  • Parity Android v1.15: create match API, notifications dari API, favorites Player sync.

v1.3 — 2026-08-10

  • Parity Android v1.14: category ProShop/Rent; booking sections Rent vs Pro Shop; dummy tanpa Rent-in-merch.
  • Booking court picker (By time + By court): kartu teks saja, tanpa gambar (parity Android).
  • Fix Time Slot semua "Full": getRawData sekarang unwrap field data dari envelope API (sebelumnya parse root → availability kosong).
  • Court picker: daftar vertikal full-width (tanpa scroll samping); harga hanya /hr.
  • Hapus label "Find by" & "Choose your court"; slot expanded = satu kotak (waktu + court).
  • Bottom bar: Book + total Court rental; animasi expand/collapse slot; court cards grid 2 kolom.
  • Label Select Court; section By court muncul/hilang dengan animasi.
  • Animasi Select Court / expand slot: tanpa move-from-top (hindari nembus/jump); auto-scroll ke slot yang di-expand.

v1.2 — 2026-08-09

  • Time Slot: no "Available" badge; "Select time"; segmented By time / By court (parity Android v1.13).
  • By court court picker uses image cards (same as By time).

v1.1 — 2026-08-09

  • Availability/Time Slot: API mode selalu re-fetch courts (parity Android v1.12) — cegah court soft-deleted di cache tampil Sold.
  • Dummy courts: Court 1–3, displayOrder 1–3, Court 3 = VIP.

v1.0 — baseline

  • App iOS MPC (mpc-customer/mpc-ios) sebelum changelog formal di mpc-dev/docs/changes/ios.md.