From a551ca538ed82e6e626b8012599d0c4df2c2a130 Mon Sep 17 00:00:00 2001 From: sampanna Date: Wed, 10 Jun 2026 18:02:17 +0545 Subject: [PATCH] country + status added and other changes --- app/Http/Controllers/CommentController.php | 3 +- app/Http/Controllers/HomeController.php | 69 ++- .../Controllers/RegistrationController.php | 70 ++- app/Http/Controllers/ScoreboardController.php | 27 +- app/Models/Country.php | 16 + app/Models/Registration.php | 7 + ...26_06_10_104707_create_countries_table.php | 30 ++ ...ries_and_status_to_registrations_table.php | 30 ++ database/seeders/DatabaseSeeder.php | 11 +- database/seeders/countries_seeder.php | 309 +++++++++++++ resources/views/dashboard/admin.blade.php | 80 +++- resources/views/dashboard/counselor.blade.php | 435 ++++++++++++------ resources/views/layouts/master.blade.php | 7 + resources/views/registrations.blade.php | 431 +++++++++++++++-- resources/views/scoreboard.blade.php | 150 +++--- routes/web.php | 4 +- 16 files changed, 1386 insertions(+), 293 deletions(-) create mode 100644 app/Models/Country.php create mode 100644 database/migrations/2026_06_10_104707_create_countries_table.php create mode 100644 database/migrations/2026_06_10_104953_add_countries_and_status_to_registrations_table.php create mode 100644 database/seeders/countries_seeder.php diff --git a/app/Http/Controllers/CommentController.php b/app/Http/Controllers/CommentController.php index ee1c61c..da69aae 100644 --- a/app/Http/Controllers/CommentController.php +++ b/app/Http/Controllers/CommentController.php @@ -19,7 +19,8 @@ class CommentController extends Controller 'comment' => $c->comment, 'author' => auth()->user()->name, 'created_at_human' => $c->created_at->diffForHumans(), - ]); + ]) + ->values(); // ← add this return response()->json(['comments' => $comments]); } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 0825bb9..d52156f 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -2,26 +2,28 @@ namespace App\Http\Controllers; +use App\Models\Country; use App\Models\Registration; use Carbon\Carbon; use Illuminate\Http\Request; class HomeController extends Controller { - public function index() + public function index(Request $request) { $user = auth()->user(); return match ($user->role) { - 'admin' => $this->adminDashboard(), - 'counselor' => $this->counselorDashboard(), + 'admin' => $this->adminDashboard($request), + 'counselor' => $this->counselorDashboard($request), default => abort(403, 'Unauthorized action.'), }; } - public function adminDashboard() + public function adminDashboard(Request $request) { - $today = Carbon::today(); + $today = Carbon::today(); + $search = trim($request->input('search', '')); $query = Registration::with([ 'sessions' => function ($q) use ($today) { @@ -30,16 +32,21 @@ class HomeController extends Controller ]) ->whereHas('sessions', function ($q) use ($today) { $q->whereDate('play_date', $today); - }) - ->orderBy('created_at', 'desc') - ->paginate(10); + }); + + if ($search) { + $query->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('phone', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%"); + }); + } + + $query = $query->orderBy('created_at', 'desc')->paginate(10)->withQueryString(); $registrations = $query->getCollection()->map(function ($student) { - $todaySession = $student->sessions->first(); - - $todayGoals = null; - + $todayGoals = null; if ($todaySession) { $todayGoals = $todaySession->shots ->sortBy('shot_number') @@ -47,7 +54,6 @@ class HomeController extends Controller ->values() ->toArray(); } - return [ 'id' => $student->id, 'name' => $student->name, @@ -56,41 +62,51 @@ class HomeController extends Controller 'today_goals' => $todayGoals, 'total_score' => $student->total_score, 'session_id' => $todaySession?->id, + 'country_id' => $student->country_id, ]; }); $query->setCollection($registrations); $data['registrations'] = $query; + $data['search'] = $search; $data['total'] = Registration::count(); $data['played'] = $registrations->filter(fn($r) => !empty($r['today_goals']) && count($r['today_goals']) >= 3)->count(); $data['topScore'] = $registrations->max('total_score') ?? 0; + $data['countries'] = Country::where('status', 1)->orderBy('title')->get(['id','title','country_flag']); return view('dashboard.admin', $data); } - public function counselorDashboard() + public function counselorDashboard(Request $request) { - $today = Carbon::today(); + $today = Carbon::today(); + $search = trim($request->input('search', '')); $query = Registration::with([ 'sessions' => function ($q) use ($today) { $q->whereDate('play_date', $today)->with('shots'); }, - 'comments' + 'comments', + 'country' ]) ->whereHas('sessions', function ($q) use ($today) { $q->whereDate('play_date', $today); - }) - ->orderBy('created_at', 'desc') - ->paginate(10); + }); + + if ($search) { + $query->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('phone', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%"); + }); + } + + $query = $query->orderBy('created_at', 'desc')->paginate(10)->withQueryString(); $registrations = $query->getCollection()->map(function ($student) { - $todaySession = $student->sessions->first(); - - $todayGoals = null; - + $todayGoals = null; if ($todaySession) { $todayGoals = $todaySession->shots ->sortBy('shot_number') @@ -98,7 +114,6 @@ class HomeController extends Controller ->values() ->toArray(); } - return [ 'id' => $student->id, 'name' => $student->name, @@ -107,6 +122,10 @@ class HomeController extends Controller 'today_goals' => $todayGoals, 'total_score' => $student->total_score, 'session_id' => $todaySession?->id, + 'country_id' => $student->country_id, + 'country_title' => $student->country?->title ?? '', // add + 'country_flag' => $student->country?->country_flag ?? '', // add + 'status' => $student->status ?? 'warm', // add if not there 'comment_count' => $student->comments->count(), ]; }); @@ -114,9 +133,11 @@ class HomeController extends Controller $query->setCollection($registrations); $data['registrations'] = $query; + $data['search'] = $search; $data['total'] = Registration::count(); $data['played'] = $registrations->filter(fn($r) => !empty($r['today_goals']) && count($r['today_goals']) >= 3)->count(); $data['topScore'] = $registrations->max('total_score') ?? 0; + $data['countries'] = Country::where('status', 1)->orderBy('title')->get(['id','title','country_flag']); return view('dashboard.counselor', $data); } diff --git a/app/Http/Controllers/RegistrationController.php b/app/Http/Controllers/RegistrationController.php index e3b9615..b7d5a38 100644 --- a/app/Http/Controllers/RegistrationController.php +++ b/app/Http/Controllers/RegistrationController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Models\Country; use App\Models\GameSession; use App\Models\GameShot; use App\Models\Registration; @@ -10,13 +11,28 @@ use Illuminate\Support\Facades\Cache; class RegistrationController extends Controller { - public function index() + public function index(Request $request) { - $registrations = Registration::orderBy('id', 'desc')->paginate(20); + $search = trim($request->input('search', '')); - return view('registrations', compact('registrations')); + $query = Registration::with(['sessions.shots', 'comments']); + + if ($search) { + $query->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('phone', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%"); + }); + } + + $registrations = $query->orderBy('id', 'desc')->paginate(20)->withQueryString(); + + $data['registrations'] = $registrations; + $data['search'] = $search; + $data['countries'] = Country::where('status', 1)->orderBy('title')->get(['id','title','country_flag']); + + return view('registrations', $data); } - public function create() { return view('registrations.create'); @@ -311,5 +327,51 @@ class RegistrationController extends Controller return view('leaderboard', $data); } + + public function history($id) + { + $reg = Registration::with(['sessions.shots'])->findOrFail($id); + + $sessions = $reg->sessions + ->sortByDesc('play_date') + ->map(fn($s) => [ + 'date' => $s->play_date, + 'score' => $s->score, + 'shots' => $s->shots->sortBy('shot_number')->map(fn($sh) => (bool)$sh->result)->values(), + ])->values(); + + return response()->json(['sessions' => $sessions]); + } + + public function updateCountry(Request $request, $id) + { + $request->validate([ + 'country_id' => 'required|exists:countries,id', + ]); + + $registration = Registration::findOrFail($id); + $registration->update(['country_id' => $request->country_id]); + + return response()->json([ + 'status' => 'ok', + 'country_id' => $registration->country_id, + 'country_name' => $registration->country->title, + ]); + } + + public function updateStatus(Request $request, $id) + { + $request->validate([ + 'status' => 'required|in:hot,warm,cold', + ]); + + $registration = Registration::findOrFail($id); + $registration->update(['status' => $request->status]); + + return response()->json([ + 'status' => 'ok', + 'value' => $registration->status, + ]); + } } \ No newline at end of file diff --git a/app/Http/Controllers/ScoreboardController.php b/app/Http/Controllers/ScoreboardController.php index 979513b..b772c59 100644 --- a/app/Http/Controllers/ScoreboardController.php +++ b/app/Http/Controllers/ScoreboardController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use App\Models\Registration; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; class ScoreboardController extends Controller { @@ -15,34 +16,41 @@ class ScoreboardController extends Controller public function select(Request $request) { $request->validate(['registration_id' => 'required|exists:registrations,id']); - session(['scoreboard_player_id' => $request->registration_id]); + Cache::put('scoreboard_selected_player', $request->registration_id, now()->endOfDay()); return response()->json(['status' => 'ok']); } public function state() { - $id = session('scoreboard_player_id'); + $id = Cache::get('scoreboard_selected_player'); if (!$id) { return response()->json(['player' => null, 'leaderboard' => $this->leaderboard()]); } $reg = Registration::with([ - 'sessions' => fn($q) => $q->whereDate('play_date', today())->with('shots') + 'sessions' => fn($q) => $q->orderByDesc('play_date')->with('shots') ])->findOrFail($id); - $todaySession = $reg->sessions->first(); + $todaySession = $reg->sessions->firstWhere('play_date', today()->toDateString()); $shots = $todaySession ? $todaySession->shots->sortBy('shot_number')->map(fn($s) => (bool)$s->result)->values()->toArray() : []; + $history = $reg->sessions->map(fn($s) => [ + 'date' => $s->play_date, + 'score' => $s->score, + 'shots' => $s->shots->sortBy('shot_number')->map(fn($sh) => (bool)$sh->result)->values()->toArray(), + ])->toArray(); + return response()->json([ 'player' => [ - 'id' => $reg->id, - 'name' => $reg->name, - 'total_score' => $reg->total_score, - 'shots' => $shots, + 'id' => $reg->id, + 'name' => $reg->name, + 'total_score' => $reg->total_score, + 'shots' => $shots, 'session_score' => $todaySession?->calculateScore() ?? 0, + 'history' => $history, ], 'leaderboard' => $this->leaderboard(), ]); @@ -55,9 +63,10 @@ class ScoreboardController extends Controller ->get(['id', 'name', 'total_score']) ->map(fn($r, $i) => [ 'rank' => $i + 1, + 'id' => $r->id, 'name' => $r->name, 'total_score' => $r->total_score, ]) ->toArray(); } -} +} \ No newline at end of file diff --git a/app/Models/Country.php b/app/Models/Country.php new file mode 100644 index 0000000..8723e59 --- /dev/null +++ b/app/Models/Country.php @@ -0,0 +1,16 @@ +hasMany(Registration::class); + } +} + diff --git a/app/Models/Registration.php b/app/Models/Registration.php index 09b351f..40f98d6 100644 --- a/app/Models/Registration.php +++ b/app/Models/Registration.php @@ -10,6 +10,8 @@ class Registration extends Model 'name', 'email', 'phone', + 'country_id', + 'status', 'total_score', ]; @@ -31,6 +33,11 @@ class Registration extends Model return $this->hasMany(Comment::class); } + public function country() + { + return $this->belongsTo(\App\Models\Country::class); + } + /* |--------------------------- | Helper methods diff --git a/database/migrations/2026_06_10_104707_create_countries_table.php b/database/migrations/2026_06_10_104707_create_countries_table.php new file mode 100644 index 0000000..bef9a13 --- /dev/null +++ b/database/migrations/2026_06_10_104707_create_countries_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('title'); + $table->string('country_flag')->nullable(); + $table->boolean('status')->default(true); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('countries'); + } +}; diff --git a/database/migrations/2026_06_10_104953_add_countries_and_status_to_registrations_table.php b/database/migrations/2026_06_10_104953_add_countries_and_status_to_registrations_table.php new file mode 100644 index 0000000..43c478d --- /dev/null +++ b/database/migrations/2026_06_10_104953_add_countries_and_status_to_registrations_table.php @@ -0,0 +1,30 @@ +unsignedBigInteger('country_id')->nullable(); + $table->enum('status', ['hot', 'warm', 'cold'])->default('warm'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('registrations', function (Blueprint $table) { + $table->dropColumn(['country_id', 'status']); + }); + + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 6b901f8..82591c3 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -15,11 +15,14 @@ class DatabaseSeeder extends Seeder */ public function run(): void { + $this->call([ + countries_seeder::class, + ]); // User::factory(10)->create(); - User::factory()->create([ - 'name' => 'Test User', - 'email' => 'test@example.com', - ]); + // User::factory()->create([ + // 'name' => 'Test User', + // 'email' => 'test@example.com', + // ]); } } diff --git a/database/seeders/countries_seeder.php b/database/seeders/countries_seeder.php new file mode 100644 index 0000000..24018df --- /dev/null +++ b/database/seeders/countries_seeder.php @@ -0,0 +1,309 @@ +truncate(); + + DB::table('countries')->insert([ + [ + 'id' => 1, + 'title' => 'United States', + 'country_flag' => 'https://flagcdn.com/w80/us.png', + 'status' => 1, + ], + [ + 'id' => 2, + 'title' => 'Mexico', + 'country_flag' => 'https://flagcdn.com/w80/mx.png', + 'status' => 1, + ], + [ + 'id' => 3, + 'title' => 'Canada', + 'country_flag' => 'https://flagcdn.com/w80/ca.png', + 'status' => 1, + ], + [ + 'id' => 4, + 'title' => 'Japan', + 'country_flag' => 'https://flagcdn.com/w80/jp.png', + 'status' => 1, + ], + [ + 'id' => 5, + 'title' => 'Iran', + 'country_flag' => 'https://flagcdn.com/w80/ir.png', + 'status' => 1, + ], + [ + 'id' => 6, + 'title' => 'South Korea', + 'country_flag' => 'https://flagcdn.com/w80/kr.png', + 'status' => 1, + ], + [ + 'id' => 7, + 'title' => 'Australia', + 'country_flag' => 'https://flagcdn.com/w80/au.png', + 'status' => 1, + ], + [ + 'id' => 8, + 'title' => 'Saudi Arabia', + 'country_flag' => 'https://flagcdn.com/w80/sa.png', + 'status' => 1, + ], + [ + 'id' => 9, + 'title' => 'Qatar', + 'country_flag' => 'https://flagcdn.com/w80/qa.png', + 'status' => 1, + ], + [ + 'id' => 10, + 'title' => 'Uzbekistan', + 'country_flag' => 'https://flagcdn.com/w80/uz.png', + 'status' => 1, + ], + [ + 'id' => 11, + 'title' => 'Jordan', + 'country_flag' => 'https://flagcdn.com/w80/jo.png', + 'status' => 1, + ], + [ + 'id' => 12, + 'title' => 'Iraq', + 'country_flag' => 'https://flagcdn.com/w80/iq.png', + 'status' => 1, + ], + [ + 'id' => 13, + 'title' => 'Argentina', + 'country_flag' => 'countries/ZQLg2ALI9Ez25ZqiFA2u5LRox2lmn66MOkr9Ywqr.png', + 'status' => 1, + ], + [ + 'id' => 14, + 'title' => 'Brazil', + 'country_flag' => 'https://flagcdn.com/w80/br.png', + 'status' => 1, + ], + [ + 'id' => 15, + 'title' => 'Uruguay', + 'country_flag' => 'https://flagcdn.com/w80/uy.png', + 'status' => 1, + ], + [ + 'id' => 16, + 'title' => 'Colombia', + 'country_flag' => 'https://flagcdn.com/w80/co.png', + 'status' => 1, + ], + [ + 'id' => 17, + 'title' => 'Ecuador', + 'country_flag' => 'https://flagcdn.com/w80/ec.png', + 'status' => 1, + ], + [ + 'id' => 18, + 'title' => 'Paraguay', + 'country_flag' => 'https://flagcdn.com/w80/py.png', + 'status' => 1, + ], + [ + 'id' => 19, + 'title' => 'New Zealand', + 'country_flag' => 'https://flagcdn.com/w80/nz.png', + 'status' => 1, + ], + [ + 'id' => 20, + 'title' => 'Morocco', + 'country_flag' => 'https://flagcdn.com/w80/ma.png', + 'status' => 1, + ], + [ + 'id' => 21, + 'title' => 'Senegal', + 'country_flag' => 'https://flagcdn.com/w80/sn.png', + 'status' => 1, + ], + [ + 'id' => 22, + 'title' => 'Egypt', + 'country_flag' => 'https://flagcdn.com/w80/eg.png', + 'status' => 1, + ], + [ + 'id' => 23, + 'title' => 'Algeria', + 'country_flag' => 'https://flagcdn.com/w80/dz.png', + 'status' => 1, + ], + [ + 'id' => 24, + 'title' => 'Tunisia', + 'country_flag' => 'https://flagcdn.com/w80/tn.png', + 'status' => 1, + ], + [ + 'id' => 25, + 'title' => 'South Africa', + 'country_flag' => 'https://flagcdn.com/w80/za.png', + 'status' => 1, + ], + [ + 'id' => 26, + 'title' => 'Ivory Coast', + 'country_flag' => 'https://flagcdn.com/w80/ci.png', + 'status' => 1, + ], + [ + 'id' => 27, + 'title' => 'Ghana', + 'country_flag' => 'https://flagcdn.com/w80/gh.png', + 'status' => 1, + ], + [ + 'id' => 28, + 'title' => 'Cape Verde', + 'country_flag' => 'https://flagcdn.com/w80/cv.png', + 'status' => 1, + ], + [ + 'id' => 29, + 'title' => 'DR Congo', + 'country_flag' => 'https://flagcdn.com/w80/cd.png', + 'status' => 1, + ], + [ + 'id' => 30, + 'title' => 'England', + 'country_flag' => 'https://upload.wikimedia.org/wikipedia/en/thumb/b/be/Flag_of_England.svg/120px-Flag_of_England.svg.png', + 'status' => 1, + ], + [ + 'id' => 31, + 'title' => 'France', + 'country_flag' => 'https://flagcdn.com/w80/fr.png', + 'status' => 1, + ], + [ + 'id' => 32, + 'title' => 'Spain', + 'country_flag' => 'https://flagcdn.com/w80/es.png', + 'status' => 1, + ], + [ + 'id' => 33, + 'title' => 'Germany', + 'country_flag' => 'https://flagcdn.com/w80/de.png', + 'status' => 1, + ], + [ + 'id' => 34, + 'title' => 'Portugal', + 'country_flag' => 'https://flagcdn.com/w80/pt.png', + 'status' => 1, + ], + [ + 'id' => 35, + 'title' => 'Netherlands', + 'country_flag' => 'https://flagcdn.com/w80/nl.png', + 'status' => 1, + ], + [ + 'id' => 36, + 'title' => 'Belgium', + 'country_flag' => 'https://flagcdn.com/w80/be.png', + 'status' => 1, + ], + [ + 'id' => 37, + 'title' => 'Croatia', + 'country_flag' => 'https://flagcdn.com/w80/hr.png', + 'status' => 1, + ], + [ + 'id' => 38, + 'title' => 'Switzerland', + 'country_flag' => 'https://flagcdn.com/w80/ch.png', + 'status' => 1, + ], + [ + 'id' => 39, + 'title' => 'Austria', + 'country_flag' => 'https://flagcdn.com/w80/at.png', + 'status' => 1, + ], + [ + 'id' => 40, + 'title' => 'Scotland', + 'country_flag' => 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Flag_of_Scotland.svg/120px-Flag_of_Scotland.svg.png', + 'status' => 1, + ], + [ + 'id' => 41, + 'title' => 'Norway', + 'country_flag' => 'https://flagcdn.com/w80/no.png', + 'status' => 1, + ], + [ + 'id' => 42, + 'title' => 'Bosnia and Herzegovina', + 'country_flag' => 'https://flagcdn.com/w80/ba.png', + 'status' => 1, + ], + [ + 'id' => 43, + 'title' => 'Sweden', + 'country_flag' => 'https://flagcdn.com/w80/se.png', + 'status' => 1, + ], + [ + 'id' => 44, + 'title' => 'Türkiye', + 'country_flag' => 'https://flagcdn.com/w80/tr.png', + 'status' => 1, + ], + [ + 'id' => 45, + 'title' => 'Czechia', + 'country_flag' => 'https://flagcdn.com/w80/cz.png', + 'status' => 1, + ], + [ + 'id' => 46, + 'title' => 'Panama', + 'country_flag' => 'https://flagcdn.com/w80/pa.png', + 'status' => 1, + ], + [ + 'id' => 47, + 'title' => 'Curaçao', + 'country_flag' => 'https://flagcdn.com/w80/cw.png', + 'status' => 1, + ], + [ + 'id' => 48, + 'title' => 'Haiti', + 'country_flag' => 'https://flagcdn.com/w80/ht.png', + 'status' => 1, + ], + ]); + } +} diff --git a/resources/views/dashboard/admin.blade.php b/resources/views/dashboard/admin.blade.php index 7a4732d..d15ec95 100644 --- a/resources/views/dashboard/admin.blade.php +++ b/resources/views/dashboard/admin.blade.php @@ -7,35 +7,38 @@

