- 05 Jul, 2026 29 commits
-
-
Mahmoud Aglan authored
11 Livewire screens: Home dashboard, Schedule (weekly), Attendance (monthly), Finances (invoice list + detail), Profile, Child Detail (with tabs), Evaluation Detail, Excuse Form, Notifications, and Programs browser. Custom parent layout with fixed bottom nav bar (5 tabs). Redirect parent role login to new portal. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Dashboard: - Primary action (new registration) is now a full-width hero card - Secondary actions are a compact 2x2 icon grid Registration wizard: - Mobile step indicator: compact progress bar + step name instead of cramped 5-circle stepper - Sticky bottom nav bar on mobile (fixed position, safe-area aware) so Back/Next are always reachable without scrolling - Activity selection uses horizontal scrollable pills on mobile - Desktop layout remains unchanged (sm: breakpoint gates all changes) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
New instances and the service fallback now default to the academy paying the platform fee rather than adding it to the client's invoice. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
GroupStatus is a backed enum — need ->value to get the string for __(). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The SystemSettingsForm only displayed settings already in the DB, so platform_fee_customer_pays was invisible. Switched the route to use the schema-driven Admin\SystemSettings component which always renders all defined settings with their defaults. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Quick actions now includes: new registration, enroll existing, collect payment, attendance. Below it a full "Creation Wizards" grid with buttons for every wizard (program, group, transfer, invoice, facility, employee, trainer, pricing rule, product, stock adjustment, cash session, setup). Each button is permission-gated and uses wire:navigate. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- CreateProductWizard: fix permission mismatch (products.create→inventory.create), add SKU uniqueness validation, redirect to list after success instead of dead-end - ProductForm: set branch_id on new products - ProductList: fix dynamic Tailwind classes (use full class strings for JIT) - GroupList: fix dynamic Tailwind status badge classes - POSTerminal: remove dead addProgram() method and unused imports - CSS: add safelist comment for dynamic color classes used via Blade interpolation Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- POS Terminal now shows products tab with addProduct() method (programs are enrolled via receptionist desk, not POS) - Product list and POS show branch products + academy-wide (null branch) - CreateProductWizard and ProductForm now set branch_id on create - Product model gets ManglesUniqueOnDelete for SKU collision prevention - Clicking a product in POS adds it to cart (or increments qty if exists) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Add ManglesUniqueOnDelete trait that appends a timestamp suffix to unique fields (code, slug, sku, employee_number) when a record is soft-deleted, freeing the value for new records. Also make group code generation collision-resistant by checking withTrashed(). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Programs: activate (draft/closed→active), close (active→closed) Groups: activate (forming/on_hold→active), pause (active→on_hold) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- GroupSchedulePrintController used $this->authorize() but Laravel 13's base Controller has no AuthorizesRequests trait — switched to Gate::authorize() - Added deleteGroup() to GroupList with full cascade: sessions (attendance auto-cascades), schedules, enrollments, waitlists, then the group itself - Delete button with wire:confirm for Arabic confirmation prompt, gated behind groups.delete permission Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
1. ProgramForm now passes status to service — programs default 'active' (the property was set but never included in the data array, so the DB default 'draft' won) 2. Receptionist wizard now finds groups with branch_id=NULL (academy-wide programs) alongside branch-specific ones. Previously only exact branch match was checked, hiding programs created without a branch. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Programs with branch_id=NULL are academy-wide — they should be visible regardless of which branch is selected. The filter now uses WHERE branch_id = X OR branch_id IS NULL. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
training_groups.code is NOT NULL — the auto-created default group was missing it, causing a constraint violation. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The seeder was trying to set branch_id on the user, but that column doesn't exist on the users table (it's on participants/payments). Removed the branch assignment and unused Branch import. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The academy identity is now established by the seeder (from ACADEMY_NAME_EN, ACADEMY_NAME_AR env vars). The wizard no longer has an "Academy Profile" step. It starts directly at Branches (step 1) and only configures operational data: branches, activities, programs, facilities, groups, staff, settings. This enforces one-academy-per-instance: the academy exists before the wizard runs, and no user action can create or duplicate it. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
DatabaseSeeder now uses Academy::first() — never creates duplicates. If the wizard already created an academy, the seeder respects it and just ensures the env-var admin user is super_admin on that academy. FinancialAccountsSeeder no longer has a hardcoded 'el-captain' fallback; it skips gracefully if no academy exists yet. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- UsesBranchScope falls back to withoutGlobalScopes if no branch found in current academy - Shows proper error message instead of TypeError when no branch exists - DatabaseSeeder assigns branch_id to admin user on every seed run Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- RolesAndPermissionsSeeder: seed roles for ALL academies (not just hardcoded 'el-captain' slug) - PermissionSeeder: assign permissions to all role instances per slug (across academies) - DatabaseSeeder: look for owner role in user's academy first, always set is_super_admin Root cause: wizard-created academy had different slug than seeder expected, so roles/permissions were never created for it, leaving the admin user with no permissions (403 on dashboard). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Fix setup wizard CHECK violation: tax_percentage type 'number' → 'integer' - Programs now default to 'active' status (not 'draft') - Auto-create first group when program is created via TrainingProgramService - Enable auto_create_groups_enabled setting in wizard for overflow auto-creation Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Reads ADMIN_EMAIL, ADMIN_PASSWORD, ADMIN_NAME, ACADEMY_NAME_EN, ACADEMY_NAME_AR from env — set by the manager during provisioning. Falls back to defaults for dev environments. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- key:generate needs an APP_KEY= line in .env to write to (even empty) - Replace el-captain:setup (doesn't exist) with db:seed Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
CapRover passes env vars as container environment, but Laravel's config:cache reads from .env file. Must dump env to .env first, then generate APP_KEY if missing. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Registration wizard now opens /invoices/{uuid}/print in new tab instead of printing whole page - Print view redesigned: mobile-responsive layout, touch-friendly 48px buttons, proper viewport - Share button (Web Share API) shows on mobile devices that support it - Print-receipt-button component changed from window.open popup to target=_blank link - Added min-height 48px to all action buttons for touch accessibility Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Remove 23 hardcoded business decisions: all financial/operational behaviors now configurable per-academy Every penalty, compensation, auto-invoice, and automation is now guarded by a SettingsService toggle (default OFF for financial, ON for operational). Added 88 system settings across 8 groups with Arabic labels, conditional UI visibility for dependent fields, and a new "رواتب وتعويضات" admin tab. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Money flows: - Payslip paid → double-entry financial transaction (debit salary expense / credit cash) - POS sale → inventory movements for tracked products - Enrollment → auto-invoice via PricingService - Invoice overdue detection enhanced with balance guard Operational events (previously empty → now wired): - AssignmentCreated → generate trainer attendance expectations - AssignmentEnded → remove future trainer attendance - FacilityStatusChanged → cancel reservations on maintenance - PurchaseOrderReceived → create receiving inventory movements - StockCountCompleted → process count adjustments - KitAssembled → deduct component stock - InventoryMovementCreated → check low stock threshold Business rule enforcement: - Medical certificate enforcement at attendance time (configurable) - Group capacity check + auto-waitlist on enrollment - Participant status blocking (frozen/suspended can't enroll) - Attendance threshold from settings (not hardcoded) Dashboard rebuilt with actionable data: - Today's sessions, trainers present, payments, active participants - Needs-attention cards (overdue invoices, pending approvals, expired docs) - Today's schedule with take-attendance buttons - Recent payments feed + quick action buttons Scheduled jobs: - attendance:auto-absent (hourly) - documents:expire (daily 06:00) - payments:detect-defaults (daily 08:00) - attendance:send-alerts (daily 20:00) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Complete trainer compensation lifecycle: - 7 migrations (trainer_compensations, payroll_periods, payslips, payslip_items, trainer_advances, trainer_rate_history + make employee_id nullable for freelancers) - 7 enums, 6 models with proper relationships - CompensationCalculatorService: auto-calculates session/player/revenue/penalty earnings - PayrollService: period management, bulk payslip generation, approval workflow, payment recording - TrainerAdvanceService: salary advance/loan lifecycle with installment tracking - Event listeners: AttendanceMarked → auto-compensation, SessionCancelled → trainer pay - 4 Livewire pages: PayrollDashboard, TrainerCompensations, PayslipDetail, TrainerAdvances - Sidebar navigation + routes with permission middleware Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The layout file lives at resources/views/layouts/app.blade.php, so the correct Livewire attribute is Layout('layouts.app'). 11 components had the wrong path 'components.layouts.app' causing MissingLayoutException. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Expanded from 10 shallow steps to 12 deep steps covering ALL organization data: - Academy profile: phone, email, address, type, website, WhatsApp - Branches: working days (inline toggles), email, city, manager name - Programs: age range (age_min/age_max columns), sessions_per_week, registration fee (separate BasePrice), payment frequency - Facilities: branch selection per facility, visual grid preview - Groups: structured schedule (day + start/end time repeater), segment selection - Participants: classification (on Person), skill_level (on Participant), national_id, medical_notes, collapsible extras - Staff: phone, specialization (creates linked Person for trainers) - NEW Step 9: Financial (tax, invoice/receipt prefix, payment methods, wallet, discounts, family discount, trial period) - NEW Step 10: Policies (attendance grace periods, auto-absent, suspension threshold, medical/guardian requirements, waitlist, freeze days, email/SMS toggles) - Step 11: General settings (currency, timezone, week start, date/time format, pagination) - Step 12: Summary dashboard with stats cards Schema alignment verified: Branch uses operating_hours (not metadata), Person owns classification/medical_notes, Participant owns skill_level, TrainingProgram uses age_min/age_max/sessions_per_week columns directly, all SettingsService keys match SystemSettings schema exactly. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 03 Jul, 2026 4 commits
-
-
Mahmoud Aglan authored
- Seed 78 notification templates (26 events × 3 channels: in_app, email, sms) in Arabic - Create 14 new listeners for previously unwired events (invoice sent/cancelled, wallet deposit/frozen, cash session closed, enrollment completed, session completed, participant registered/status changed/suspended/frozen, evaluation shared, POS receipt) - Wire all listeners in EventServiceProvider - Add PublicDocumentController with signed URL routes for invoices, receipts, and POS receipts - Add PublicLinkHelper for generating 30-day signed URLs - Add 3 standalone RTL Arabic public views (invoice, receipt, pos-receipt) - Update existing listeners (SendInvoiceNotification, SendOverdueReminder, SendPaymentConfirmation) to include public_link/receipt_link variables - Align all listener variable names with template placeholders Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Trainers/head trainers redirect to /trainer dashboard on login - Receptionists redirect to /receptionist dashboard - Guardians (parents) redirect to /guardian dashboard - Financial data (revenue, invoices, payments) only queried if user has 'invoices.list' permission — returns null/empty otherwise - Blade sections wrapped in @can('invoices.list') so even direct URL access shows no sensitive financial info to unauthorized roles Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Setup wizard now covers 10 steps (was 8): - Facilities step includes visual grid layout builder (rows×columns) - New Groups step: create groups with interactive segment multi-select - New Participants step: import existing players with guardian data - completeSetup() creates SpaceLayout + SpaceSegments for each facility grid - Hint encourages max division for scheduling flexibility Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Document system: polymorphic documents table, upload/approve/reject workflow, medical certificate tracking with expiry, system settings toggles, daily expire job. Feature wizards: Employee, Trainer, Program, Group, Facility, Invoice, Product, PricingRule, TransferParticipant, StockAdjustment — all with Arabic UI, step-by-step guided creation, and delegation to existing services. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 02 Jul, 2026 3 commits
-
-
Mahmoud Aglan authored
Arabic-first landing page with pricing, features, about, and contact pages. Includes business model docs and infrastructure capacity planning. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Used by ReceiptService for cashier name on payment receipts. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 01 Jul, 2026 4 commits
-
-
Mahmoud Aglan authored
- enrollInProgram() was called with an array but expects (Participant, TrainingProgram, User, options[]) — would crash at runtime - View referenced $program->fee_amount which doesn't exist on TrainingProgram (prices live in base_prices table) — fees never displayed - Added #[Computed] selectedProgramFee() to resolve price from base_prices - Updated view to use computed property and inline BasePrice query for program list Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
These files were modified locally but never committed, causing production errors (customerPays() method missing, LoginRedirectService not found). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Blade's regex compiler treats literal {{ inside __() strings as directive openings, causing unclosed-paren parse errors. Replaced with single braces in placeholder text. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Livewire 4 dropped support for the legacy get*Property() magic accessor. Migrated all 6 affected components to use the #[Computed] attribute: - NewRegistrationWizard (hotbuyResults, hotbuyTotal, selectedProgram, etc.) - WeeklySchedule (weekDays, timeSlots) - InvoiceCreate (subtotal, total) - InvoiceShow (canCancel, canRecordPayment) - SystemSettings (activeSchema) - NotificationTemplateForm (availableVariables) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-