MarinaLoop Dev Changelog

2025-06-09

  • ๐Ÿšค Refactored "Just Book the Boat" as Primary CTA

    Axel Alwan

    Elevated the "Just Book the Boat" experience to the top of the experience list and styled it as the flagship booking method. Added context and tags like โ€œMost Flexible.โ€

  • ๐Ÿงฑ Combined Book a Private Trip with Experiences Section

    Axel Alwan

    Merged the private trip explainer block into the Featured Experiences section for cleaner layout and flow, reducing awkward spacing and improving UX.

  • ๐Ÿ“ Fixed Button Width Issues in Layout

    Axel Alwan

    Corrected an issue where `max-w-xl` was not applying as expected. Updated to `w-64` or flex container constraints for consistent button sizing.

  • ๐Ÿ“ธ Created New Activity: Photo Cruise

    Axel Alwan

    Added a new activity via SQL: "Photo Cruise" optimized for aesthetic lighting, golden hour, and creators. Set tags and duration appropriately.

  • ๐Ÿ–ผ๏ธ Generated Experience Covers with AI

    Axel Alwan

    Created custom visuals for โ€œMusic & Mimosas,โ€ โ€œPhoto Cruise,โ€ โ€œIsland Hop,โ€ โ€œSandbar Hang,โ€ and โ€œMorning Resetโ€ using high-resolution AI-generated imagery.

  • ๐Ÿงฎ Fixed SQL Tag Array Formatting

    Axel Alwan

    Resolved malformed array literal in Supabase insert by updating from string to valid array format using `{tag1,tag2}`.

2025-06-08

  • โฐ Fixed Invalid Time Bug in Booking Modal

    Axel Alwan

    Resolved a critical bug where `Date.toISOString()` was throwing on modal open due to mismatched date-time inputs. Ensured full ISO strings are passed correctly.

  • ๐Ÿ“Œ Accurate Date Assignment on Booking Click

    Axel Alwan

    Ensured that clicking a time slot now passes the correct date from the box instead of defaulting to today, fixing false date rendering in the modal.

  • ๐Ÿงฉ Improved DateTimePicker Slot Injection

    Axel Alwan

    Refactored the way slots are parsed and rendered in the modal, passing ISO-formatted start times directly from the calendar for seamless booking.

  • ๐Ÿ“ฑ Polished Mobile Popover Styling

    Axel Alwan

    Refined the bottom-sheet style popover to include sunset gold borders, sticky headers, and full-width presentation for mobile UX clarity.

  • ๐Ÿ”‘ Resolved Missing React Key Warning

    Axel Alwan

    Eliminated the React "each child in a list should have a unique key" warning by assigning slot-specific keys in the calendar rendering loop.

  • ๐Ÿ“ Enhanced Visual Hierarchy in Popovers

    Axel Alwan

    Added sticky weekday headers, improved typography, and introduced spacing/borders for readability across available time blocks.

2025-06-07

  • ๐Ÿ“ฑ Mobile-First Boat Availability Calendar

    Axel Alwan

    Redesigned the availability calendar to use a Dialog bottom sheet on mobile and Popover on desktop, making date selection intuitive across devices.

  • ๐Ÿ“† Event-Aware Boat Availability Integration

    Axel Alwan

    Integrated `public_events` into the boat availability view to visually distinguish between open slots, private reservations, and upcoming events.

  • ๐Ÿ›Ÿ Auto-Created Boat Reservations from Events

    Axel Alwan

    Implemented backend logic to auto-generate `boat_reservations` when `public_events` or `activity_bookings` are created, preventing double bookings.

  • ๐Ÿ” Polished Privacy Policy with SMS Compliance

    Axel Alwan

    Rewrote and styled the privacy policy to align with A2P 10DLC compliance, explicitly covering consent, SMS opt-out, and data deletion rights.

  • โš–๏ธ Refactored Terms of Service for Liability Protection

    Axel Alwan

    Redesigned and reworded the Terms of Service with full brand styling and stronger disclaimers to limit MarinaLoopโ€™s legal exposure.

  • ๐ŸŽจ Implemented Styled Full-Height Legal Pages

    Axel Alwan

    Both Privacy and Terms pages were visually upgraded with MarinaLoopโ€™s styling system, responsive spacing, and improved readability.

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)