Student Registrations

-

Track registrations and goal scores for today's session.

+

View registrations and manage student comments.

@@ -96,6 +99,7 @@ Name Phone Email + Country Today's Shots Total Score Actions @@ -123,6 +127,19 @@ {{ $reg['phone'] }} {{ $reg['email'] }} + + +
@if(is_null($reg['today_goals'])) @@ -775,4 +792,33 @@ document.getElementById('submitRegistrationBtn').addEventListener('click', funct }); }); + @endpush \ No newline at end of file diff --git a/resources/views/dashboard/counselor.blade.php b/resources/views/dashboard/counselor.blade.php index c100e13..5892183 100644 --- a/resources/views/dashboard/counselor.blade.php +++ b/resources/views/dashboard/counselor.blade.php @@ -10,6 +10,20 @@

View registrations and manage student comments.

+
+
+ + + + + @if(!empty($search)) + + + + @endif +
+
@@ -84,6 +98,8 @@ Name Phone Email + Country + Status Today's Shots Total Score Comments @@ -91,9 +107,16 @@ @foreach ($registrations as $reg) -
+ data-name="{{ $reg['name'] }}" + data-phone="{{ $reg['phone'] }}" + data-email="{{ $reg['email'] ?? '' }}" + data-score="{{ $reg['total_score'] }}" + data-status="{{ $reg['status'] ?? 'warm' }}" + data-country-title="{{ $reg['country_title'] ?? '' }}" + data-country-flag="{{ $reg['country_flag'] ?? '' }}" + data-shots="{{ json_encode($reg['today_goals'] ?? []) }}">
#{{ str_pad($reg['id'], 4, '0', STR_PAD_LEFT) }} @@ -107,6 +130,28 @@ {{ $reg['phone'] }} {{ $reg['email'] }} + + + +
+ @if(!empty($reg['country_flag'])) + + @endif + {{ $reg['country_title'] ?: '—' }} +
+ + + + + @php $status = $reg['status'] ?? 'warm'; @endphp + + +
@if(is_null($reg['today_goals'])) @@ -126,12 +171,14 @@ @endif
+
{{ $reg['total_score'] }}
+ @@ -151,20 +198,30 @@
- + -
-
-
-

