MarinaLoop Dev Changelog

2025-06-04

  • ๐Ÿšค Launched Public Charter Booking System

    Axel Alwan

    Created `public_events` table to support shared per-person boat charters and linked them to activities, boats, and marinas.

  • ๐Ÿ—“๏ธ Built CharterCalendar Page with SSR

    Axel Alwan

    Implemented `/charter` route that displays all upcoming public events using server-side Supabase fetch for SEO benefits.

  • ๐Ÿ”— Implemented Slug-Based Event Detail Pages

    Axel Alwan

    Converted event links to use SEO-friendly slugs and built `[slug]/page.tsx` with dynamic metadata rendering.

  • ๐Ÿงฎ Created get_remaining_spots Supabase RPC

    Axel Alwan

    Wrote a Supabase RPC function to calculate remaining guest capacity for each public event, used for booking limits.

  • ๐Ÿ“‹ Designed PublicEventBookingForm Component

    Axel Alwan

    Added animated booking form with marine-styled theme, including input validation, toast alerts, and max guest enforcement.

    After

    After screenshot
  • ๐Ÿ’ต Added Per Guest Pricing to Event Details

    Axel Alwan

    Displayed event price per guest using `price_per_guest` from `public_events`, formatted with currency utilities.

  • โฐ Formatted Time to AM/PM

    Axel Alwan

    Updated `formatTimeString` to convert event start time from military to 12-hour format for better readability.

2025-05-30

  • ๐ŸŒค๏ธ Integrated Daily Weather Forecast with Open-Meteo

    Axel Alwan

    Displayed forecast icon, temperature in Fahrenheit, and chance of rain for selected date using Open-Meteoโ€™s daily weather API.

    Before

    Before screenshot

    After

    After screenshot
  • ๐ŸŒŠ Added Marine Conditions Toggle

    Axel Alwan

    Let users optionally load marine conditions (wave height, wind wave, and peak period) with a โ€œShow Tide & Marine Conditionsโ€ button.

  • ๐ŸŒ‡ Improved Sunset Info Display

    Axel Alwan

    Reworked sunset logic to show accurate sunset time and highlight โ€œSunset Viewโ€ slots. Sunset time now re-fetches on date change.

  • ๐Ÿงผ Handled Missing Weather Gracefully

    Axel Alwan

    Resolved issues with stale or missing weather data by resetting marine and forecast states when changing dates.

  • ๐Ÿ“ญ Improved Forecast Labeling

    Axel Alwan

    Replaced โ€œUnknownโ€ weather description fallback with a more user-friendly โ€œForecast unavailable for this date.โ€

  • ๐Ÿง˜โ€โ™‚๏ธ Condensed UI with Expandable Marine Info

    Axel Alwan

    Streamlined the DateTimePicker UI by hiding marine details unless explicitly requested by the user, reducing visual overload.

2025-05-29

  • ๐ŸŒŸ Launched Featured Experiences Section

    Axel Alwan

    Created a visually aligned Featured Experiences component to match Featured Boats, promoting activity-first browsing.

  • ๐Ÿ’ธ Refactored Booking Modal Price Breakdown

    Axel Alwan

    Added breakdowns for extra guests and extra hours, and displayed dynamic "Only $X per person!" callout for price clarity.

  • โš ๏ธ Highlighted Unavailable Days and Sunset Time

    Axel Alwan

    Improved feedback when no slots are available with styled alerts and animated input borders. Added a styled sunset badge with emoji gradients.

  • ๐Ÿ“† Moved Sunset Logic into DateTimePicker

    Axel Alwan

    Centralized sunset fetching and formatting directly inside DateTimePicker to update in sync with selected date.

  • ๐ŸŒ‡ Identified and Highlighted Sunset Slot

    Axel Alwan

    Created `isSunsetSlot()` utility to detect optimal sunset-aligned time slots, highlighting them in orange as suggested picks.

  • ๐ŸŽจ Improved UX for Slot Selection Visual Cues

    Axel Alwan

    Refined slot styling to reduce perceived pre-selection and emphasize active state vs suggested (sunset) state.

  • โ›… Planned Weather Forecast Integration

    Axel Alwan

    Evaluated OpenWeatherMap, WeatherAPI, and Tomorrow.io for adding real-time weather guidance to booking flow.

