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 ...@@ -71,9 +71,26 @@ class CoachAssessmentController extends Controller
$groups = CoachAssessmentService::getAvailableGroups($relevantDisciplineIds); $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', [ return $this->view('SportsActivity.Views.assessment.assess', [
'registration' => $registration, 'registration' => $registration,
'groups' => $groups, 'groups' => $groups,
'programs' => $programs,
'selectedDisciplineIds' => $selectedDisciplineIds, 'selectedDisciplineIds' => $selectedDisciplineIds,
]); ]);
} }
......
...@@ -204,6 +204,7 @@ return [ ...@@ -204,6 +204,7 @@ return [
['GET', '/api/sa/bookings/price-preview', 'SportsActivity\Controllers\Api\BookingApiController@pricePreview', ['auth'], 'sa.booking.view'], ['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'], ['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/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/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/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'], ['GET', '/api/sa/disciplines/list', 'SportsActivity\Controllers\Api\SmartFilterApiController@disciplines', ['auth'], 'sa.group.view'],
......
...@@ -93,59 +93,108 @@ ...@@ -93,59 +93,108 @@
</div> </div>
</div> </div>
<!-- Group Selection by Discipline --> <!-- Program & Group Selection -->
<div class="card" style="margin-bottom:16px;">
<div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;display:flex;align-items:center;gap:8px;">
<i data-lucide="users" style="width:18px;height:18px;color:#0D7377;"></i>
<h3 style="margin:0;color:#0D7377;font-size:15px;">تعيين في مجموعة <span style="color:#DC2626;">*</span></h3>
</div>
<div style="padding:16px;">
<?php <?php
$groupsByDiscipline = []; $programsByDisc = [];
foreach ($groups as $g) { foreach ($programs as $p) {
$dId = (int) ($g['discipline_id'] ?? 0); $dId = (int) ($p['discipline_id'] ?? 0);
$dName = $g['discipline_name'] ?? 'بدون نشاط'; if (!isset($programsByDisc[$dId])) {
if (!isset($groupsByDiscipline[$dId])) { $programsByDisc[$dId] = ['name' => $p['discipline_name'] ?? '', 'programs' => []];
$groupsByDiscipline[$dId] = ['name' => $dName, 'groups' => []]; }
$programsByDisc[$dId]['programs'][] = $p;
} }
$groupsByDiscipline[$dId]['groups'][] = $g; $groupsByProgram = [];
foreach ($groups as $g) {
$pId = (int) ($g['program_id'] ?? 0);
if (!isset($groupsByProgram[$pId])) $groupsByProgram[$pId] = [];
$groupsByProgram[$pId][] = $g;
} }
$playerType = $registration['p_type'] ?? 'non_member';
?> ?>
<?php if (count($groupsByDiscipline) > 1): ?>
<div class="card" style="margin-bottom:16px;">
<div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;display:flex;align-items:center;gap:8px;">
<i data-lucide="layers" style="width:18px;height:18px;color:#0D7377;"></i>
<h3 style="margin:0;color:#0D7377;font-size:15px;">اختيار البرنامج والمجموعة <span style="color:#DC2626;">*</span></h3>
</div>
<div style="padding:16px;">
<!-- Step 1: Discipline Tabs -->
<?php if (count($programsByDisc) > 1): ?>
<div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;"> <div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;">
<?php foreach ($groupsByDiscipline as $dId => $dData): ?> <?php foreach ($programsByDisc as $dId => $dData): ?>
<button type="button" class="disc-tab btn btn-outline" data-disc="<?= $dId ?>" style="padding:8px 16px;font-size:13px;border-radius:8px;"> <button type="button" class="disc-filter-btn btn btn-outline" data-disc-id="<?= $dId ?>" style="padding:8px 16px;font-size:13px;border-radius:8px;">
<?= e($dData['name']) ?> <span style="font-size:11px;color:#6B7280;">(<?= count($dData['groups']) ?>)</span> <?= e($dData['name']) ?>
</button> </button>
<?php endforeach; ?> <?php endforeach; ?>
<button type="button" class="disc-tab btn btn-outline" data-disc="all" style="padding:8px 16px;font-size:13px;border-radius:8px;">الكل</button>
</div> </div>
<?php endif; ?> <?php endif; ?>
<input type="text" id="groupSearch" class="form-input" placeholder="ابحث عن مجموعة..." style="margin-bottom:12px;padding:12px;font-size:14px;border-radius:10px;">
<div style="max-height:400px;overflow-y:auto;display:grid;gap:8px;" id="groupsList"> <!-- Step 2: Program Cards -->
<?php foreach ($groups as $g): ?> <div id="programsList" style="display:grid;gap:10px;margin-bottom:16px;">
<label class="group-radio-option" data-disc-id="<?= (int) ($g['discipline_id'] ?? 0) ?>" data-name="<?= e($g['name_ar'] . ' ' . ($g['discipline_name'] ?? '') . ' ' . ($g['program_name'] ?? '')) ?>" <?php foreach ($programs as $p):
style="display:flex;align-items:center;gap:12px;padding:14px;border:2px solid #E5E7EB;border-radius:10px;cursor:pointer;transition:all 0.2s;"> $pId = (int) $p['id'];
<input type="radio" name="group_id" value="<?= (int) $g['id'] ?>" required style="accent-color:#2563EB;width:20px;height:20px;flex-shrink:0;"> $pGroups = $groupsByProgram[$pId] ?? [];
<div style="flex:1;min-width:0;"> $fee = $playerType === 'member' ? (float) $p['monthly_fee_member'] : (float) $p['monthly_fee_nonmember'];
<div style="font-weight:600;font-size:14px;"><?= e($g['name_ar']) ?></div> ?>
<div style="font-size:12px;color:#6B7280;margin-top:2px;"> <div class="program-card" data-disc-id="<?= (int) $p['discipline_id'] ?>" data-program-id="<?= $pId ?>"
<?= e($g['discipline_name'] ?? '') ?><?= e($g['program_name'] ?? '') ?> style="border:2px solid #E5E7EB;border-radius:12px;padding:14px 16px;cursor:pointer;transition:all 0.2s;"
<?php if (!empty($g['coach_name'])): ?> | مدرب: <?= e($g['coach_name']) ?><?php endif; ?> onclick="selectProgram(this, <?= $pId ?>)">
<div style="display:flex;align-items:center;justify-content:space-between;">
<div>
<div style="font-weight:700;font-size:14px;color:#1A1A2E;"><?= e($p['name_ar']) ?></div>
<div style="font-size:12px;color:#6B7280;margin-top:3px;">
<?= (int) $p['session_duration_minutes'] ?> دقيقة | <?= (int) $p['sessions_per_week'] ?> مرات/أسبوع
| سعة: <?= (int) $p['max_capacity'] ?>
</div> </div>
</div> </div>
<div style="text-align:left;flex-shrink:0;"> <div style="text-align:left;">
<div style="font-size:14px;font-weight:700;color:#059669;"> <div style="font-size:15px;font-weight:700;color:#059669;"><?= number_format($fee, 0) ?> ج.م</div>
<?= number_format(($registration['p_type'] ?? 'non_member') === 'member' ? (float) $g['monthly_fee_member'] : (float) $g['monthly_fee_nonmember'], 0) ?> ج.م <div style="font-size:10px;color:#6B7280;"><?= $playerType === 'member' ? 'عضو' : 'غير عضو' ?></div>
</div>
</div> </div>
<div style="font-size:11px;color:#6B7280;"><?= (int) $g['current_count'] ?>/<?= (int) $g['max_capacity'] ?></div>
</div> </div>
</label>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<!-- Step 3: Groups under selected program -->
<div id="groupsSection" style="display:none;">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;">
<h4 style="margin:0;font-size:14px;color:#374151;"><i data-lucide="users" style="width:16px;height:16px;vertical-align:middle;margin-left:4px;color:#0D7377;"></i> المجموعات المتاحة</h4>
<button type="button" id="btnAddGroup" class="btn btn-outline" style="font-size:12px;padding:6px 12px;border-radius:8px;color:#0D7377;border-color:#0D7377;" onclick="showAddGroupModal()">
<i data-lucide="plus" style="width:14px;height:14px;vertical-align:middle;margin-left:4px;"></i> أضف مجموعة
</button>
</div>
<div id="groupCards" style="display:grid;gap:10px;max-height:350px;overflow-y:auto;">
<!-- Populated by JS -->
</div>
<div id="noGroupsMsg" style="display:none;text-align:center;padding:24px;color:#6B7280;font-size:13px;">
<i data-lucide="inbox" style="width:32px;height:32px;color:#D1D5DB;display:block;margin:0 auto 8px;"></i>
لا توجد مجموعات لهذا البرنامج — أضف مجموعة جديدة
</div>
</div>
</div>
</div>
<!-- Add Group Modal -->
<div id="addGroupModal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.4);z-index:9998;align-items:center;justify-content:center;">
<div style="background:#fff;border-radius:14px;padding:24px;width:90%;max-width:380px;box-shadow:0 20px 60px rgba(0,0,0,0.2);">
<h3 style="margin:0 0 16px;font-size:16px;font-weight:700;color:#1A1A2E;">إضافة مجموعة جديدة</h3>
<div class="form-group" style="margin-bottom:14px;">
<label class="form-label" style="font-size:13px;">اسم المجموعة (اختياري)</label>
<input type="text" id="newGroupName" class="form-input" placeholder="سيتم إنشاء اسم تلقائي إن تُرك فارغاً">
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;">
<button type="button" class="btn btn-outline" onclick="hideAddGroupModal()">إلغاء</button>
<button type="button" class="btn btn-primary" id="btnConfirmAddGroup" onclick="createGroup()">إنشاء</button>
</div>
</div> </div>
</div> </div>
<!-- Hidden data for JS -->
<script id="groupsData" type="application/json"><?= json_encode($groupsByProgram, JSON_UNESCAPED_UNICODE) ?></script>
<script id="playerType" type="application/json"><?= json_encode($playerType) ?></script>
<button type="button" id="btnShowConfirm" class="btn btn-primary" style="width:100%;padding:16px;font-size:16px;font-weight:700;border-radius:12px;"> <button type="button" id="btnShowConfirm" class="btn btn-primary" style="width:100%;padding:16px;font-size:16px;font-weight:700;border-radius:12px;">
<i data-lucide="check-circle" style="width:18px;height:18px;vertical-align:middle;margin-left:6px;"></i> تأكيد التصنيف والتعيين <i data-lucide="check-circle" style="width:18px;height:18px;vertical-align:middle;margin-left:6px;"></i> تأكيد التصنيف والتعيين
</button> </button>
...@@ -181,51 +230,142 @@ ...@@ -181,51 +230,142 @@
</form> </form>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { var groupsData = JSON.parse(document.getElementById('groupsData').textContent);
var playerType = JSON.parse(document.getElementById('playerType').textContent);
var selectedProgramId = null;
var csrfToken = document.querySelector('input[name="_csrf_token"]').value;
function selectProgram(el, programId) {
selectedProgramId = programId;
document.querySelectorAll('.program-card').forEach(function(c) {
c.style.borderColor = '#E5E7EB';
c.style.background = '';
});
el.style.borderColor = '#0D7377';
el.style.background = '#F0FDFA';
renderGroups(programId);
document.getElementById('groupsSection').style.display = '';
if (typeof lucide !== 'undefined') lucide.createIcons(); if (typeof lucide !== 'undefined') lucide.createIcons();
}
function renderGroups(programId) {
var groups = groupsData[programId] || [];
var container = document.getElementById('groupCards');
var noMsg = document.getElementById('noGroupsMsg');
var search = document.getElementById('groupSearch'); if (groups.length === 0) {
var activeDisc = 'all'; container.innerHTML = '';
noMsg.style.display = '';
} else {
noMsg.style.display = 'none';
var html = '';
groups.forEach(function(g) {
var fee = playerType === 'member' ? parseFloat(g.monthly_fee_member) : parseFloat(g.monthly_fee_nonmember);
var pct = g.max_capacity > 0 ? Math.round((g.current_count / g.max_capacity) * 100) : 0;
var barColor = pct >= 90 ? '#DC2626' : pct >= 70 ? '#F59E0B' : '#059669';
var checked = '';
function filterGroups() { html += '<label class="group-radio-option" style="display:block;border:2px solid #E5E7EB;border-radius:12px;padding:14px 16px;cursor:pointer;transition:all 0.2s;">';
var q = (search ? search.value.toLowerCase() : ''); html += '<div style="display:flex;align-items:center;gap:12px;">';
document.querySelectorAll('.group-radio-option').forEach(function(el) { html += '<input type="radio" name="group_id" value="' + g.id + '" required style="accent-color:#2563EB;width:20px;height:20px;flex-shrink:0;" onchange="highlightGroup(this)">';
var matchSearch = !q || el.dataset.name.toLowerCase().indexOf(q) >= 0; html += '<div style="flex:1;min-width:0;">';
var matchDisc = activeDisc === 'all' || el.dataset.discId === activeDisc; html += '<div style="font-weight:600;font-size:14px;">' + esc(g.name_ar) + '</div>';
el.style.display = (matchSearch && matchDisc) ? '' : 'none'; html += '<div style="font-size:12px;color:#6B7280;margin-top:2px;">';
if (g.coach_name) html += 'مدرب: ' + esc(g.coach_name) + ' | ';
html += esc(g.discipline_name || '') + ' — ' + esc(g.program_name || '');
html += '</div>';
html += '</div>';
html += '<div style="text-align:left;flex-shrink:0;">';
html += '<div style="font-size:15px;font-weight:700;color:#059669;">' + fee.toLocaleString() + ' ج.م</div>';
html += '<div style="font-size:11px;color:#6B7280;">' + g.current_count + '/' + g.max_capacity + '</div>';
html += '</div>';
html += '</div>';
// Progress bar
html += '<div style="margin-top:10px;background:#F3F4F6;border-radius:6px;height:6px;overflow:hidden;">';
html += '<div style="height:100%;width:' + pct + '%;background:' + barColor + ';border-radius:6px;transition:width 0.3s;"></div>';
html += '</div>';
html += '<div style="display:flex;justify-content:space-between;margin-top:4px;font-size:10px;color:#9CA3AF;">';
html += '<span>' + pct + '% ممتلئة</span>';
html += '<span>متبقي ' + (g.max_capacity - g.current_count) + ' مكان</span>';
html += '</div>';
html += '</label>';
}); });
container.innerHTML = html;
} }
if (typeof lucide !== 'undefined') lucide.createIcons();
}
if (search) { function highlightGroup(radio) {
search.addEventListener('input', filterGroups); document.querySelectorAll('#groupCards .group-radio-option').forEach(function(el) {
} el.style.borderColor = '#E5E7EB';
el.style.background = '';
});
radio.closest('.group-radio-option').style.borderColor = '#2563EB';
radio.closest('.group-radio-option').style.background = '#F0F7FF';
}
function showAddGroupModal() {
document.getElementById('addGroupModal').style.display = 'flex';
document.getElementById('newGroupName').value = '';
}
document.querySelectorAll('.disc-tab').forEach(function(tab) { function hideAddGroupModal() {
tab.addEventListener('click', function() { document.getElementById('addGroupModal').style.display = 'none';
document.querySelectorAll('.disc-tab').forEach(function(t) { }
t.style.background = '';
t.style.color = ''; function createGroup() {
if (!selectedProgramId) return;
var name = document.getElementById('newGroupName').value.trim();
var btn = document.getElementById('btnConfirmAddGroup');
btn.disabled = true;
btn.textContent = 'جاري الإنشاء...';
fetch('/api/sa/groups/quick-create', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest'},
body: '_csrf_token=' + encodeURIComponent(csrfToken) + '&program_id=' + selectedProgramId + '&name_ar=' + encodeURIComponent(name)
})
.then(function(r) { return r.json(); })
.then(function(data) {
btn.disabled = false;
btn.textContent = 'إنشاء';
if (!data.success) { alert(data.error || 'فشل'); return; }
// Add to local data
if (!groupsData[selectedProgramId]) groupsData[selectedProgramId] = [];
groupsData[selectedProgramId].push(data.group);
renderGroups(selectedProgramId);
hideAddGroupModal();
})
.catch(function() {
btn.disabled = false;
btn.textContent = 'إنشاء';
alert('خطأ في الاتصال');
}); });
}
function esc(s) { var d = document.createElement('div'); d.textContent = s || ''; return d.innerHTML; }
document.addEventListener('DOMContentLoaded', function() {
if (typeof lucide !== 'undefined') lucide.createIcons();
// Discipline filter
document.querySelectorAll('.disc-filter-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
document.querySelectorAll('.disc-filter-btn').forEach(function(b) { b.style.background = ''; b.style.color = ''; });
this.style.background = '#0D7377'; this.style.background = '#0D7377';
this.style.color = '#fff'; this.style.color = '#fff';
activeDisc = this.dataset.disc; var discId = this.dataset.discId;
filterGroups(); document.querySelectorAll('.program-card').forEach(function(c) {
c.style.display = c.dataset.discId === discId ? '' : 'none';
}); });
}); // Hide groups until new program selected
document.getElementById('groupsSection').style.display = 'none';
document.querySelectorAll('input[name="group_id"]').forEach(function(radio) { selectedProgramId = null;
radio.addEventListener('change', function() {
document.querySelectorAll('.group-radio-option').forEach(function(el) {
el.style.borderColor = '#E5E7EB';
el.style.background = '';
});
if (this.checked) {
this.closest('.group-radio-option').style.borderColor = '#2563EB';
this.closest('.group-radio-option').style.background = '#F0F7FF';
}
}); });
}); });
// Skill level highlight
document.querySelectorAll('input[name="skill_level"]').forEach(function(radio) { document.querySelectorAll('input[name="skill_level"]').forEach(function(radio) {
radio.addEventListener('change', function() { radio.addEventListener('change', function() {
document.querySelectorAll('input[name="skill_level"]').forEach(function(r) { document.querySelectorAll('input[name="skill_level"]').forEach(function(r) {
...@@ -237,7 +377,7 @@ document.addEventListener('DOMContentLoaded', function() { ...@@ -237,7 +377,7 @@ document.addEventListener('DOMContentLoaded', function() {
}); });
}); });
// Confirmation overlay logic // Confirmation overlay
var overlay = document.getElementById('confirmOverlay'); var overlay = document.getElementById('confirmOverlay');
var btnShow = document.getElementById('btnShowConfirm'); var btnShow = document.getElementById('btnShowConfirm');
var btnCancel = document.getElementById('btnCancelConfirm'); var btnCancel = document.getElementById('btnCancelConfirm');
...@@ -247,41 +387,34 @@ document.addEventListener('DOMContentLoaded', function() { ...@@ -247,41 +387,34 @@ document.addEventListener('DOMContentLoaded', function() {
var selectedGroup = document.querySelector('input[name="group_id"]:checked'); var selectedGroup = document.querySelector('input[name="group_id"]:checked');
var selectedLevel = document.querySelector('input[name="skill_level"]:checked'); var selectedLevel = document.querySelector('input[name="skill_level"]:checked');
if (!selectedGroup) { if (!selectedProgramId) { alert('اختر البرنامج أولاً'); return; }
alert('اختر مجموعة أولاً'); if (!selectedGroup) { alert('اختر مجموعة أولاً'); return; }
return; if (!selectedLevel) { alert('اختر المستوى أولاً'); return; }
}
if (!selectedLevel) {
alert('اختر المستوى أولاً');
return;
}
var label = selectedGroup.closest('.group-radio-option'); var progCard = document.querySelector('.program-card[data-program-id="' + selectedProgramId + '"]');
var groupName = label.querySelector('div[style*="font-weight:600"]').textContent.trim(); var progName = progCard ? progCard.querySelector('div[style*="font-weight:700"]').textContent.trim() : '';
var infoLine = label.querySelector('div[style*="color:#6B7280"]'); var groupLabel = selectedGroup.closest('.group-radio-option');
var parts = infoLine ? infoLine.textContent.trim().split('—') : ['', '']; var groupName = groupLabel.querySelector('div[style*="font-weight:600"]').textContent.trim();
var discName = (parts[0] || '').trim(); var discEl = groupLabel.querySelector('div[style*="color:#6B7280"]');
var progName = (parts[1] || '').split('|')[0].trim(); var discText = discEl ? discEl.textContent.trim().split('—') : [''];
var amountEl = label.querySelector('div[style*="color:#059669"]'); var amountEl = groupLabel.querySelector('div[style*="color:#059669"]');
var amount = amountEl ? amountEl.textContent.trim() : '—';
document.getElementById('confGroup').textContent = groupName; document.getElementById('confGroup').textContent = groupName;
document.getElementById('confDisc').textContent = discName; document.getElementById('confDisc').textContent = (discText[1] || discText[0] || '').trim().split('|')[0].trim();
document.getElementById('confProg').textContent = progName; document.getElementById('confProg').textContent = progName;
document.getElementById('confLevel').textContent = levelLabels[selectedLevel.value] || selectedLevel.value; document.getElementById('confLevel').textContent = levelLabels[selectedLevel.value] || selectedLevel.value;
document.getElementById('confAmount').textContent = amount; document.getElementById('confAmount').textContent = amountEl ? amountEl.textContent.trim() : '—';
overlay.style.display = 'flex'; overlay.style.display = 'flex';
if (typeof lucide !== 'undefined') lucide.createIcons(); if (typeof lucide !== 'undefined') lucide.createIcons();
}); });
btnCancel.addEventListener('click', function() { btnCancel.addEventListener('click', function() { overlay.style.display = 'none'; });
overlay.style.display = 'none'; overlay.addEventListener('click', function(e) { if (e.target === overlay) overlay.style.display = 'none'; });
});
overlay.addEventListener('click', function(e) { // Auto-select first discipline if only one
if (e.target === overlay) overlay.style.display = 'none'; var discBtns = document.querySelectorAll('.disc-filter-btn');
}); if (discBtns.length === 1) discBtns[0].click();
}); });
</script> </script>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
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