Comments for

-

+
+
+
+ +
+
+

+

+
+ + + +
+
-
- -
- -
- - Loading comments… -
-
-
- - - - - - - - + + + + + + + + + + - - + @foreach ($registrations as $reg) - + @php + $sessionData = $reg->sessions->sortByDesc('play_date')->map(fn($s) => [ + 'date' => $s->play_date, + 'score' => $s->score, + 'shots' => $s->shots->sortBy('shot_number')->map(fn($sh) => (bool)$sh->result)->values()->toArray(), + ])->values()->toArray(); - - - + - - - - + + {{-- Country TD (editable with flag preview) --}} + - - - - - + + + @endforeach -
IDNamePhoneEmailTotal ScoreCreatedIDNamePhoneEmailCountryStatusTotal ScoreSessionsCommentsRegistered
#{{ $reg->id }} - {{ $reg->name ?? '-' }} + $commentData = $reg->comments->sortByDesc('created_at')->map(fn($c) => [ + 'comment' => $c->comment, + 'created_at' => $c->created_at->diffForHumans(), + ])->values()->toArray(); + @endphp +
+ #{{ str_pad($reg->id, 4, '0', STR_PAD_LEFT) }} - {{ $reg->phone }} + +
+
+ {{ strtoupper(substr($reg->name, 0, 1)) }} +
+ {{ $reg->name ?? '-' }} +
- {{ $reg->email ?? '-' }} + {{ $reg->phone }}{{ $reg->email ?? '-' }} +
+ + +
- {{ $reg->total_score }} + + {{-- Status TD (read-only badge) --}} + + @php $status = $reg->status ?? 'warm'; @endphp + + {{ match($status) { 'hot' => '🔥 Hot', 'warm' => '☀️ Warm', 'cold' => '❄️ Cold', default => '☀️ Warm' } }} + - {{ $reg->created_at->format('Y-m-d') }} + + +
+ + {{ $reg->total_score }} +
+ + + {{ $reg->sessions->count() }} + + + + + {{ $reg->comments->count() }} + + {{ $reg->created_at->format('Y-m-d') }}
-
-
- Showing {{ $registrations->firstItem() }} - {{ $registrations->lastItem() }} + Showing {{ $registrations->firstItem() }}–{{ $registrations->lastItem() }} of {{ $registrations->total() }}
+
{{ $registrations->appends(request()->query())->links() }}
+
+
+
-
- {{ $registrations->links() }} + +
+ +
+
+
+
+
+

