MarinaLoop Dev Changelog
2025-06-04
๐ค Launched Public Charter Booking System
Axel AlwanCreated `public_events` table to support shared per-person boat charters and linked them to activities, boats, and marinas.
๐๏ธ Built CharterCalendar Page with SSR
Axel AlwanImplemented `/charter` route that displays all upcoming public events using server-side Supabase fetch for SEO benefits.
๐ Implemented Slug-Based Event Detail Pages
Axel AlwanConverted event links to use SEO-friendly slugs and built `[slug]/page.tsx` with dynamic metadata rendering.
๐งฎ Created get_remaining_spots Supabase RPC
Axel AlwanWrote a Supabase RPC function to calculate remaining guest capacity for each public event, used for booking limits.
๐ Designed PublicEventBookingForm Component
Axel AlwanAdded animated booking form with marine-styled theme, including input validation, toast alerts, and max guest enforcement.
After
๐ต Added Per Guest Pricing to Event Details
Axel AlwanDisplayed event price per guest using `price_per_guest` from `public_events`, formatted with currency utilities.
โฐ Formatted Time to AM/PM
Axel AlwanUpdated `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 AlwanDisplayed forecast icon, temperature in Fahrenheit, and chance of rain for selected date using Open-Meteoโs daily weather API.
Before
After
๐ Added Marine Conditions Toggle
Axel AlwanLet users optionally load marine conditions (wave height, wind wave, and peak period) with a โShow Tide & Marine Conditionsโ button.
๐ Improved Sunset Info Display
Axel AlwanReworked 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 AlwanResolved issues with stale or missing weather data by resetting marine and forecast states when changing dates.
๐ญ Improved Forecast Labeling
Axel AlwanReplaced โUnknownโ weather description fallback with a more user-friendly โForecast unavailable for this date.โ
๐งโโ๏ธ Condensed UI with Expandable Marine Info
Axel AlwanStreamlined the DateTimePicker UI by hiding marine details unless explicitly requested by the user, reducing visual overload.
2025-05-29
๐ Launched Featured Experiences Section
Axel AlwanCreated a visually aligned Featured Experiences component to match Featured Boats, promoting activity-first browsing.
๐ธ Refactored Booking Modal Price Breakdown
Axel AlwanAdded 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 AlwanImproved 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 AlwanCentralized sunset fetching and formatting directly inside DateTimePicker to update in sync with selected date.
๐ Identified and Highlighted Sunset Slot
Axel AlwanCreated `isSunsetSlot()` utility to detect optimal sunset-aligned time slots, highlighting them in orange as suggested picks.
๐จ Improved UX for Slot Selection Visual Cues
Axel AlwanRefined slot styling to reduce perceived pre-selection and emphasize active state vs suggested (sunset) state.
โ Planned Weather Forecast Integration
Axel AlwanEvaluated OpenWeatherMap, WeatherAPI, and Tomorrow.io for adding real-time weather guidance to booking flow.
2025-05-29
๐บ๏ธ Resolved Mapbox API Loading Issue
Axel AlwanTracked 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 AlwanConfirmed and activated Mapbox style endpoint access to ensure tile assets load correctly in production without CORS issues.
๐ Switched Boat Detail Navigation to Slug
Axel AlwanUpdated 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 AlwanRefactored `boats/[slug]/page.tsx` to fetch data using `getBoatBySlug()` and correctly load associated activities by boat ID.
โ Verified Slug Routing and Link Consistency
Axel AlwanValidated 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 AlwanConnected `useAvailableSlots` with `BookingModal` to validate time-based experiences like sunset cruises against available calendar slots.
โณ Dynamic Sunset Time Calculation with Override
Axel AlwanImproved `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 AlwanDisplayed a fallback date picker if no slots matched sunset-based defaults, enabling user-controlled retries for booking.
๐ Extended Slot Generation Past Sunset
Axel AlwanUpdated `getAvailableTimeSlotsJS` to extend the availability window up to 2 hours after sunset for sunset-based experiences.
๐ Debugged Slot Mismatch Between Sunset and Availability
Axel AlwanResolved mismatch between sunset start time and available slots by aligning ISO string comparison precision in `BookingModal.tsx`.
๐ก๏ธ Improved Booking Validation Guard Rails
Axel AlwanPrevented 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 AlwanRestructured boat detail pages to highlight available activities before showing boat info, shifting focus to user intent-driven discovery.
๐งฑ Launched New Global Activities Architecture
Axel AlwanCreated `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 AlwanPopulated 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 AlwanUpdated 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 AlwanIntroduced `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 AlwanReplaced legacy `boat_activities` query with dynamic join across `activities` and `boat_activity_links` for scalable activity assignment.
๐ง Fixed TypeScript Compatibility Between Tables
Axel AlwanResolved 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 AlwanConnected 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 AlwanBuilt `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 AlwanEmbedded 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 AlwanIntroduced 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 AlwanResolved 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 AlwanSuccessfully 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 AlwanRemoved 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 AlwanIntegrated `min_hours` and `max_hours` fields into the booking flow to define flexible but bounded session durations.
๐ง Fixed Broken Duration Selector Minimum Logic
Axel AlwanResolved float rounding and state reactivity issues that previously prevented users from selecting below the included hours.
โป๏ธ Refactored Duration State Rehydration
Axel AlwanIntroduced 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 AlwanReplaced legacy `bookings` filtering with accurate `activity_bookings` overlap detection using composed datetime checks.
๐ก Sanitized RPC Call for Activity Booking
Axel AlwanResolved 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 AlwanFixed 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 AlwanUsers 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 AlwanBooking 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 AlwanCreated 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 AlwanFinal 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 AlwanGuest 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 AlwanIntegrated 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 AlwanReplaced 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 AlwanCorrected booking end-time calculation and synced duration with slot selection. Now supports flexible multi-hour bookings.
๐งน Refactored Slot Filtering Logic
Axel AlwanRemoved broken chain-filtering logic in favor of straightforward availability generation, unlocking stable UX for users selecting longer durations.
๐งผ Responsive Booking Modal Layout Cleanup
Yaarub AlwanReorganized booking form into structured cards for availability, guests, duration, and payment summary with better spacing and flow.
๐ End Time Preview with Contextual Copy
Yaarub AlwanAdded 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 AlwanResolved 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 AlwanConsolidated 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 AlwanDisplayed 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 AlwanActivity 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 AlwanInitially split activity vs boat modals, then simplified the approach by dynamically adjusting props inside a single modal.
โฑ๏ธ Improved Extra Hour Charge Conditions
Axel AlwanFixed 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 AlwanMade duration editable even for flat-rate activities to allow optional time extensions and fee calculations.
๐ฅ Added Booking Modal Metadata and Guest Cap Logic
Axel AlwanDefaulted 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 AlwanCaptains 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 AlwanEach boat now shows activities with duration, base price, and tiered guest/hour pricing displayed in responsive cards.
๐ฆ Created `getBoatActivities` query
Axel AlwanFetched 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 AlwanOutlined system to validate boat and captain availability with dual calendar logic and minimum heads-up rules.
๐ฒ Scoped Booking Workflow with Auto-Confirmation & Notifications
Axel AlwanDesigned post-payment logic including instant confirmation, phone number exchange, and alerts to both captain and customer.
๐ Proposed `captain_availability` and blackout structure
Axel AlwanArchitected future tables for weekly availability, custom blackouts, and slot validation using time overlap checks.
May 14, 2025
โ Fixed JWT expiration during image upload
Axel AlwanResolved session issues by refreshing Supabase auth on reload.
๐ผ๏ธ Synced image uploads to image_urls in the boats table
Axel AlwanUpdated local form state and ensured image URLs were included in the database update payload.
๐ Replaced manual BoatData interface
Axel AlwanNow using Supabase types via `type Boat = Database['public']['Tables']['boats']['Row']`.
๐ Created an RLS policy for UPDATE
Axel AlwanPolicy uses auth.uid() = boat_owner with a WITH CHECK to ensure safe updates.
USING (auth.uid() = boat_owner) WITH CHECK (auth.uid() = boat_owner)