1. 01 Jul, 2026 17 commits
    • Mahmoud Aglan's avatar
      Fix all column mismatches between code and live database schema · 0cc5b982
      Mahmoud Aglan authored
      Critical SQL fixes (pages were crashing):
      - GlobalSearch: remove non-existent branch_id/invoice_number, fix relationship
      - RevenueWidget: payment_method → method
      - FinancialReport: line_total → total_amount, balance_due → due_amount
      - PaymentPlanCreate: rewrite to match actual payment_plans/installments schema
      
      High-priority display fixes (features showing null):
      - invoice_number → number (8 locations)
      - balance_due → due_amount (6 locations)
      - full_name_ar → full_name (7 locations, accessor doesn't exist)
      - payment_method → method in print view
      - subtotal → subtotal_amount
      - description → notes on invoice
      - line_total → total_amount on invoice items
      - receipt_number → reference on payment
      
      Medium fixes:
      - Dashboard: fix format() call on string time column
      - Participant card: access person fields via relationship
      
      Low fixes:
      - daily-financial-print: createdBy → creator relationship
      - reports-page: payment_method key → method
      
      Infrastructure:
      - Add migration for cash_session_id on payments table
      - Add cash_session_id to Payment model fillable
      - Fix float → decimal:2 casts on Evaluation/EvaluationScore
      - Update enum registry docs to match actual DB CHECK constraints
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      0cc5b982
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
      Fix broken links, add cross-links, and wire up navigation across views · 7f52ca38
      Mahmoud Aglan authored
      - Fix "Record Payment" button on participant-show (was linking to list)
      - Add clickable links in enrollment-list (participant, group, program)
      - Add participant links on invoice contact names (list + show)
      - Add print button on invoice-show, print link on group-list
      - Add bulk-status link on participant-list
      - Link wizard success screens to participant/invoice views
      - Fix guardian dashboard: child names, invoices, groups now clickable
      - Add missing model relationships: Branch (participants, groups,
        facilities, cashSessions), Payment (branch, cashSession),
        CashSession (payments, posTransactions), TrainingSchedule (facility),
        Participant (branch, wallet, invoices, payments, attendance, POS,
        evaluations), Invoice (enrollments, posTransaction)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      7f52ca38
    • Mahmoud Aglan's avatar
      Full UX overhaul: tap feedback, close buttons, active states · 1e55b9c5
      Mahmoud Aglan authored
      Problems fixed:
      - -webkit-tap-highlight-color:transparent killed OS default feedback
        but no custom active states existed → users got zero confirmation
        of their taps on mobile. Now ALL buttons/links get scale(0.97) on
        :active via CSS base layer, plus explicit active:bg-* on key buttons.
      - No modal/dropdown had a visible X close button → users couldn't
        discover how to dismiss on touch. Added X buttons to: sidebar (mobile),
        topbar user menu, global search dropdown, POS receipt modal, and all
        confirmation modals (enrollment cancel, waitlist, freeze, status change,
        reschedule, evaluation criteria form).
      - Sidebar nav links had no hover/press states → added hover:bg-white/10
        and active:bg-white/20 + active:scale-[0.97].
      - POS terminal: program cards, quantity +/-, checkout, split-add, mobile
        pay bar all now have active:scale and active:bg-* feedback.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      1e55b9c5
    • Mahmoud Aglan's avatar
      Use branding data and receipt settings in all invoice/print views · 519e8625
      Mahmoud Aglan authored
      Wizard inline invoice and the print/invoice view were using hardcoded
      colors and no logo/branch info. Now they pull from SettingsService:
      logo, primary_color, receipt_footer_text, and branch address/phone.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      519e8625
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
      Additional mobile fixes from parallel agents (forms, lists, reports) · 1b69367d
      Mahmoud Aglan authored
      - Remaining form views: touch-friendly inputs, stacked buttons
      - assignment-list, pricing-rule-list: mobile card layouts
      - visual-schedule-builder: stacked sidebar on mobile
      - reports-page, user-profile: responsive grids and padding
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      1b69367d
    • Mahmoud Aglan's avatar
      Comprehensive mobile-first responsive overhaul of entire UI · 944501f1
      Mahmoud Aglan authored
      - All 96 blade views optimized for mobile (touch targets, responsive
        grids, stacked layouts)
      - Guest/login layout: respects branding CSS vars, touch-friendly inputs
      - Sidebar: RTL-correct mobile slide-in with backdrop blur
      - Topbar: compact mobile layout, overflow actions in user dropdown
      - All list views: dual layout (desktop table + mobile cards)
      - All forms: responsive padding, stacked submit buttons, 44px inputs
      - Attendance: 4-col action grid on mobile for quick marking
      - POS terminal: sticky bottom cart bar, radio card payment methods
      - Dashboard/receptionist: 2x2 stat grids, large action cards
      - app.css: safe-area utilities, print styles, touch min-heights
      - Zero RTL violations (logical properties only: ms/me/ps/pe/start/end)
      - Branding CSS vars respected throughout (--brand-primary etc.)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      944501f1
    • Mahmoud Aglan's avatar
      Add 3% platform fee to wizard invoice + printable invoice on success · f00b5c97
      Mahmoud Aglan authored
      - Invoice now includes service_fee_amount via PlatformFeeService (3% env-configurable)
      - Review step and payment step both show fee breakdown (subtotal + service fee = total)
      - Payment records the full total (including fee), not just the program price
      - Success screen shows a proper printable invoice with items table, totals breakdown,
        payment status badge, and a print button that hides nav/sidebar
      - Stores invoiceId for the computed invoiceForPrint property
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      f00b5c97
    • Mahmoud Aglan's avatar
      Add pre-flight checks to registration wizard — block if critical data missing · c8ba2296
      Mahmoud Aglan authored
      Wizard now checks on mount: active academy, branch, activities, programs
      with groups, and base prices. Shows a clear Arabic error screen instead of
      silently failing at confirm(). Also blocks step 3→4 if no price exists
      for the selected program.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      c8ba2296
    • Mahmoud Aglan's avatar
      Fix invoice creation: type must be 'standard' not 'enrollment' (CHECK constraint) · 28713729
      Mahmoud Aglan authored
      invoices.type only allows: standard, recurring, credit_note, proforma.
      The wizard was passing 'enrollment' which violated the DB constraint,
      causing a silent failure caught by the try/catch.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      28713729
    • Mahmoud Aglan's avatar
      Add membership type (member/non_member) to registration wizard with price differentiation · e8ed93cf
      Mahmoud Aglan authored
      - Step 2 now shows member vs non-member toggle + membership_id field
      - Price resolution checks base_prices.metadata->membership_type first,
        falls back to generic price if no membership-specific price exists
      - Membership type saved to participant record
      - Review step shows membership status
      - Computed property selectedProgramFee updates live when membership changes
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      e8ed93cf
    • Mahmoud Aglan's avatar
      Fix registration wizard: step-skip bug + actual invoice/payment creation · b01d4577
      Mahmoud Aglan authored
      Bugs fixed:
      - Step 2 was skipped: checkDuplicates() advanced step AND nextStep() advanced
        again after it returned. Now nextStep() returns early after checkDuplicates()
      - No invoice was ever created: confirm() now creates a real invoice via
        InvoiceService with the price resolved from base_prices table
      - No payment was ever recorded: now uses PaymentService.recordPayment() which
        creates double-entry transaction and updates invoice paid_amount
      - fee_amount doesn't exist on training_programs — price comes from base_prices
        (polymorphic). Added resolveProgramFee() + selectedProgramFee computed property
      - Success screen now shows: participant number, program, invoice number/amount,
        payment status (paid vs outstanding)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      b01d4577
    • Mahmoud Aglan's avatar
      Tighten receptionist permissions — remove access to financial dashboard, wallets, invoice creation · e8798d13
      Mahmoud Aglan authored
      A receptionist should only:
      - Register participants (wizard)
      - Look up participant info (read-only)
      - Collect payments on existing invoices
      - Sell via POS
      - Open/close their cash session
      
      Removed: invoices.list (gates financial overview), invoices.create,
      wallets.list/view/credit, participants.update, guardians.update,
      enrollments.list, cash_sessions.manage, payments.list,
      pos_sessions.open/close/list
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      e8798d13
    • Mahmoud Aglan's avatar
      Fix receptionist registration wizard — full rewrite of broken business logic · 45a76a04
      Mahmoud Aglan authored
      Problems fixed:
      - MissingRulesException crash on step 4 (empty rules passed to validate())
      - Guardian was never actually created as Person + Guardian record
      - Guardian was never linked to participant via guardian_participant pivot
      - Enrollment in program never happened (service didn't handle program_id)
      - medical_notes was passed at wrong level (it's on people table, not participants)
      - relation 'guardian' missing from validation (exists in DB CHECK constraint)
      
      Now the wizard properly:
      1. Creates guardian Person + Guardian record (or reuses existing)
      2. Creates participant Person record with all fields (phone, national_id, medical_notes)
      3. Creates Participant via ParticipantService with guardian linked
      4. Attaches guardian via guardian_participant pivot
      5. Enrolls in program via EnrollmentService (auto-finds/creates group)
      6. Added participant phone + national_id fields to step 2
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      45a76a04
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
  2. 30 Jun, 2026 23 commits
    • Mahmoud Aglan's avatar
      Fix 3 bugs: participant branch, layout update, receipt branch · 23c68694
      Mahmoud Aglan authored
      1. ParticipantForm: set branch_id from session in mount() so new
         participants get the active branch (was null, invisible in list)
      2. SpaceLayoutService::update: compare config BEFORE updating the model
         so change detection works (was comparing same value to itself)
      3. ReceiptSettings: use session branch_id instead of user->branch_id
         which could be null, preventing template save
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      23c68694
    • Mahmoud Aglan's avatar
      Fix participant import: rename $errors to $importErrors to avoid Livewire conflict · f98f2b2b
      Mahmoud Aglan authored
      Livewire reserves $errors for the validation MessageBag. Using the same
      name as a public property causes a 500 error on render.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      f98f2b2b
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
      Fix dashboard branch scoping: invoices don't have branch_id column · 88148120
      Mahmoud Aglan authored
      Invoices use billable morph (not direct branch_id). Scope through
      whereHasMorph on the participant's branch_id instead.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      88148120
    • Mahmoud Aglan's avatar
      Add reports, admin tools, print views, guardian portal, and 15+ features · 909a0b40
      Mahmoud Aglan authored
      - Financial report with daily revenue chart and top programs
      - Attendance report with per-participant stats and CSV export
      - Activity log viewer with filters and expandable details
      - System settings page with grouped tabs
      - Guardian portal dashboard (children, attendance, invoices)
      - Payment plan creation UI with installment preview
      - Coupon validator component
      - Invoice, group schedule, participant card, and certificate print views
      - Session rescheduling component
      - Participant freeze/unfreeze, bulk status change, status timeline
      - Enrollment history component
      - Dashboard widgets (revenue, enrollment trends)
      - Dark mode toggle, language switcher, locale middleware
      - API stats endpoint for mobile
      - Parent weekly SMS report command
      - Group capacity alert command
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      909a0b40
    • Mahmoud Aglan's avatar
      Add waitlist management, group transfer, quick attendance, import, profile, and more · b4c9f796
      Mahmoud Aglan authored
      New features:
      - Waitlist manager with promote/cancel actions
      - Group transfer (move participant between groups)
      - Quick attendance marking (mobile-friendly trainer view)
      - Participant CSV import with preview and validation
      - User profile page with password change
      - Daily financial report (printable)
      - Reconcile group counts command
      - Deactivate expired enrollments command
      - Overdue invoice reminders (2x weekly)
      - Sidebar navigation updates (waitlist, transfer, quick attendance, import)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      b4c9f796
    • Mahmoud Aglan's avatar
      Add 25+ features: branch scoping, notifications, exports, scheduling, and more · 54175068
      Mahmoud Aglan authored
      Major additions:
      - Branch scoping for all 15 list components via UsesBranchScope trait
      - Payment notification listener (email/SMS on every payment)
      - Print receipt button on POS, payment wizard, and invoice show
      - CSV export for participants, payments, invoices, enrollments
      - Global search in topbar (participants, invoices, groups)
      - Bulk messaging component (SMS/email by group, status, membership)
      - Weekly schedule visual timetable with program/trainer filters
      - Trainer dashboard (today's sessions, assigned groups, attendance links)
      - Duplicate participant detection in registration wizard
      - Enhanced dashboard: today's schedule, overdue invoices, birthdays, recent payments
      - 7 scheduled commands: daily summary, birthdays, low stock, expiring enrollments,
        installment reminders, overdue reminders
      - Health check endpoint (/health)
      - Participant transfer service and group capacity service
      - WhatsApp link helper for quick communication
      - User activity tracking middleware
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      54175068
    • Mahmoud Aglan's avatar
      Add member/non-member pricing fields to program form · 22d54f2b
      Mahmoud Aglan authored
      Prices are stored as base_prices with metadata.membership_type.
      Shows two fields: member price and non-member price (EGP).
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      22d54f2b
    • Mahmoud Aglan's avatar
      Add branch switcher in topbar with session-based branch scoping · 0618b998
      Mahmoud Aglan authored
      - BranchSwitcher component in topbar: select branch or "all branches"
      - UsesBranchScope trait: all components read active branch from session
      - Dashboard/Reports: filter by selected branch, show all when "all"
      - Receptionist wizards: use session branch instead of user->branch_id
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      0618b998
    • Mahmoud Aglan's avatar
      Simplify membership to member/non_member with club membership_id · 4e5b3052
      Mahmoud Aglan authored
      - membership_type now only allows 'member' or 'non_member'
      - Members must provide membership_id (club card number)
      - membership_id is unique per branch (same card can't register twice)
      - Shows membership_id input conditionally when type is 'member'
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      4e5b3052
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
      Add branch_id to participants/payments and fix error page copy button · 977f178d
      Mahmoud Aglan authored
      Participants and payments are now branch-scoped: migration adds nullable
      branch_id FK to both tables, all creation paths (ParticipantForm,
      receptionist wizards, InvoiceShow, POSService) pass branch_id through.
      
      Error page copy button rewritten to use a hidden textarea rendered
      server-side — eliminates JS string escaping issues with multi-line
      error messages and special characters.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      977f178d
    • Mahmoud Aglan's avatar
      Fix receptionist 403 for super admins without branch_id · 596c3ee3
      Mahmoud Aglan authored
      Super admins and academy owners aren't tied to a branch. Instead of
      aborting, fall back to the first active branch so they can still
      access the receptionist desk.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      596c3ee3
    • Mahmoud Aglan's avatar
      Add platform service fee (3%) on all transactions · d35573dd
      Mahmoud Aglan authored
      Revenue model: 3% fee on every POS transaction, shown as "مصاريف خدمة"
      on receipts and invoices. The percentage is controlled ONLY via the
      PLATFORM_SERVICE_FEE_PERCENT env var — not editable by any admin.
      
      - PlatformFeeService: calculates fee from env var (default 3%)
      - POSService: includes service_fee_amount in transaction + invoice total
      - POS terminal UI: shows fee line before grand total
      - Receipt print: displays "مصاريف خدمة" row
      - Invoice show: displays service fee row
      - System settings: read-only banner showing the current fee percentage
      - Migration: adds service_fee_amount column to pos_transactions + invoices
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      d35573dd
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
      Add receipt template system, branch-scoped receptionist, and business logic fixes · c314a847
      Mahmoud Aglan authored
      - Receipt templates: configurable per-branch with field toggles, section ordering,
        and appearance settings (paper width, font size, currency symbol)
      - ReceiptController for printing POS/payment receipts via thermal layout
      - Receipt settings UI (Livewire) under Settings for branch managers
      - Branch-scoped receptionist: all 4 wizards enforce user's branch_id
      - Wallet freeze guard: deposit/withdraw now reject frozen wallets
      - Overdue invoice job: daily command transitions sent→overdue past due_date
      - Session generation scheduler: daily command creates upcoming training sessions
      - Default receipt template created during setup wizard
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      c314a847
    • Mahmoud Aglan's avatar
      Enforce no two groups on same cell, allow trainer overlap · 69cb95b2
      Mahmoud Aglan authored
      - Group-to-group segment overlap is blocked (hard error)
      - Trainer-to-group overlap is allowed (trainers supervise areas)
      - Checks pending unsaved assignments, not just DB reservations
      - Proper Arabic error message explaining the constraint
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      69cb95b2
    • Mahmoud Aglan's avatar
      Add comprehensive conflict detection + flexible time to schedule builder · 4794a02c
      Mahmoud Aglan authored
      ScheduleConflictService checks ALL sources of trainer/group conflicts:
      - TrainingSchedule (recurring weekly assignments)
      - TrainingSession (specific date overrides)
      - TrainingGroup.head_trainer_id (implied trainer commitment)
      - Assignment model (formal polymorphic assignments)
      
      Schedule Builder improvements:
      - Flexible time picker (any minute interval, not just hourly)
      - Trainer availability indicators (green dot = free, orange = busy)
      - Group availability indicators (red warning if scheduled elsewhere)
      - Implied trainer warnings (group's head trainer conflict = soft warning)
      - New vs existing assignments visually distinct (green = unsaved)
      - Trainer name shown on existing reservations
      - Row/column/all selection helpers
      - Recurring booking checks group + trainer + space conflicts per date
      - Cancel series now deactivates the underlying TrainingSchedule
      - Final validation pass before commit (double-check for race conditions)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      4794a02c
    • Mahmoud Aglan's avatar
      Add Visual Schedule Builder for drag-drop facility scheduling · e0119a1d
      Mahmoud Aglan authored
      Full-featured schedule builder with:
      - Facility selection, date navigation, weekly view
      - Hourly time slot grid showing existing reservations
      - Grid/segment view with drag-drop group assignment
      - Trainer drag-drop with overlap support
      - Collision detection via SpaceCollisionService
      - Single-date save and recurring weekly booking (N weeks, multi-day)
      - Cancel single reservation or entire recurring series
      - RTL Arabic-first UI with Alpine.js interactivity
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      e0119a1d
    • Mahmoud Aglan's avatar
      Add financial overview dashboard, enforce setup wizard, fix permission system · 71a6c06f
      Mahmoud Aglan authored
      Financial Overview:
      - New FinancialOverview Livewire component with P&L, break-even gauge,
        facility costs breakdown, revenue sources, collection rate
      - Migration adds monthly_rental_cost to facilities table
      - Monthly cost field added to facility form
      - Sidebar entry under المالية section
      
      Setup Wizard Enforcement:
      - Activities are now mandatory (min 1)
      - Programs are now mandatory with price > 0
      - Facilities are now mandatory with monthly cost field
      - Auto-creates BasePrice records for programs during setup
      - Facility form includes operating hours and monthly cost
      
      Permission System Fix:
      - PermissionSeeder now called from DatabaseSeeder (has correct permission
        names matching route middleware: pos.sell, attendance.mark, etc.)
      - Branch manager gets all relevant module prefixes (inventory, pricing,
        wallets, activities, audit, notifications)
      - Receptionist gets pos.sell, pos.list, cash_sessions.manage
      - Accountant gets reports.view, wallets.view, pricing.list
      - PermissionService falls back to roles() pivot when primaryRole is null
      - SetCurrentAcademy middleware eager-loads roles.permissions as fallback
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      71a6c06f
    • Mahmoud Aglan's avatar
      Add copy-all button to error page for clipboard export · 2fc16d13
      Mahmoud Aglan authored
      Big prominent button copies full error report (exception, stack trace,
      request data, SQL queries, session) as formatted text to clipboard.
      Visual feedback with green check animation on success.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      2fc16d13
    • Mahmoud Aglan's avatar
      Add visual Space Assignment system for groups to facility segments · 40d21535
      Mahmoud Aglan authored
      Features:
      - SpaceLayoutManager: full CRUD for facility layouts (grid/lanes/zones/custom)
        with visual segment preview and toggle availability
      - SpaceAssignmentWizard: 5-step wizard for assigning groups to facility segments
        Step 1: Search and select training group
        Step 2: Choose which schedule slot to assign
        Step 3: Pick the facility (if not already linked)
        Step 4: Visual grid/lane/zone selector with real-time collision detection
        Step 5: Success confirmation
      - Visual grid renders as clickable cells showing available/selected/occupied/disabled states
      - Real-time collision checking against existing confirmed reservations
      - Saves space_reservation_template on TrainingSchedule for auto-reservation on session creation
      - Fix: ReservationService.autoReserveForSession() now uses correct field names
        (space_reservation_template instead of segments, segment_ids instead of segments key)
      - Added "التخطيط" action link in facility list table
      - Added "تعيين المساحات" to sidebar navigation
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      40d21535