Commit e695c32c authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat(sports): redesign classification page — program-first flow with inline group creation

- Classification now shows: Discipline tabs → Program cards → Groups
- Each group card shows progress bar (capacity %), coach, price, remaining slots
- "Add Group" button creates a new group inline via API without leaving the page
- New API: POST /api/sa/groups/quick-create for inline group creation
- Controller now passes programs data to the view
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 01da9b94
<?php
declare(strict_types=1);
namespace App\Modules\SportsActivity\Controllers\Api;
use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
class GroupQuickCreateApiController extends Controller
{
public function create(Request $request): Response
{
$db = App::getInstance()->db();
$employee = App::getInstance()->currentEmployee();
$programId = (int) $request->post('program_id', 0);
$nameAr = trim((string) $request->post('name_ar', ''));
if ($programId < 1) {
return $this->json(['success' => false, 'error' => 'البرنامج مطلوب']);
}
$program = $db->selectOne(
"SELECT p.id, p.name_ar, p.max_capacity, p.discipline_id, d.name_ar as discipline_name
FROM sa_programs p LEFT JOIN sa_disciplines d ON d.id = p.discipline_id
WHERE p.id = ? AND p.is_active = 1",
[$programId]
);
if (!$program) {
return $this->json(['success' => false, 'error' => 'البرنامج غير موجود']);
}
if ($nameAr === '') {
$count = (int) ($db->selectOne(
"SELECT COUNT(*) as c FROM sa_groups WHERE program_id = ?",
[$programId]
)['c'] ?? 0);
$nameAr = $program['name_ar'] . ' — مجموعة ' . ($count + 1);
}
$code = 'GRP-' . strtoupper(substr(md5((string) microtime(true)), 0, 6));
$groupId = $db->insert('sa_groups', [
'code' => $code,
'name_ar' => $nameAr,
'program_id' => $programId,
'coach_id' => null,
'max_capacity' => (int) ($program['max_capacity'] ?? 20),
'current_count' => 0,
'is_full' => 0,
'status' => 'active',
'is_archived' => 0,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'created_by' => $employee ? (int) $employee->id : null,
]);
return $this->json([
'success' => true,
'group' => [
'id' => $groupId,
'name_ar' => $nameAr,
'code' => $code,
'program_id' => $programId,
'program_name' => $program['name_ar'],
'discipline_name' => $program['discipline_name'] ?? '',
'max_capacity' => (int) ($program['max_capacity'] ?? 20),
'current_count' => 0,
],
]);
}
}
......@@ -71,9 +71,26 @@ class CoachAssessmentController extends Controller
$groups = CoachAssessmentService::getAvailableGroups($relevantDisciplineIds);
$db2 = App::getInstance()->db();
$programs = [];
if (!empty($relevantDisciplineIds)) {
$ph = implode(',', array_fill(0, count($relevantDisciplineIds), '?'));
$programs = $db2->select(
"SELECT p.id, p.code, p.name_ar, p.monthly_fee_member, p.monthly_fee_nonmember,
p.session_duration_minutes, p.sessions_per_week, p.max_capacity,
d.id as discipline_id, d.name_ar as discipline_name
FROM sa_programs p
LEFT JOIN sa_disciplines d ON d.id = p.discipline_id
WHERE p.discipline_id IN ({$ph}) AND p.is_active = 1 AND p.is_archived = 0
ORDER BY d.name_ar, p.name_ar",
array_map('intval', $relevantDisciplineIds)
);
}
return $this->view('SportsActivity.Views.assessment.assess', [
'registration' => $registration,
'groups' => $groups,
'programs' => $programs,
'selectedDisciplineIds' => $selectedDisciplineIds,
]);
}
......
......@@ -204,6 +204,7 @@ return [
['GET', '/api/sa/bookings/price-preview', 'SportsActivity\Controllers\Api\BookingApiController@pricePreview', ['auth'], 'sa.booking.view'],
['GET', '/api/sa/players/search', 'SportsActivity\Controllers\Api\PlayerSearchApiController@search', ['auth'], 'sa.player.view'],
['POST', '/api/sa/member-lookup', 'SportsActivity\Controllers\Api\MemberLookupApiController@lookup', ['auth', 'csrf'], null],
['POST', '/api/sa/groups/quick-create', 'SportsActivity\Controllers\Api\GroupQuickCreateApiController@create', ['auth', 'csrf'], 'sa.group.manage'],
['GET', '/api/sa/groups/search', 'SportsActivity\Controllers\Api\SmartFilterApiController@groups', ['auth'], 'sa.group.view'],
['GET', '/api/sa/coaches/search', 'SportsActivity\Controllers\Api\SmartFilterApiController@coaches', ['auth'], 'sa.group.view'],
['GET', '/api/sa/disciplines/list', 'SportsActivity\Controllers\Api\SmartFilterApiController@disciplines', ['auth'], 'sa.group.view'],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment