diff --git a/app/Console/Commands/FetchMetaData.php b/app/Console/Commands/FetchMetaData.php index 729c7a5..5bbffba 100644 --- a/app/Console/Commands/FetchMetaData.php +++ b/app/Console/Commands/FetchMetaData.php @@ -7,6 +7,7 @@ use App\Jobs\ProcessElficTraits; use App\Jobs\ProcessKlingonName; use App\Jobs\ProcessLitteratureReferences; +use App\Jobs\ProcessMixte; use App\Jobs\ProcessOrigins; use App\Jobs\ProcessPersonality; use App\Jobs\ProcessSimilarNames; @@ -70,6 +71,10 @@ public function handle(): void if (is_null($name->klingon_translation)) { //ProcessKlingonName::dispatch($name); } + + if (is_null($name->unisex)) { + ProcessMixte::dispatch($name); + } } } } diff --git a/app/Http/Controllers/FemaleNameController.php b/app/Http/Controllers/FemaleNameController.php new file mode 100644 index 0000000..0e370d1 --- /dev/null +++ b/app/Http/Controllers/FemaleNameController.php @@ -0,0 +1,96 @@ +query('page') ?? 1; + + $letters = Cache::remember('all-letters-female', 604800, function () { + return FemaleNamesViewModel::index(); + }); + + Paginator::currentPageResolver(function () use ($requestedPage) { + return $requestedPage; + }); + + $namesPagination = Cache::remember('all-names-female-page-'.$requestedPage, 604800, function () { + return Name::where('name', '!=', '_PRENOMS_RARES') + ->where('gender', 'female') + ->orderBy('name', 'asc') + ->paginate(40); + }); + + $names = $namesPagination + ->map(fn (Name $name) => [ + 'id' => $name->id, + 'name' => StringHelper::getProperName($name->name), + 'avatar' => $name->avatar, + 'url' => route('name.show', [ + 'id' => $name->id, + 'name' => StringHelper::sanitizeNameForURL($name->name), + ]), + ]); + + return view('names.female.index', [ + 'letters' => $letters, + 'names' => $names, + 'namesPagination' => $namesPagination, + ]); + } + + public function letter(Request $request): View + { + $requestedLetter = $request->attributes->get('letter'); + $requestedPage = $request->query('page') ?? 1; + + $letters = Cache::remember('all-letters-female', 604800, function () { + return FemaleNamesViewModel::index(); + }); + + Paginator::currentPageResolver(function () use ($requestedPage) { + return $requestedPage; + }); + + $namesPagination = Cache::remember('female-letter-'.$requestedLetter.'-page-' . $requestedPage, 604800, function () use ($requestedLetter) { + return Name::where('name', '!=', '_PRENOMS_RARES') + ->where('gender', 'female') + ->where('name', 'like', $requestedLetter . '%') + ->orderBy('name', 'asc') + ->paginate(40); + }); + + $names = $namesPagination + ->map(fn (Name $name) => [ + 'id' => $name->id, + 'name' => StringHelper::getProperName($name->name), + 'avatar' => $name->avatar, + 'url' => route('name.show', [ + 'id' => $name->id, + 'name' => StringHelper::sanitizeNameForURL($name->name), + ]), + ]); + + return view('names.female.letter', [ + 'letters' => $letters, + 'names' => $names, + 'namesPagination' => $namesPagination, + 'activeLetter' => Str::ucfirst($requestedLetter), + ]); + } +} diff --git a/app/Http/Controllers/MaleNameController.php b/app/Http/Controllers/MaleNameController.php new file mode 100644 index 0000000..444346d --- /dev/null +++ b/app/Http/Controllers/MaleNameController.php @@ -0,0 +1,95 @@ +query('page') ?? 1; + + $letters = Cache::remember('all-letters-male', 604800, function () { + return MaleNamesViewModel::index(); + }); + + Paginator::currentPageResolver(function () use ($requestedPage) { + return $requestedPage; + }); + + $namesPagination = Cache::remember('all-names-male-page-'.$requestedPage, 604800, function () { + return Name::where('name', '!=', '_PRENOMS_RARES') + ->where('gender', 'male') + ->orderBy('name', 'asc') + ->paginate(40); + }); + + $names = $namesPagination + ->map(fn (Name $name) => [ + 'id' => $name->id, + 'name' => StringHelper::getProperName($name->name), + 'avatar' => $name->avatar, + 'url' => route('name.show', [ + 'id' => $name->id, + 'name' => StringHelper::sanitizeNameForURL($name->name), + ]), + ]); + + return view('names.male.index', [ + 'letters' => $letters, + 'names' => $names, + 'namesPagination' => $namesPagination, + ]); + } + + public function letter(Request $request): View + { + $requestedLetter = $request->attributes->get('letter'); + $requestedPage = $request->query('page') ?? 1; + + $letters = Cache::remember('all-letters-male', 604800, function () { + return MaleNamesViewModel::index(); + }); + + Paginator::currentPageResolver(function () use ($requestedPage) { + return $requestedPage; + }); + + $namesPagination = Cache::remember('male-letter-'.$requestedLetter.'-page-' . $requestedPage, 604800, function () use ($requestedLetter) { + return Name::where('name', '!=', '_PRENOMS_RARES') + ->where('gender', 'male') + ->where('name', 'like', $requestedLetter . '%') + ->orderBy('name', 'asc') + ->paginate(40); + }); + + $names = $namesPagination + ->map(fn (Name $name) => [ + 'id' => $name->id, + 'name' => StringHelper::getProperName($name->name), + 'avatar' => $name->avatar, + 'url' => route('name.show', [ + 'id' => $name->id, + 'name' => StringHelper::sanitizeNameForURL($name->name), + ]), + ]); + + return view('names.male.letter', [ + 'letters' => $letters, + 'names' => $names, + 'namesPagination' => $namesPagination, + 'activeLetter' => Str::ucfirst($requestedLetter), + ]); + } +} diff --git a/app/Http/Controllers/NameController.php b/app/Http/Controllers/NameController.php index d40c390..689160b 100644 --- a/app/Http/Controllers/NameController.php +++ b/app/Http/Controllers/NameController.php @@ -2,13 +2,94 @@ namespace App\Http\Controllers; +use App\Helpers\StringHelper; +use App\Http\ViewModels\Names\AllNamesViewModel; use App\Http\ViewModels\Names\NameViewModel; +use App\Models\Name; use Illuminate\Http\Request; +use Illuminate\Pagination\Paginator; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Str; use Illuminate\View\View; class NameController extends Controller { + public function index(Request $request): View + { + // get the page parameter from the url + $requestedPage = $request->query('page') ?? 1; + + $letters = Cache::remember('all-letters', 604800, function () { + return AllNamesViewModel::index(); + }); + + Paginator::currentPageResolver(function () use ($requestedPage) { + return $requestedPage; + }); + + $namesPagination = Cache::remember('all-names-page-'.$requestedPage, 604800, function () { + return Name::where('name', '!=', '_PRENOMS_RARES') + ->orderBy('name', 'asc') + ->paginate(40); + }); + + $names = $namesPagination + ->map(fn (Name $name) => [ + 'id' => $name->id, + 'name' => StringHelper::getProperName($name->name), + 'avatar' => $name->avatar, + 'url' => route('name.show', [ + 'id' => $name->id, + 'name' => StringHelper::sanitizeNameForURL($name->name), + ]), + ]); + + return view('names.index', [ + 'letters' => $letters, + 'names' => $names, + 'namesPagination' => $namesPagination, + ]); + } + + public function letter(Request $request): View + { + $requestedLetter = $request->attributes->get('letter'); + $requestedPage = $request->query('page') ?? 1; + + $letters = Cache::remember('all-letters', 604800, function () { + return AllNamesViewModel::index(); + }); + + Paginator::currentPageResolver(function () use ($requestedPage) { + return $requestedPage; + }); + + $namesPagination = Cache::remember('letter-'.$requestedLetter.'-page-' . $requestedPage, 604800, function () use ($requestedLetter) { + return Name::where('name', '!=', '_PRENOMS_RARES') + ->where('name', 'like', $requestedLetter . '%') + ->orderBy('name', 'asc') + ->paginate(40); + }); + + $names = $namesPagination + ->map(fn (Name $name) => [ + 'id' => $name->id, + 'name' => StringHelper::getProperName($name->name), + 'avatar' => $name->avatar, + 'url' => route('name.show', [ + 'id' => $name->id, + 'name' => StringHelper::sanitizeNameForURL($name->name), + ]), + ]); + + return view('names.letter', [ + 'letters' => $letters, + 'names' => $names, + 'namesPagination' => $namesPagination, + 'activeLetter' => Str::ucfirst($requestedLetter), + ]); + } + public function show(Request $request): View { $requestedName = $request->attributes->get('name'); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 2bfa4a2..bbcaa95 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -67,5 +67,6 @@ class Kernel extends HttpKernel 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'administrator' => \App\Http\Middleware\CheckAdministratorRole::class, 'name' => \App\Http\Middleware\CheckName::class, + 'letter' => \App\Http\Middleware\CheckLetter::class, ]; } diff --git a/app/Http/Middleware/CheckLetter.php b/app/Http/Middleware/CheckLetter.php new file mode 100644 index 0000000..b6fb333 --- /dev/null +++ b/app/Http/Middleware/CheckLetter.php @@ -0,0 +1,37 @@ +route()->parameter('letter'); + + // check if the requested letter is between A and Z and is exactly one character + if (strlen($requestedLetter) > 1) { + return redirect()->route('home.index'); + } + + if (!preg_match('/^[A-Za-z]+$/', $requestedLetter)) { + return redirect()->route('home.index'); + } + + $request->attributes->add(['letter' => Str::lcfirst($requestedLetter)]); + + return $next($request); + } +} diff --git a/app/Http/ViewModels/Home/HomeViewModel.php b/app/Http/ViewModels/Home/HomeViewModel.php index 083b2b3..7a8b6c9 100644 --- a/app/Http/ViewModels/Home/HomeViewModel.php +++ b/app/Http/ViewModels/Home/HomeViewModel.php @@ -86,7 +86,7 @@ public static function nameSpotlight(): array public static function serverStats(): array { - $totalNames = Name::count(); + $totalNames = Name::where('name', '!=', '_PRENOMS_RARES')->count(); return [ 'total_names' => $totalNames, diff --git a/app/Http/ViewModels/Names/AllNamesViewModel.php b/app/Http/ViewModels/Names/AllNamesViewModel.php new file mode 100644 index 0000000..2266034 --- /dev/null +++ b/app/Http/ViewModels/Names/AllNamesViewModel.php @@ -0,0 +1,37 @@ +push([ + 'letter' => 'Tous', + 'count' => Number::format(Name::where('name', '!=', '_PRENOMS_RARES')->count(), locale: 'fr'), + 'url' => route('name.index'), + ]); + + foreach ($alphabet as $letter) { + $letters->push([ + 'letter' => $letter, + 'count' => Number::format(Name::where('name', 'like', $letter . '%')->count(), locale: 'fr'), + 'url' => route('name.letter', ['letter' => Str::lcfirst($letter)]), + ]); + } + + return $letters; + } +} diff --git a/app/Http/ViewModels/Names/FemaleNamesViewModel.php b/app/Http/ViewModels/Names/FemaleNamesViewModel.php new file mode 100644 index 0000000..2347d2a --- /dev/null +++ b/app/Http/ViewModels/Names/FemaleNamesViewModel.php @@ -0,0 +1,43 @@ +where('name', '!=', '_PRENOMS_RARES')->count(); + + $letters = collect(); + $letters->push([ + 'letter' => 'Tous', + 'count' => Number::format($total, locale: 'fr'), + 'url' => route('name.fille.index'), + ]); + + foreach ($alphabet as $letter) { + $total = Name::where('gender', 'female') + ->where('name', 'like', $letter . '%')->count(); + $letters->push([ + 'letter' => $letter, + 'count' => Number::format($total, locale: 'fr'), + 'url' => route('name.fille.letter', [ + 'letter' => Str::lcfirst($letter) + ]), + ]); + } + + return $letters; + } +} diff --git a/app/Http/ViewModels/Names/MaleNamesViewModel.php b/app/Http/ViewModels/Names/MaleNamesViewModel.php new file mode 100644 index 0000000..2b60ec0 --- /dev/null +++ b/app/Http/ViewModels/Names/MaleNamesViewModel.php @@ -0,0 +1,43 @@ +where('name', '!=', '_PRENOMS_RARES')->count(); + + $letters = collect(); + $letters->push([ + 'letter' => 'Tous', + 'count' => Number::format($total, locale: 'fr'), + 'url' => route('name.garcon.index'), + ]); + + foreach ($alphabet as $letter) { + $total = Name::where('gender', 'male') + ->where('name', 'like', $letter . '%')->count(); + $letters->push([ + 'letter' => $letter, + 'count' => Number::format($total, locale: 'fr'), + 'url' => route('name.garcon.letter', [ + 'letter' => Str::lcfirst($letter) + ]), + ]); + } + + return $letters; + } +} diff --git a/app/Jobs/ProcessMixte.php b/app/Jobs/ProcessMixte.php index 1501e93..39a3edd 100644 --- a/app/Jobs/ProcessMixte.php +++ b/app/Jobs/ProcessMixte.php @@ -27,9 +27,9 @@ public function __construct( */ public function handle(): void { - if ($this->name->celebrities === null) { - $celebrities = OpenAIHelper::getUnisex($this->name->name); - $this->name->celebrities = $celebrities; + if ($this->name->unisex === null) { + $answer = OpenAIHelper::getUnisex($this->name->name); + $this->name->unisex = $answer; $this->name->save(); } } diff --git a/database/migrations/2023_12_08_013120_create_name_table.php b/database/migrations/2023_12_08_013120_create_name_table.php index 8fe9aa1..999515a 100644 --- a/database/migrations/2023_12_08_013120_create_name_table.php +++ b/database/migrations/2023_12_08_013120_create_name_table.php @@ -24,7 +24,7 @@ public function up(): void $table->text('litterature_artistics_references')->nullable(); $table->text('similar_names_in_other_languages')->nullable(); $table->text('klingon_translation')->nullable(); - $table->boolean('unisex')->default(false); + $table->boolean('unisex')->nullable(); $table->integer('total')->default(0); $table->integer('page_views')->default(0); $table->timestamps(); diff --git a/resources/css/app.css b/resources/css/app.css index 757178d..ef161ce 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -5,3 +5,7 @@ .name-show-grid { grid-template-columns: 1fr 240px; } + +.name-index-grid { + grid-template-columns: 240px 1fr; +} diff --git a/resources/views/home/index.blade.php b/resources/views/home/index.blade.php index 130bb6d..f0cc3e5 100644 --- a/resources/views/home/index.blade.php +++ b/resources/views/home/index.blade.php @@ -15,7 +15,7 @@
- Parcourir tous les prénoms + Parcourir tous les prénoms
@@ -63,59 +63,59 @@