Commit f55d369e authored by Mahmoud Aglan's avatar Mahmoud Aglan

koko

parent ec2d60d4
...@@ -28,7 +28,7 @@ class PlayerController extends Controller ...@@ -28,7 +28,7 @@ class PlayerController extends Controller
$params = []; $params = [];
if ($search !== '') { if ($search !== '') {
$where[] = '(p.full_name_ar LIKE ? OR p.national_id LIKE ? OR p.serial_number LIKE ?)'; $where[] = '(p.full_name_ar LIKE ? OR p.national_id LIKE ? OR p.registration_serial LIKE ?)';
$params[] = "%{$search}%"; $params[] = "%{$search}%";
$params[] = "%{$search}%"; $params[] = "%{$search}%";
$params[] = "%{$search}%"; $params[] = "%{$search}%";
...@@ -122,17 +122,17 @@ class PlayerController extends Controller ...@@ -122,17 +122,17 @@ class PlayerController extends Controller
return $this->redirect('/sa/players/create'); return $this->redirect('/sa/players/create');
} }
// Generate serial number // Generate registration serial
$lastSerial = $db->selectOne("SELECT serial_number FROM sa_players ORDER BY id DESC LIMIT 1"); $lastSerial = $db->selectOne("SELECT registration_serial FROM sa_players ORDER BY id DESC LIMIT 1");
$nextNum = 1; $nextNum = 1;
if ($lastSerial && !empty($lastSerial['serial_number'])) { if ($lastSerial && !empty($lastSerial['registration_serial'])) {
$parts = explode('-', $lastSerial['serial_number']); $parts = explode('-', $lastSerial['registration_serial']);
$nextNum = (int) end($parts) + 1; $nextNum = (int) end($parts) + 1;
} }
$serialNumber = 'SAP-' . str_pad((string) $nextNum, 5, '0', STR_PAD_LEFT); $serialNumber = 'SAP-' . str_pad((string) $nextNum, 5, '0', STR_PAD_LEFT);
$data = [ $data = [
'serial_number' => $serialNumber, 'registration_serial' => $serialNumber,
'full_name_ar' => $fullNameAr, 'full_name_ar' => $fullNameAr,
'full_name_en' => $fullNameEn ?: null, 'full_name_en' => $fullNameEn ?: null,
'player_type' => $playerType, 'player_type' => $playerType,
...@@ -147,7 +147,7 @@ class PlayerController extends Controller ...@@ -147,7 +147,7 @@ class PlayerController extends Controller
'guardian_national_id' => $guardianNationalId ?: null, 'guardian_national_id' => $guardianNationalId ?: null,
'guardian_relationship' => $guardianRelationship ?: null, 'guardian_relationship' => $guardianRelationship ?: null,
'medical_status' => 'pending', 'medical_status' => 'pending',
'card_status' => 'not_issued', 'card_status' => 'inactive',
'notes' => $notes ?: null, 'notes' => $notes ?: null,
'created_at' => now(), 'created_at' => now(),
'updated_at' => now(), 'updated_at' => now(),
......
...@@ -59,7 +59,7 @@ $__template->layout('Layout.main'); ...@@ -59,7 +59,7 @@ $__template->layout('Layout.main');
<tbody> <tbody>
<?php foreach ($players as $player): ?> <?php foreach ($players as $player): ?>
<tr> <tr>
<td><code style="font-size:12px;"><?= e($player['serial_number'] ?? '') ?></code></td> <td><code style="font-size:12px;"><?= e($player['registration_serial'] ?? '') ?></code></td>
<td> <td>
<a href="/sa/players/<?= (int) $player['id'] ?>" style="text-decoration:none;color:#0D7377;font-weight:600;"> <a href="/sa/players/<?= (int) $player['id'] ?>" style="text-decoration:none;color:#0D7377;font-weight:600;">
<?= e($player['full_name_ar'] ?? '') ?> <?= e($player['full_name_ar'] ?? '') ?>
......
...@@ -32,7 +32,7 @@ $relationLabels = ['father' => 'أب', 'mother' => 'أم', 'brother' => 'أخ', ...@@ -32,7 +32,7 @@ $relationLabels = ['father' => 'أب', 'mother' => 'أم', 'brother' => 'أخ',
<div style="font-size:13px;color:#6B7280;margin-bottom:4px;" dir="ltr"><?= e($player['full_name_en']) ?></div> <div style="font-size:13px;color:#6B7280;margin-bottom:4px;" dir="ltr"><?= e($player['full_name_en']) ?></div>
<?php endif; ?> <?php endif; ?>
<div style="display:flex;gap:8px;flex-wrap:wrap;"> <div style="display:flex;gap:8px;flex-wrap:wrap;">
<code style="font-size:11px;background:#F3F4F6;padding:2px 8px;border-radius:4px;"><?= e($player['serial_number'] ?? '') ?></code> <code style="font-size:11px;background:#F3F4F6;padding:2px 8px;border-radius:4px;"><?= e($player['registration_serial'] ?? '') ?></code>
<?php $mStatus = $player['medical_status'] ?? 'pending'; $mColor = $medColors[$mStatus] ?? '#6B7280'; ?> <?php $mStatus = $player['medical_status'] ?? 'pending'; $mColor = $medColors[$mStatus] ?? '#6B7280'; ?>
<span style="padding:2px 10px;border-radius:10px;font-size:11px;font-weight:600;background:<?= $mColor ?>15;color:<?= $mColor ?>;"><?= e($medLabels[$mStatus] ?? $mStatus) ?></span> <span style="padding:2px 10px;border-radius:10px;font-size:11px;font-weight:600;background:<?= $mColor ?>15;color:<?= $mColor ?>;"><?= e($medLabels[$mStatus] ?? $mStatus) ?></span>
</div> </div>
......
...@@ -222,6 +222,44 @@ class TutorialController extends Controller ...@@ -222,6 +222,44 @@ class TutorialController extends Controller
'scenarios' => ['label' => 'سيناريوهات كاملة', 'icon' => 'play-circle', 'color' => '#6366F1'], 'scenarios' => ['label' => 'سيناريوهات كاملة', 'icon' => 'play-circle', 'color' => '#6366F1'],
]; ];
private const MEMBERSHIP_TUTORIALS = [
'new-member-registration' => ['title' => 'تسجيل عضو جديد', 'subtitle' => 'إنشاء استمارة عضوية من الصفر', 'icon' => 'user-plus', 'color' => '#8B5CF6', 'category' => 'registration', 'order' => 1],
'pay-form-fee' => ['title' => 'دفع رسوم الاستمارة', 'subtitle' => 'إرسال طلب دفع 505 ج.م للخزينة', 'icon' => 'receipt', 'color' => '#059669', 'category' => 'registration', 'order' => 2],
'fill-form' => ['title' => 'ملء استمارة العضوية', 'subtitle' => 'إكمال البيانات الشخصية والمهنية', 'icon' => 'file-text', 'color' => '#3B82F6', 'category' => 'registration', 'order' => 3],
'membership-pricing' => ['title' => 'تسعير العضوية', 'subtitle' => 'حساب قيمة العضوية حسب المؤهل', 'icon' => 'calculator', 'color' => '#F59E0B', 'category' => 'registration', 'order' => 4],
'pay-membership-cash' => ['title' => 'دفع العضوية كاش', 'subtitle' => 'سداد قيمة العضوية دفعة واحدة', 'icon' => 'banknote', 'color' => '#10B981', 'category' => 'financial', 'order' => 5],
'pay-membership-installments' => ['title' => 'دفع العضوية بالتقسيط', 'subtitle' => 'مقدم 25% وتقسيط حتى 30 شهر', 'icon' => 'calendar-range', 'color' => '#06B6D4', 'category' => 'financial', 'order' => 6],
'special-discounts' => ['title' => 'الخصومات الخاصة', 'subtitle' => 'تطبيق خصم خاص أو عرض مجلس الإدارة', 'icon' => 'badge-percent', 'color' => '#EC4899', 'category' => 'financial', 'order' => 7],
'add-spouse' => ['title' => 'إضافة زوج/زوجة', 'subtitle' => 'إضافة زوجة للعضوية مع حساب الرسوم', 'icon' => 'heart', 'color' => '#F97316', 'category' => 'family', 'order' => 8],
'add-child' => ['title' => 'إضافة أبناء', 'subtitle' => 'إضافة أبناء مع التصنيف التلقائي', 'icon' => 'baby', 'color' => '#F59E0B', 'category' => 'family', 'order' => 9],
'add-temporary-member' => ['title' => 'إضافة عضو مؤقت', 'subtitle' => 'والدين أو أشقاء أو مربية', 'icon' => 'user-cog', 'color' => '#6366F1', 'category' => 'family', 'order' => 10],
'children-aging' => ['title' => 'تقادم أعمار الأبناء', 'subtitle' => 'التجميد التلقائي والفصل عند بلوغ 25', 'icon' => 'clock', 'color' => '#DC2626', 'category' => 'family', 'order' => 11],
'interview-process' => ['title' => 'المقابلات', 'subtitle' => 'جدولة وإجراء مقابلة العضوية', 'icon' => 'message-square', 'color' => '#0EA5E9', 'category' => 'procedures', 'order' => 12],
'change-status' => ['title' => 'تغيير حالة العضوية', 'subtitle' => 'دورة الحالات من محتمل حتى فعال', 'icon' => 'refresh-cw', 'color' => '#8B5CF6', 'category' => 'procedures', 'order' => 13],
'annual-subscription' => ['title' => 'الاشتراك السنوي', 'subtitle' => 'توليد وتحصيل الاشتراكات السنوية', 'icon' => 'calendar-check', 'color' => '#059669', 'category' => 'financial', 'order' => 14],
'fines-violations' => ['title' => 'المخالفات والغرامات', 'subtitle' => 'فرض غرامة وتصعيد العقوبات', 'icon' => 'alert-triangle', 'color' => '#DC2626', 'category' => 'procedures', 'order' => 15],
'carnet-issuance' => ['title' => 'إصدار الكارنيه', 'subtitle' => 'شروط وإجراءات طباعة الكارنيه', 'icon' => 'id-card', 'color' => '#3B82F6', 'category' => 'procedures', 'order' => 16],
'transfer-separation' => ['title' => 'فصل الأبناء', 'subtitle' => 'فصل ابن/ابنة لعضوية مستقلة', 'icon' => 'git-branch', 'color' => '#F97316', 'category' => 'transfers', 'order' => 17],
'divorce-transfer' => ['title' => 'تحويل عند الطلاق', 'subtitle' => 'نقل العضوية بعد الطلاق', 'icon' => 'split', 'color' => '#DC2626', 'category' => 'transfers', 'order' => 18],
'death-transfer' => ['title' => 'تحويل عند الوفاة', 'subtitle' => 'نقل العضوية للزوج/الزوجة', 'icon' => 'heart-off', 'color' => '#6B7280', 'category' => 'transfers', 'order' => 19],
'waiver-process' => ['title' => 'التنازل عن العضوية', 'subtitle' => 'تنازل لشخص آخر مع رسوم 30%', 'icon' => 'arrow-right-left', 'color' => '#8B5CF6', 'category' => 'transfers', 'order' => 20],
'membership-freeze-drop' => ['title' => 'التجميد والإسقاط', 'subtitle' => 'تجميد العضوية أو إسقاطها', 'icon' => 'snowflake', 'color' => '#06B6D4', 'category' => 'transfers', 'order' => 21],
'honorary-membership' => ['title' => 'العضوية الشرفية', 'subtitle' => 'عضوية بدون رسوم بقرار مجلس', 'icon' => 'award', 'color' => '#F59E0B', 'category' => 'types', 'order' => 22],
'foreign-membership' => ['title' => 'العضوية الأجنبية', 'subtitle' => 'عضوية لغير المصريين بـ 10,000$', 'icon' => 'globe', 'color' => '#10B981', 'category' => 'types', 'order' => 23],
'athletic-conversion' => ['title' => 'تحويل لاعب لعضو', 'subtitle' => 'تحويل عضوية رياضية لعاملة', 'icon' => 'trophy', 'color' => '#EC4899', 'category' => 'types', 'order' => 24],
'full-new-member-scenario' => ['title' => 'سيناريو كامل: عضو جديد', 'subtitle' => 'من التسجيل حتى استلام الكارنيه', 'icon' => 'play-circle', 'color' => '#6366F1', 'category' => 'scenarios', 'order' => 25],
];
private const MEMBERSHIP_CATEGORIES = [
'registration' => ['label' => 'التسجيل والاستمارة', 'icon' => 'user-plus', 'color' => '#8B5CF6'],
'financial' => ['label' => 'المالي والرسوم', 'icon' => 'banknote', 'color' => '#059669'],
'family' => ['label' => 'التابعين والعائلة', 'icon' => 'users', 'color' => '#F59E0B'],
'procedures' => ['label' => 'الإجراءات', 'icon' => 'clipboard', 'color' => '#3B82F6'],
'transfers' => ['label' => 'التحويل والفصل', 'icon' => 'git-branch','color' => '#F97316'],
'types' => ['label' => 'أنواع العضوية', 'icon' => 'crown', 'color' => '#EC4899'],
'scenarios' => ['label' => 'سيناريوهات كاملة', 'icon' => 'play-circle','color' => '#6366F1'],
];
public function index(Request $request): Response public function index(Request $request): Response
{ {
return $this->view('Tutorials.Views.index', [ return $this->view('Tutorials.Views.index', [
...@@ -233,7 +271,56 @@ class TutorialController extends Controller ...@@ -233,7 +271,56 @@ class TutorialController extends Controller
'color' => '#8B5CF6', 'color' => '#8B5CF6',
'count' => count(self::SA_TUTORIALS), 'count' => count(self::SA_TUTORIALS),
], ],
'membership' => [
'title' => 'شئون العضوية',
'subtitle' => 'التسجيل والرسوم والتحويلات',
'icon' => 'users',
'color' => '#3B82F6',
'count' => count(self::MEMBERSHIP_TUTORIALS),
], ],
],
]);
}
public function membership(Request $request): Response
{
$grouped = [];
foreach (self::MEMBERSHIP_TUTORIALS as $slug => $tutorial) {
$cat = $tutorial['category'];
if (!isset($grouped[$cat])) {
$grouped[$cat] = self::MEMBERSHIP_CATEGORIES[$cat];
$grouped[$cat]['tutorials'] = [];
}
$grouped[$cat]['tutorials'][$slug] = $tutorial;
}
return $this->view('Tutorials.Views.membership.index', [
'categories' => $grouped,
'totalCount' => count(self::MEMBERSHIP_TUTORIALS),
]);
}
public function showMembership(Request $request, string $slug): Response
{
if (!isset(self::MEMBERSHIP_TUTORIALS[$slug])) {
return $this->redirect('/tutorials/membership')->withError('الشرح غير موجود');
}
$tutorial = self::MEMBERSHIP_TUTORIALS[$slug];
$viewFile = 'Tutorials.Views.membership.' . str_replace('-', '_', $slug);
$keys = array_keys(self::MEMBERSHIP_TUTORIALS);
$currentIdx = array_search($slug, $keys);
$prev = $currentIdx > 0 ? $keys[$currentIdx - 1] : null;
$next = $currentIdx < count($keys) - 1 ? $keys[$currentIdx + 1] : null;
return $this->view($viewFile, [
'tutorial' => $tutorial,
'slug' => $slug,
'prevSlug' => $prev,
'nextSlug' => $next,
'prevTitle' => $prev ? self::MEMBERSHIP_TUTORIALS[$prev]['title'] : null,
'nextTitle' => $next ? self::MEMBERSHIP_TUTORIALS[$next]['title'] : null,
]); ]);
} }
......
...@@ -5,4 +5,6 @@ return [ ...@@ -5,4 +5,6 @@ return [
['GET', '/tutorials', 'Tutorials\Controllers\TutorialController@index', ['auth'], 'tutorials.view'], ['GET', '/tutorials', 'Tutorials\Controllers\TutorialController@index', ['auth'], 'tutorials.view'],
['GET', '/tutorials/sports-activity', 'Tutorials\Controllers\TutorialController@sportsActivity', ['auth'], 'tutorials.view'], ['GET', '/tutorials/sports-activity', 'Tutorials\Controllers\TutorialController@sportsActivity', ['auth'], 'tutorials.view'],
['GET', '/tutorials/sports-activity/{slug}', 'Tutorials\Controllers\TutorialController@show', ['auth'], 'tutorials.view'], ['GET', '/tutorials/sports-activity/{slug}', 'Tutorials\Controllers\TutorialController@show', ['auth'], 'tutorials.view'],
['GET', '/tutorials/membership', 'Tutorials\Controllers\TutorialController@membership', ['auth'], 'tutorials.view'],
['GET', '/tutorials/membership/{slug}', 'Tutorials\Controllers\TutorialController@showMembership', ['auth'], 'tutorials.view'],
]; ];
<?php $__template->layout('Layout.main'); ?>
<?php $__template->section('title'); ?>شروحات شئون العضوية<?php $__template->endSection(); ?>
<?php $__template->section('styles'); ?>
<style>
.tut-hero { text-align:center; margin-bottom:36px; padding:30px 20px; background:linear-gradient(135deg,#3B82F610,#6366F108); border-radius:20px; border:1px solid #3B82F620; }
.tut-hero-icon { width:64px;height:64px;background:linear-gradient(135deg,#3B82F6,#6366F1);border-radius:16px;display:inline-flex;align-items:center;justify-content:center;margin-bottom:14px; }
.tut-category { margin-bottom:32px; }
.tut-category-header { display:flex;align-items:center;gap:12px;margin-bottom:14px;padding-bottom:10px;border-bottom:2px solid #F3F4F6; }
.tut-category-icon { width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center; }
.tut-category-label { font-size:17px;font-weight:700;color:#1A1A2E; }
.tut-grid { display:grid;grid-template-columns:repeat(auto-fill, minmax(280px, 1fr));gap:14px; }
.tut-card { display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:12px;border:1px solid #E5E7EB;background:#fff;text-decoration:none;color:inherit;transition:all .15s ease; }
.tut-card:hover { border-color:var(--card-color);box-shadow:0 4px 12px rgba(0,0,0,.06);transform:translateY(-1px); }
.tut-card-icon { width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0; }
.tut-card-title { font-size:14px;font-weight:600;color:#1A1A2E;margin:0 0 2px; }
.tut-card-sub { font-size:12px;color:#6B7280;margin:0; }
.tut-card-num { font-size:11px;font-weight:700;color:#fff;background:var(--card-color);width:22px;height:22px;border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0; }
.tut-breadcrumb { display:flex;align-items:center;gap:8px;margin-bottom:20px;font-size:13px; }
.tut-breadcrumb a { color:#6B7280;text-decoration:none; }
.tut-breadcrumb a:hover { color:#8B5CF6; }
.tut-breadcrumb span { color:#9CA3AF; }
</style>
<?php $__template->endSection(); ?>
<?php $__template->section('content'); ?>
<div style="max-width:1000px;margin:0 auto;">
<div class="tut-breadcrumb">
<a href="/tutorials"><i data-lucide="graduation-cap" style="width:14px;height:14px;"></i></a>
<span>/</span>
<span style="color:#1A1A2E;font-weight:600;">شئون العضوية</span>
</div>
<div class="tut-hero">
<div class="tut-hero-icon">
<i data-lucide="users" style="width:32px;height:32px;color:#fff;"></i>
</div>
<h2 style="font-size:24px;font-weight:800;color:#1A1A2E;margin:0 0 6px;">شروحات شئون العضوية</h2>
<p style="font-size:14px;color:#6B7280;margin:0;"><?= (int) $totalCount ?> شرح تفصيلي يغطي كل العمليات من التسجيل حتى التحويلات</p>
</div>
<?php $num = 1; foreach ($categories as $catKey => $cat): ?>
<div class="tut-category">
<div class="tut-category-header">
<div class="tut-category-icon" style="background:<?= e($cat['color']) ?>15;">
<i data-lucide="<?= e($cat['icon']) ?>" style="width:18px;height:18px;color:<?= e($cat['color']) ?>;"></i>
</div>
<span class="tut-category-label"><?= e($cat['label']) ?></span>
<span style="font-size:12px;color:#9CA3AF;margin-right:auto;"><?= count($cat['tutorials']) ?> شرح</span>
</div>
<div class="tut-grid">
<?php foreach ($cat['tutorials'] as $slug => $tut): ?>
<a href="/tutorials/membership/<?= e($slug) ?>" class="tut-card" style="--card-color:<?= e($tut['color']) ?>;">
<div class="tut-card-num" style="background:<?= e($tut['color']) ?>;"><?= $num ?></div>
<div class="tut-card-icon" style="background:<?= e($tut['color']) ?>12;">
<i data-lucide="<?= e($tut['icon']) ?>" style="width:20px;height:20px;color:<?= e($tut['color']) ?>;"></i>
</div>
<div style="flex:1;min-width:0;">
<p class="tut-card-title"><?= e($tut['title']) ?></p>
<p class="tut-card-sub"><?= e($tut['subtitle']) ?></p>
</div>
<i data-lucide="chevron-left" style="width:16px;height:16px;color:#D1D5DB;flex-shrink:0;"></i>
</a>
<?php $num++; endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<script>document.addEventListener('DOMContentLoaded', function() { if (typeof lucide !== 'undefined') lucide.createIcons(); });</script>
<?php $__template->endSection(); ?>
...@@ -14,6 +14,7 @@ MenuRegistry::register('tutorials', [ ...@@ -14,6 +14,7 @@ MenuRegistry::register('tutorials', [
'order' => 990, 'order' => 990,
'children' => [ 'children' => [
['label_ar' => 'النشاط الرياضي', 'label_en' => 'Sports Activity', 'route' => '/tutorials/sports-activity', 'permission' => 'tutorials.view', 'order' => 1], ['label_ar' => 'النشاط الرياضي', 'label_en' => 'Sports Activity', 'route' => '/tutorials/sports-activity', 'permission' => 'tutorials.view', 'order' => 1],
['label_ar' => 'شئون العضوية', 'label_en' => 'Membership', 'route' => '/tutorials/membership', 'permission' => 'tutorials.view', 'order' => 2],
], ],
]); ]);
......
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