2025-05-29

  • ๐Ÿ—บ๏ธ Resolved Mapbox API Loading Issue

    Axel Alwan

    Tracked down missing API key error in `experiences/[slug]/page.tsx` caused by unconfigured environment variable and enabled Mapbox API via Supabase Edge settings.

  • ๐Ÿงฉ Enabled Mapbox Tile Access in Supabase

    Axel Alwan

    Confirmed and activated Mapbox style endpoint access to ensure tile assets load correctly in production without CORS issues.

  • ๐Ÿ”— Switched Boat Detail Navigation to Slug

    Axel Alwan

    Updated boat listing cards to use `/boats/[slug]` instead of ID-based routing, aligning with the new slug-based dynamic routing setup.

  • ๐Ÿ›ฅ๏ธ Confirmed Slug-Based Boat Detail Fetching

    Axel Alwan

    Refactored `boats/[slug]/page.tsx` to fetch data using `getBoatBySlug()` and correctly load associated activities by boat ID.

  • โœ… Verified Slug Routing and Link Consistency

    Axel Alwan

    Validated consistency between filtered boat lists and detailed views, ensuring seamless routing and data hydration across pages.

2025-05-28

  • ๐ŸŒ‡ Integrated Slot Availability for Sunset Cruises

    Axel Alwan

    Connected `useAvailableSlots` with `BookingModal` to validate time-based experiences like sunset cruises against available calendar slots.

  • โณ Dynamic Sunset Time Calculation with Override

    Axel Alwan

    Improved `getSunsetTime()` to fetch sunset for the selected date and subtract 1.5 hours, rounding to nearest 5 minutes for start time.

  • ๐Ÿ“… Added Date Picker for Unavailable Sunset Slots

    Axel Alwan

    Displayed a fallback date picker if no slots matched sunset-based defaults, enabling user-controlled retries for booking.

  • ๐ŸŒ™ Extended Slot Generation Past Sunset

    Axel Alwan

    Updated `getAvailableTimeSlotsJS` to extend the availability window up to 2 hours after sunset for sunset-based experiences.

  • ๐Ÿ” Debugged Slot Mismatch Between Sunset and Availability

    Axel Alwan

    Resolved mismatch between sunset start time and available slots by aligning ISO string comparison precision in `BookingModal.tsx`.

  • ๐Ÿ›ก๏ธ Improved Booking Validation Guard Rails

    Axel Alwan

    Prevented double booking and stale slot submissions by verifying user-selected start time is still in current slot list before proceeding.

May 26, 2025

  • ๐ŸŽฏ Redesigned Activity-First Booking Experience

    Axel Alwan

    Restructured boat detail pages to highlight available activities before showing boat info, shifting focus to user intent-driven discovery.

  • ๐Ÿงฑ Launched New Global Activities Architecture

    Axel Alwan

    Created `activities` and `boat_activity_links` tables to support decoupled activity definitions with flexible many-to-many boat mapping and future location-based matching.

  • ๐ŸŒ… Seeded Demo Activities and Linked Boats

    Axel Alwan

    Populated new activity tables with seed data for party cruises, dolphin tours, and sunset rides, linked to real boats via `boat_activity_links`.

  • ๐ŸŽจ Enhanced ActivityCard UI & UX

    Axel Alwan

    Updated activity cards with full-click booking interaction, updated styling, gallery image previews, and improved color harmony using custom design tokens.

  • ๐Ÿงช Refactored BookingModal with Zod Validation

    Axel Alwan

    Introduced `zod` schema to validate booking form inputs, ensuring better data hygiene and clearer feedback for end users.

  • ๐Ÿ”— Rewired Activity Fetch Logic to Use Join Table

    Axel Alwan

    Replaced legacy `boat_activities` query with dynamic join across `activities` and `boat_activity_links` for scalable activity assignment.

  • ๐Ÿ”ง Fixed TypeScript Compatibility Between Tables

    Axel Alwan

    Resolved mismatches between `BoatActivityWithGlobal` types and legacy RPC payloads by restructuring selected activity fields and sanitizing data shapes.