+

+
+ + + +
+
+
+ +
+ +
+
+
+

Total Score

+
+ + 0 +
+
+
+

Sessions

+

0

+
+
+

Email

+

+
+
+

Registered:

+
+ +
+ +
+

Score History

+
+

No sessions yet.

+
+
+ +
+

Comments

+
+

No comments yet.

+
+
+ + +
-
-@endsection \ No newline at end of file + + + +@endsection + +@push('js') + + +@endpush \ No newline at end of file diff --git a/resources/views/scoreboard.blade.php b/resources/views/scoreboard.blade.php index a15fa93..870daf7 100644 --- a/resources/views/scoreboard.blade.php +++ b/resources/views/scoreboard.blade.php @@ -78,13 +78,27 @@ .bar i { display:block; height:100%; background:linear-gradient(90deg,#0566e9,#0ab4ff,#0640c3); transition:width .5s ease; } .rscore { color:var(--cyan); font-size:clamp(14px,1.9vw,26px); font-weight:900; text-align:right; } .pts { font-size:clamp(8px,.9vw,13px); font-family:Arial,sans-serif; } - .next-box { text-align:center; cursor:default; justify-content:center; align-items:center; gap:1vh; padding:1.5vh 0; border:none; background:rgba(1,17,35,.85); border:1.5px solid var(--cyan); } - .next-ball { width:9.5vw; height:9.5vw; border-radius:50%; display:grid; place-items:center; font-size:clamp(32px,5.5vw,80px); background:radial-gradient(circle,rgba(0,174,239,.3),transparent 62%); box-shadow:0 0 24px rgba(0,174,239,.55); } - .waiting-text { font-family:Arial,sans-serif; font-size:clamp(11px,1.4vw,20px); font-weight:900; text-transform:uppercase; letter-spacing:.5px; color:var(--cyan); } + + /* HISTORY BOX */ + .next-box { padding:.8vh 1.2vw; align-items:stretch; justify-content:flex-start; gap:0; } + .history-wrap { flex:1; min-height:0; overflow-y:auto; display:flex; flex-direction:column; gap:.5vh; padding-top:.3vh; justify-content:flex-start; } + .history-wrap::-webkit-scrollbar { width:3px; } + .history-wrap::-webkit-scrollbar-thumb { background:rgba(0,174,239,.4); border-radius:99px; } + .history-row { display:grid; grid-template-columns:6vw 1fr auto; align-items:center; gap:.6vw; padding:.55vh .5vw; border-radius:7px; background:rgba(0,174,239,.06); border:1px solid rgba(0,174,239,.15); flex-shrink:0; } + .history-date { font-family:Arial,sans-serif; font-size:clamp(9px,1vw,13px); font-weight:900; color:var(--cyan); line-height:1.25; } + .history-shots { display:flex; gap:.35vw; align-items:center; } + .hshot { font-size:clamp(11px,1.2vw,17px); line-height:1; } + .hshot.goal { filter:drop-shadow(0 0 4px rgba(0,255,70,.6)); } + .hshot.miss { color:var(--red); } + .hshot.pending { opacity:.25; } + .history-score { font-family:Arial,sans-serif; font-size:clamp(13px,1.5vw,22px); font-weight:900; color:#fff; white-space:nowrap; } + .history-score span { color:var(--cyan); font-size:clamp(8px,.9vw,12px); } + .history-today { border-color:rgba(0,174,239,.5); background:rgba(0,174,239,.12); } + .no-history { font-family:Arial,sans-serif; font-size:clamp(10px,1.1vw,15px); color:rgba(255,255,255,.3); text-align:center; margin:auto; text-transform:uppercase; letter-spacing:.5px; } + .footer { flex-shrink:0; width:50vw; margin:0 auto; padding:.65vh 2vw; display:flex; justify-content:center; gap:3vw; background:rgba(1,17,35,.82); border:1px solid rgba(0,174,239,.5); border-radius:12px 12px 0 0; font-family:Arial,sans-serif; font-size:clamp(9px,1vw,14px); font-weight:900; text-transform:uppercase; } .footer span:first-child { color:var(--cyan); } - /* pulse on score update */ @keyframes scorePop { 0%{transform:scale(1)} 50%{transform:scale(1.2)} 100%{transform:scale(1)} } .score-pop { animation:scorePop .35s ease; } @@ -138,15 +152,15 @@
Top 5 Leaderboard
-
- -
+
+
-
Now Playing
-
-
Select a player
+
Player History
+
+
Select a player
+
@@ -159,67 +173,84 @@ \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index aee131b..1eb4149 100644 --- a/routes/web.php +++ b/routes/web.php @@ -32,7 +32,9 @@ Route::middleware('auth')->group(function () { Route::get('/{id}/json', [RegistrationController::class, 'getRegistrationJson'])->name('get-json'); Route::post('/record-shot', [RegistrationController::class, 'recordShot'])->name('record-shot'); Route::post('/record-shots', [RegistrationController::class, 'recordShots'])->name('record-shots'); - + Route::get('/{id}/history', [RegistrationController::class, 'history'])->name('history'); + Route::post('/{id}/country', [RegistrationController::class, 'updateCountry'])->name('update-country'); + Route::post('/{id}/status', [RegistrationController::class, 'updateStatus'])->name('update-status'); }); Route::resource('comments', CommentController::class)->only(['index', 'store'])->names('comments');