1. 28 Jul, 2026 7 commits
    • Fares's avatar
      feat(transfers): manual form_number input for child separation · 76ca34c3
      Fares authored
      Instead of auto-generating form_number at execution time, require
      the user to enter it when creating the separation request. Stored
      in transfer_requests.form_number and used during TransferProcessor
      execution. Falls back to auto-generation if empty.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      76ca34c3
    • Fares's avatar
      fix(sa): fix group auto-creation and old() array conversion errors · 772a86ba
      Fares authored
      - Remove non-existent facility_unit_id from sa_groups insert in
        enrollByCoach, add required code column with auto-generated value
      - Guard schedule copy when no source group exists
      - Fix old() helper usage for array fields (additional_coaches) by
        reading directly from session _old_input instead of old() which
        only returns strings
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      772a86ba
    • Fares's avatar
      feat(sa): redesign player assignment with trainer flow and add game pricing type · 140ee3da
      Fares authored
      Redesign the player assignment page with a 3-step guided workflow
      (Sport → Program → Trainer) supporting both trainer-based and
      program-based assignments. Add multi-coach support for groups via
      sa_group_coaches pivot table. Add per-hour/per-game pricing type
      to recreational games.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      140ee3da
    • Fares's avatar
      fix(migration): make Phase_100_002 idempotent to handle pre-existing columns · 46f03bbf
      Fares authored
      The medical_grace_deadline column already exists in the live DB from a
      prior partial run. Converted to a closure-based migration that checks
      information_schema before altering.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      46f03bbf
    • Fares's avatar
      feat(sa): add player assignment page and recreational games module · 641ec646
      Fares authored
      Player Assignment Page (/sa/assignments):
      - General-purpose assignment flow for all disciplines (not just swimming)
      - Filter by discipline and unassigned status
      - Shows player medical status, type, current groups
      - Assign with capacity check, age validation, force-enroll option
      - Registered in sidebar menu with sa.player.assign permission
      
      Recreational Games (/sa/games):
      - Full CRUD for games with type/fee/duration/facility config
      - Game sessions with open/full/in_progress/completed lifecycle
      - Ticket issuance per session with player name, type, fee tracking
      - Session detail view with ticket list and payment status
      - Migration creates sa_games, sa_game_sessions, sa_game_tickets tables
      - Registered in sidebar with sa.game.view/manage permissions
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      641ec646
    • Fares's avatar
      feat(sa): implement medical level, grace period, booking postponement, and mirror recurrence · 2e5488e5
      Fares authored
      - Medical Level (1-3): added to approval flow, saved to players/sa_players/medical_records,
        displayed on player detail page with color-coded badge
      - Medical Grace Period: configurable days (system_config), set on enrollment when
        medical cert is missing, shown in attendance view, cron auto-suspends expired grace
      - Booking Postponement: new postpone method with max 3 attempts, change history table,
        availability check for new slot, UI form on booking detail page
      - Mirror Recurrence: templates now support daily/weekly/biweekly/monthly/custom patterns,
        expandTemplate respects recurrence_type, wizard UI updated with pattern selector
      - Attendance view: grace period deadline shown instead of generic medical warning
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      2e5488e5
    • Fares's avatar
      fix(sa): fix mirror connection error with better error handling · 05172c6e
      Fares authored
      - CSRF token now uses \App\Core\CSRF::token() to ensure it's always
        generated, not raw $_SESSION which could be empty
      - apiPost and loadState now check response.ok before parsing JSON,
        preventing silent failures when server returns 419/500/HTML
      - Error messages now include status code or exception details
      - Added guard for empty SLOTS array (missing operating hours)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      05172c6e
  2. 27 Jul, 2026 5 commits
    • Fares's avatar
      feat(sa): extend facility grid system to all facility types · 26eb4204
      Fares authored
      The zone grid was previously restricted to pool-type facilities only.
      Now any facility can have a grid configured (rows × cols, max 25 each)
      via the create/edit forms. Facilities with grid dimensions get the
      visual grid manager; those without keep the unit-based mirror view.
      
      Changes:
      - Remove facility_type='pool' filter from PoolGridService::getFacility
      - MirrorController routes by grid dimensions instead of facility type
      - Facility create/edit forms now include grid rows/cols fields
      - FacilityController store/update save grid dimensions
      - Facility model fillable updated with grid columns
      - Grid size limit increased from 20 to 25
      - Facility show page adds "الشبكة" button when grid is configured
      - MirrorStateService and SlotAvailabilityService check grid dims
        instead of facility_type for zone booking cross-checks
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      26eb4204
    • Fares's avatar
      fix(sa): improve group player search with status info and treasury button · 858cd3f6
      Fares authored
      - Player search now shows type (member/non-member), medical status, and
        serial number in dropdown results for accurate identification
      - Group player table adds columns for player type and medical status
      - Pending payment players now show a "الخزينة" button linking to cashier
      - Enrollment form stays visible when group is full (uses force-enroll)
      - SearchableSelect prioritizes label field for richer display text
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      858cd3f6
    • Fares's avatar
      fix(swimming): show accurate member/non-member pricing on assignment page · 8d0f495b
      Fares authored
      Display both fee tiers on each group card with the applicable one highlighted
      based on the player's registration type, preventing pricing confusion.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      8d0f495b
    • Fares's avatar
      feat(swimming): add discipline dropdown filter to player assignment page · 2b19960d
      Fares authored
      The assignment page now shows a dropdown to select which sport's programs/groups
      to display. Defaults to Swimming but allows switching to any active discipline.
      Groups are filtered by the selected discipline and show their program names.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      2b19960d
    • Fares's avatar
      fix(sa): fix coach dropdown click bug and auto-create group on program creation · 60d769cf
      Fares authored
      1. searchable-select.js: mouseover was calling renderList() which replaced
         innerHTML and destroyed the click target DOM node, making options unclickable.
         Now mouseover only toggles inline styles without re-rendering.
      
      2. ProgramController: auto-creates a default group (code-G1) when a new program
         is created, using the first available coach for that discipline.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      60d769cf
  3. 26 Jul, 2026 5 commits
  4. 23 Jul, 2026 3 commits
  5. 22 Jul, 2026 20 commits