May 22, 2025

  • ๐Ÿ’ณ Integrated Stripe Payment Intent Flow

    Axel Alwan

    Connected Stripe `CheckoutForm` with PaymentElement and `confirmPayment`, allowing users to submit payments without redirects and return a success status for booking updates.

  • ๐Ÿ“ฌ Created Secure Webhook for Stripe Events

    Axel Alwan

    Built `api/webhooks/bookings` to process `payment_intent.succeeded` events and update bookings with `is_paid = true` securely using Stripe signature verification.

  • ๐Ÿ” Added UUID Token Metadata for Stripe Sync

    Axel Alwan

    Embedded unique booking `uuid_token` into Stripe metadata for use in the webhook handler, ensuring precise booking targeting on payment success.

  • ๐Ÿ›ก๏ธ Patched Supabase RLS to Allow Updates

    Axel Alwan

    Introduced Row Level Security policy on `activity_bookings` to permit updates from the webhook route for authenticated and secure writes.

  • ๐Ÿ”‘ Fixed Stripe Webhook Signature Mismatch

    Axel Alwan

    Resolved silent webhook failures by syncing `STRIPE_WEBHOOK_SECRET_BOOKINGS` between Stripe CLI and production environment, ensuring signature verification passes.

  • โœ… Verified is_paid Field Updates in Supabase

    Axel Alwan

    Successfully confirmed that bookings are now updated as `is_paid: true` after real or test payments, completing the payment-to-database loop.

May 21, 2025

  • ๐Ÿง  Refactored Booking Modal State Management

    Axel Alwan

    Removed redundant logic (like isActivity type guards) and restructured the state to rely purely on normalized data from the `boat_activities` table.

  • ๐Ÿ“ Added min_hours and max_hours to Activity Logic

    Axel Alwan

    Integrated `min_hours` and `max_hours` fields into the booking flow to define flexible but bounded session durations.

  • ๐Ÿ”ง Fixed Broken Duration Selector Minimum Logic

    Axel Alwan

    Resolved float rounding and state reactivity issues that previously prevented users from selecting below the included hours.

  • โ™ป๏ธ Refactored Duration State Rehydration

    Axel Alwan

    Introduced reactive state updates using `useEffect` to dynamically reset duration and availability bounds when the activity or boat changes.

  • ๐Ÿงฎ Synced Slot Filtering with Activity Bookings

    Axel Alwan

    Replaced legacy `bookings` filtering with accurate `activity_bookings` overlap detection using composed datetime checks.

  • ๐Ÿ“ก Sanitized RPC Call for Activity Booking

    Axel Alwan

    Resolved column mismatches and clarified datetime composition for the `book_activity_v2` Supabase RPC. Now fully respects duration, date, and time.

  • โœ… Cleaned Up Booking Confirmation Page

    Axel Alwan

    Fixed invalid date display bug by correcting the server-side datetime construction and feeding in proper ISO strings for the summary card.

May 20, 2025

  • ๐Ÿ‘ค Added Guest Checkout Booking Flow

    Axel Alwan

    Users can now book without logging in by entering their name, email, and phone number. Booking data is stored with a unique token and no auth required.

  • ๐Ÿ“„ Inline Booking Confirmation UI

    Axel Alwan

    Booking confirmation, payment reminder, and session details now render directly inside the modal after submission โ€” no redirect required.

  • ๐Ÿงพ Supabase Insert with UUID and Guest Info

    Axel Alwan

    Created bookings now include `uuid_token`, `guest_name`, `guest_email`, `guest_phone`, and `num_guests`, enabling post-booking access and communication.

  • ๐Ÿ’ต Dynamic Booking Summary Calculation

    Axel Alwan

    Final cost, extra guest/hour charges, and per-person pricing now update live based on duration and guest count before confirmation.

  • ๐Ÿง‘โ€๐Ÿ’ป Improved Modal UX and Input Validation

    Axel Alwan

    Guest input fields added for full name, email, and phone. Modal now scrolls appropriately and disables background scrolling while open.

May 19, 2025

  • ๐Ÿ“… Overhauled DateTimePicker with Live Slot Generation

    Axel Alwan

    Integrated a smarter `DateTimePickerWithSlots` that dynamically generates slots based on boat availability, filters overlapping bookings, and adapts to duration.

  • ๐Ÿ•’ Improved Time Range Formatting and UX

    Axel Alwan

    Replaced military time with localized AM/PM format and displayed clear start-end time ranges. Selections now visually highlight the full session block.

  • ๐Ÿ“ Fixed Duration Logic for Accurate Pricing and End Time

    Axel Alwan

    Corrected booking end-time calculation and synced duration with slot selection. Now supports flexible multi-hour bookings.

  • ๐Ÿงน Refactored Slot Filtering Logic

    Axel Alwan

    Removed broken chain-filtering logic in favor of straightforward availability generation, unlocking stable UX for users selecting longer durations.

  • ๐Ÿงผ Responsive Booking Modal Layout Cleanup

    Yaarub Alwan

    Reorganized booking form into structured cards for availability, guests, duration, and payment summary with better spacing and flow.

  • ๐Ÿ”Ž End Time Preview with Contextual Copy

    Yaarub Alwan

    Added a friendly summary below the time picker showing start and end time clearly, improving trust and decision clarity.

  • ๐Ÿ› Fixed Modal Auto-Close Bug on Slot Selection

    Yaarub Alwan

    Resolved issue where clicking a time slot would accidentally trigger modal close, maintaining session state as expected.

May 18, 2025

  • ๐Ÿงฉ Unified Booking Modal for Boats and Activities

    Axel Alwan

    Consolidated flat-rate and per-hour booking logic into a single `BookingModal`, using conditional pricing logic based on whether an activity is selected.

  • ๐Ÿ’ฐ Dynamic Price Breakdown with Per-Person Estimate

    Axel Alwan

    Displayed base cost, extra guest and time charges, and calculated per-person rate. Logic adapts based on activity or open boat rental.

  • ๐ŸŽฏ Integrated Book Buttons into Activity Cards

    Axel Alwan

    Activity cards now include a call-to-action that opens the unified booking modal with relevant activity data.

  • ๐Ÿ”„ Switched from Split Modal to Smart Prop Logic

    Axel Alwan

    Initially split activity vs boat modals, then simplified the approach by dynamically adjusting props inside a single modal.

  • โฑ๏ธ Improved Extra Hour Charge Conditions

    Axel Alwan

    Fixed logic to only show extra hour charges on flat-rate activities, avoiding confusing UI on per-hour boat bookings.

  • ๐Ÿ“ Duration Field Always Visible for Booking Control

    Axel Alwan

    Made duration editable even for flat-rate activities to allow optional time extensions and fee calculations.

  • ๐Ÿ‘ฅ Added Booking Modal Metadata and Guest Cap Logic

    Axel Alwan

    Defaulted guest count based on boat or activity limits and enforced per-hour rate with UI feedback.

May 15, 2025

  • ๐Ÿงญ Added Captain Display to Boat Page

    Axel Alwan

    Captains are now shown with their name, bio, and image on the boat detail page. Includes a fallback icon if no profile photo exists.

  • โš“ Implemented Activity Cards with Tiered Pricing

    Axel Alwan

    Each boat now shows activities with duration, base price, and tiered guest/hour pricing displayed in responsive cards.

  • ๐Ÿ“ฆ Created `getBoatActivities` query

    Axel Alwan

    Fetched all active activities per boat and added UI section to render them with optional pricing rules.

    export const getBoatActivities = async (supabase, boatId) => {
      return supabase.from('boat_activites').select('*').eq('boat_id', boatId).eq('is_active', true);
    }
  • ๐Ÿง  Planned Booking Architecture with Conflict Checks

    Axel Alwan

    Outlined system to validate boat and captain availability with dual calendar logic and minimum heads-up rules.

  • ๐Ÿ“ฒ Scoped Booking Workflow with Auto-Confirmation & Notifications

    Axel Alwan

    Designed post-payment logic including instant confirmation, phone number exchange, and alerts to both captain and customer.

  • ๐Ÿ“… Proposed `captain_availability` and blackout structure

    Axel Alwan

    Architected future tables for weekly availability, custom blackouts, and slot validation using time overlap checks.

May 14, 2025

  • โœ… Fixed JWT expiration during image upload

    Axel Alwan

    Resolved session issues by refreshing Supabase auth on reload.

  • ๐Ÿ–ผ๏ธ Synced image uploads to image_urls in the boats table

    Axel Alwan

    Updated local form state and ensured image URLs were included in the database update payload.

  • ๐Ÿ“˜ Replaced manual BoatData interface

    Axel Alwan

    Now using Supabase types via `type Boat = Database['public']['Tables']['boats']['Row']`.

  • ๐Ÿ” Created an RLS policy for UPDATE

    Axel Alwan

    Policy uses auth.uid() = boat_owner with a WITH CHECK to ensure safe updates.

    USING (auth.uid() = boat_owner)
    WITH CHECK (auth.uid() = boat_owner)