From f6628ab2127002c736ff1c14aa1abaaf54aefa69 Mon Sep 17 00:00:00 2001 From: Arthur Monney Date: Fri, 18 Oct 2024 00:02:18 +0200 Subject: [PATCH 1/8] fix: (LAR-78) forum bug and create livewire forum page --- app/Actions/Article/CreateArticleAction.php | 7 +- app/Livewire/Components/Channels.php | 16 +++ app/Livewire/Components/ChannelsSelector.php | 50 ++++++++ app/Livewire/Pages/Forum/Index.php | 54 ++++++++ app/Models/Channel.php | 7 ++ app/Models/Thread.php | 2 +- composer.lock | 117 +++++++++--------- lang/en.json | 10 -- lang/fr.json | 10 -- lang/fr/pages/forum.php | 20 +++ .../forum/thread-overview.blade.php | 4 +- .../views/components/layouts/header.blade.php | 2 +- resources/views/components/link.blade.php | 2 +- .../views/components/status-message.blade.php | 2 +- resources/views/forum/_channels.blade.php | 102 ++++++++------- resources/views/forum/index.blade.php | 26 +--- .../components/channels-selector.blade.php | 109 ++++++++++++++++ .../livewire/forum/create-thread.blade.php | 15 ++- .../livewire/pages/forum/index.blade.php | 28 +++++ resources/views/partials/_search.blade.php | 2 +- routes/forum.php | 14 +++ routes/web.php | 9 +- tests/Feature/Forum/ChannelTest.php | 24 ++-- .../Components/ChannelsSelectorTest.php | 11 ++ .../Livewire/Pages/Forum/IndexTest.php | 13 ++ 25 files changed, 469 insertions(+), 187 deletions(-) create mode 100644 app/Livewire/Components/Channels.php create mode 100644 app/Livewire/Components/ChannelsSelector.php create mode 100644 app/Livewire/Pages/Forum/Index.php delete mode 100644 lang/en.json delete mode 100644 lang/fr.json create mode 100644 lang/fr/pages/forum.php create mode 100644 resources/views/livewire/components/channels-selector.blade.php create mode 100644 resources/views/livewire/pages/forum/index.blade.php create mode 100644 routes/forum.php create mode 100644 tests/Feature/Livewire/Components/ChannelsSelectorTest.php create mode 100644 tests/Feature/Livewire/Pages/Forum/IndexTest.php diff --git a/app/Actions/Article/CreateArticleAction.php b/app/Actions/Article/CreateArticleAction.php index a960ba73..824e1528 100644 --- a/app/Actions/Article/CreateArticleAction.php +++ b/app/Actions/Article/CreateArticleAction.php @@ -9,14 +9,13 @@ use App\Models\Article; use App\Notifications\PostArticleToTelegram; use Carbon\Carbon; -use DateTimeInterface; use Illuminate\Support\Facades\Auth; final class CreateArticleAction { public function execute(CreateArticleData $articleData): Article { - if ($articleData->publishedAt && ! ($articleData->publishedAt instanceof DateTimeInterface)) { + if ($articleData->publishedAt) { $articleData->publishedAt = new Carbon( time: $articleData->publishedAt, tz: config('app.timezone') @@ -41,12 +40,14 @@ public function execute(CreateArticleData $articleData): Article } if ($articleData->file) { - $article->addMedia($articleData->file->getRealPath())->toMediaCollection('media'); + $article->addMedia($articleData->file->getRealPath()) + ->toMediaCollection('media'); } if ($article->isAwaitingApproval()) { // Envoi de la notification sur le channel Telegram pour la validation de l'article. Auth::user()?->notify(new PostArticleToTelegram($article)); + session()->flash('status', __('notifications.article.created')); } diff --git a/app/Livewire/Components/Channels.php b/app/Livewire/Components/Channels.php new file mode 100644 index 00000000..8906b7fb --- /dev/null +++ b/app/Livewire/Components/Channels.php @@ -0,0 +1,16 @@ +slug = Channel::query()->find($channelId)?->slug; + + $this->dispatch('channelUpdated', channelId: $channelId); + } + + public function resetChannel(): void + { + $this->slug = null; + + $this->dispatch('channelUpdated', channelId: null); + } + + #[Computed] + public function currentChannel(): ?Channel + { + return $this->slug ? Channel::findBySlug($this->slug) : null; + } + + public function render(): View + { + return view('livewire.components.channels-selector', [ + 'channels' => Cache::remember( + 'channels', + now()->addMonth(), + fn () => Channel::with('items')->whereNull('parent_id')->get() + ), + ]); + } +} diff --git a/app/Livewire/Pages/Forum/Index.php b/app/Livewire/Pages/Forum/Index.php new file mode 100644 index 00000000..75255abb --- /dev/null +++ b/app/Livewire/Pages/Forum/Index.php @@ -0,0 +1,54 @@ +currentChannel = Channel::query()->find($channelId); + } else { + $this->currentChannel = null; + } + + $this->dispatch('render'); + } + + public function render(): View + { + $query = Thread::query() + ->orderByDesc('created_at'); + + if ($this->currentChannel?->id) { + $query->scopes(['channel' => $this->currentChannel]); + } + + $threads = $query + ->scopes('withViewsCount') + ->paginate($this->perPage); + + return view('livewire.pages.forum.index', [ + 'threads' => $threads, + ]) + ->title(__('pages/forum.channel_title', ['channel' => isset($this->currentChannel) ? ' ~ '.$this->currentChannel->name : ''])); + } +} diff --git a/app/Models/Channel.php b/app/Models/Channel.php index 9a0fd3e5..aec67d7f 100644 --- a/app/Models/Channel.php +++ b/app/Models/Channel.php @@ -12,6 +12,13 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; +/** + * @property-read int $id + * @property string $name + * @property string $slug + * @property string $color + * @property int | null $parent_id + */ final class Channel extends Model { use HasFactory; diff --git a/app/Models/Thread.php b/app/Models/Thread.php index a49b0924..6093e60c 100644 --- a/app/Models/Thread.php +++ b/app/Models/Thread.php @@ -147,7 +147,7 @@ public function unmarkSolution(): void $this->save(); } - public function scopeForChannel(Builder $query, Channel $channel): Builder + public function scopeChannel(Builder $query, Channel $channel): Builder { return $query->whereHas('channels', function ($query) use ($channel): void { if ($channel->hasItems()) { diff --git a/composer.lock b/composer.lock index 2c9357c7..bc7c996b 100644 --- a/composer.lock +++ b/composer.lock @@ -2672,16 +2672,16 @@ }, { "name": "filament/actions", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", - "reference": "886108b59ce99edc26f5bc1231134a95ec58718a" + "reference": "addd6a6f5e8e250a34c7c12bcb4060cc5ecbb9e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/actions/zipball/886108b59ce99edc26f5bc1231134a95ec58718a", - "reference": "886108b59ce99edc26f5bc1231134a95ec58718a", + "url": "https://api.github.com/repos/filamentphp/actions/zipball/addd6a6f5e8e250a34c7c12bcb4060cc5ecbb9e8", + "reference": "addd6a6f5e8e250a34c7c12bcb4060cc5ecbb9e8", "shasum": "" }, "require": { @@ -2721,20 +2721,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-09T11:19:22+00:00" + "time": "2024-10-16T12:07:31+00:00" }, { "name": "filament/filament", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "84f839b4b42549c0d4bd231648da17561ada70c2" + "reference": "442374aea8436dc154629aa97f56736503cc3e49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/84f839b4b42549c0d4bd231648da17561ada70c2", - "reference": "84f839b4b42549c0d4bd231648da17561ada70c2", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/442374aea8436dc154629aa97f56736503cc3e49", + "reference": "442374aea8436dc154629aa97f56736503cc3e49", "shasum": "" }, "require": { @@ -2786,20 +2786,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:12+00:00" + "time": "2024-10-16T12:07:33+00:00" }, { "name": "filament/forms", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "896c868cca474b2e925a3e6162b7c76d8ff3e5fc" + "reference": "9eaf88275da18777b1738514db6083e34b1700d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/896c868cca474b2e925a3e6162b7c76d8ff3e5fc", - "reference": "896c868cca474b2e925a3e6162b7c76d8ff3e5fc", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/9eaf88275da18777b1738514db6083e34b1700d4", + "reference": "9eaf88275da18777b1738514db6083e34b1700d4", "shasum": "" }, "require": { @@ -2842,20 +2842,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-09T11:19:26+00:00" + "time": "2024-10-16T12:07:33+00:00" }, { "name": "filament/infolists", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", - "reference": "fc5f01c094fe25ef906f3e1b88d3d8883a73d6be" + "reference": "f107a83c3ac042a4d4608d45173cf88c0c55276c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/infolists/zipball/fc5f01c094fe25ef906f3e1b88d3d8883a73d6be", - "reference": "fc5f01c094fe25ef906f3e1b88d3d8883a73d6be", + "url": "https://api.github.com/repos/filamentphp/infolists/zipball/f107a83c3ac042a4d4608d45173cf88c0c55276c", + "reference": "f107a83c3ac042a4d4608d45173cf88c0c55276c", "shasum": "" }, "require": { @@ -2893,20 +2893,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:09+00:00" + "time": "2024-10-16T12:07:29+00:00" }, { "name": "filament/notifications", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", - "reference": "a5f684b690354630210fc9a90bd06da9b1f6ae82" + "reference": "b56b155efd4290459d944a1b3d515b5aaf54846d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/notifications/zipball/a5f684b690354630210fc9a90bd06da9b1f6ae82", - "reference": "a5f684b690354630210fc9a90bd06da9b1f6ae82", + "url": "https://api.github.com/repos/filamentphp/notifications/zipball/b56b155efd4290459d944a1b3d515b5aaf54846d", + "reference": "b56b155efd4290459d944a1b3d515b5aaf54846d", "shasum": "" }, "require": { @@ -2945,20 +2945,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:11+00:00" + "time": "2024-10-16T12:07:28+00:00" }, { "name": "filament/support", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "31fcff80b873b4decdba10d5f7010310e12c8e94" + "reference": "85d83838ec0290fffba2be3f99a8b0840da1dc01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/31fcff80b873b4decdba10d5f7010310e12c8e94", - "reference": "31fcff80b873b4decdba10d5f7010310e12c8e94", + "url": "https://api.github.com/repos/filamentphp/support/zipball/85d83838ec0290fffba2be3f99a8b0840da1dc01", + "reference": "85d83838ec0290fffba2be3f99a8b0840da1dc01", "shasum": "" }, "require": { @@ -2969,7 +2969,7 @@ "illuminate/support": "^10.45|^11.0", "illuminate/view": "^10.45|^11.0", "kirschbaum-development/eloquent-power-joins": "^3.0|^4.0", - "livewire/livewire": "^3.4.10 <= 3.5.6", + "livewire/livewire": "^3.4.10", "php": "^8.1", "ryangjchandler/blade-capture-directive": "^0.2|^0.3|^1.0", "spatie/color": "^1.5", @@ -3004,20 +3004,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:29+00:00" + "time": "2024-10-16T12:07:44+00:00" }, { "name": "filament/tables", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "152bf46a8f2c46f047835771a67085c2866b039b" + "reference": "fac7e8e9a787aef94f45938fd47b50ea3f9d3bff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/152bf46a8f2c46f047835771a67085c2866b039b", - "reference": "152bf46a8f2c46f047835771a67085c2866b039b", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/fac7e8e9a787aef94f45938fd47b50ea3f9d3bff", + "reference": "fac7e8e9a787aef94f45938fd47b50ea3f9d3bff", "shasum": "" }, "require": { @@ -3056,11 +3056,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-10-08T14:24:25+00:00" + "time": "2024-10-16T12:07:46+00:00" }, { "name": "filament/widgets", - "version": "v3.2.117", + "version": "v3.2.118", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -6223,16 +6223,16 @@ }, { "name": "livewire/livewire", - "version": "v3.5.6", + "version": "v3.5.12", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f" + "reference": "3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/597a2808d8d3001cc3ed5ce89a6ebab00f83b80f", - "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f", + "url": "https://api.github.com/repos/livewire/livewire/zipball/3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d", + "reference": "3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d", "shasum": "" }, "require": { @@ -6240,7 +6240,7 @@ "illuminate/routing": "^10.0|^11.0", "illuminate/support": "^10.0|^11.0", "illuminate/validation": "^10.0|^11.0", - "laravel/prompts": "^0.1.24", + "laravel/prompts": "^0.1.24|^0.2|^0.3", "league/mime-type-detection": "^1.9", "php": "^8.1", "symfony/console": "^6.0|^7.0", @@ -6287,7 +6287,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.5.6" + "source": "https://github.com/livewire/livewire/tree/v3.5.12" }, "funding": [ { @@ -6295,7 +6295,7 @@ "type": "github" } ], - "time": "2024-08-19T11:52:18+00:00" + "time": "2024-10-15T19:35:06+00:00" }, { "name": "maennchen/zipstream-php", @@ -14911,36 +14911,37 @@ }, { "name": "larastan/larastan", - "version": "v2.9.8", + "version": "v2.9.9", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "340badd89b0eb5bddbc503a4829c08cf9a2819d7" + "reference": "148faa138f0d8acb7d85f4a55693d3e13b6048d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/340badd89b0eb5bddbc503a4829c08cf9a2819d7", - "reference": "340badd89b0eb5bddbc503a4829c08cf9a2819d7", + "url": "https://api.github.com/repos/larastan/larastan/zipball/148faa138f0d8acb7d85f4a55693d3e13b6048d2", + "reference": "148faa138f0d8acb7d85f4a55693d3e13b6048d2", "shasum": "" }, "require": { "ext-json": "*", - "illuminate/console": "^9.52.16 || ^10.28.0 || ^11.0", - "illuminate/container": "^9.52.16 || ^10.28.0 || ^11.0", - "illuminate/contracts": "^9.52.16 || ^10.28.0 || ^11.0", - "illuminate/database": "^9.52.16 || ^10.28.0 || ^11.0", - "illuminate/http": "^9.52.16 || ^10.28.0 || ^11.0", - "illuminate/pipeline": "^9.52.16 || ^10.28.0 || ^11.0", - "illuminate/support": "^9.52.16 || ^10.28.0 || ^11.0", + "illuminate/console": "^9.52.16 || ^10.28.0 || ^11.16", + "illuminate/container": "^9.52.16 || ^10.28.0 || ^11.16", + "illuminate/contracts": "^9.52.16 || ^10.28.0 || ^11.16", + "illuminate/database": "^9.52.16 || ^10.28.0 || ^11.16", + "illuminate/http": "^9.52.16 || ^10.28.0 || ^11.16", + "illuminate/pipeline": "^9.52.16 || ^10.28.0 || ^11.16", + "illuminate/support": "^9.52.16 || ^10.28.0 || ^11.16", "php": "^8.0.2", "phpmyadmin/sql-parser": "^5.9.0", - "phpstan/phpstan": "^1.11.2" + "phpstan/phpstan": "^1.12.5" }, "require-dev": { "doctrine/coding-standard": "^12.0", "nikic/php-parser": "^4.19.1", "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.2", "orchestra/testbench": "^7.33.0 || ^8.13.0 || ^9.0.3", + "phpstan/phpstan-deprecation-rules": "^1.2", "phpunit/phpunit": "^9.6.13 || ^10.5.16" }, "suggest": { @@ -14989,7 +14990,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v2.9.8" + "source": "https://github.com/larastan/larastan/tree/v2.9.9" }, "funding": [ { @@ -15009,7 +15010,7 @@ "type": "patreon" } ], - "time": "2024-07-06T17:46:02+00:00" + "time": "2024-10-15T19:41:22+00:00" }, { "name": "laravel/pint", diff --git a/lang/en.json b/lang/en.json deleted file mode 100644 index 9800982d..00000000 --- a/lang/en.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "The :attribute must be at least :length characters.": "The :attribute must be at least :length characters.", - "The given :attribute has appeared in a data leak. Please choose a different :attribute.": "The given :attribute has appeared in a data leak. Please choose a different :attribute.", - "Verify Email Address": "Verify Email Address", - "Please click the button below to verify your email address.": "Please click the button below to verify your email address.", - "If you did not create an account, no further action is required.": "If you did not create an account, no further action is required.", - "Articles soumis en attente d'approbation:" : "Pending approval articles:", - "[@:username](:profile_url) a soumit l'article :title le: :date" : "[@:username](:profile_url) submitted the article :title on: :date", - "Voir l'article" : "Voir l'article" -} diff --git a/lang/fr.json b/lang/fr.json deleted file mode 100644 index 9ef90469..00000000 --- a/lang/fr.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "The :attribute must be at least :length characters.": "Le champ :attribute doit contenir au moins :length caractères.", - "The given :attribute has appeared in a data leak. Please choose a different :attribute.": "Le champ :attribute donné est apparu dans une fuite de données. Veuillez choisir un autre :attribute.", - "Verify Email Address": "Vérifier l'adresse e-mail", - "Please click the button below to verify your email address.": "Veuillez cliquer sur le bouton ci-dessous pour vérifier votre adresse email.", - "If you did not create an account, no further action is required.": "Si vous n'avez pas créé de compte, aucune autre action n'est requise.", - "Articles soumis en attente d'approbation:" : "Articles soumis en attente d'approbation:", - "[@:username](:profile_url) a soumit l'article [:title](:url) le: :date" : "[@:username](:profile_url) a soumit l'article [:title](:url) le: :date", - "Voir l'article": "Voir l'article" -} diff --git a/lang/fr/pages/forum.php b/lang/fr/pages/forum.php new file mode 100644 index 00000000..7b89994b --- /dev/null +++ b/lang/fr/pages/forum.php @@ -0,0 +1,20 @@ + 'Forum :channel', + 'channel_selector' => 'Sélectionner un channel', + 'channel_placeholder' => 'Rechercher un channel', + 'channel_lists' => 'Toutes', + 'view_channel' => 'Afficher', + 'reset_channel' => 'Réinitialiser', + 'new_thread' => 'Nouveau sujet', + 'all_threads' => 'Tous les sujets', + 'info' => [ + 'title' => 'Bon à savoir', + 'description' => "Veuillez rechercher votre question avant de publier votre sujet en utilisant le champ de recherche dans la barre de navigation pour voir si elle n'a pas déjà été traitée.", + ], + +]; diff --git a/resources/views/components/forum/thread-overview.blade.php b/resources/views/components/forum/thread-overview.blade.php index 45c3f081..ed4f9698 100644 --- a/resources/views/components/forum/thread-overview.blade.php +++ b/resources/views/components/forum/thread-overview.blade.php @@ -26,9 +26,9 @@ @if (count($channels = $thread->channels->load('parent')))
@foreach ($channels as $channel) - + - + @endforeach
@endif diff --git a/resources/views/components/layouts/header.blade.php b/resources/views/components/layouts/header.blade.php index 70aaec63..3d209f8a 100644 --- a/resources/views/components/layouts/header.blade.php +++ b/resources/views/components/layouts/header.blade.php @@ -15,7 +15,7 @@
@include('partials._search') diff --git a/resources/views/components/link.blade.php b/resources/views/components/link.blade.php index c3ffd72d..5d711982 100644 --- a/resources/views/components/link.blade.php +++ b/resources/views/components/link.blade.php @@ -1,3 +1,3 @@ - + {{ $slot }} diff --git a/resources/views/components/status-message.blade.php b/resources/views/components/status-message.blade.php index b64bdb53..b169a91b 100644 --- a/resources/views/components/status-message.blade.php +++ b/resources/views/components/status-message.blade.php @@ -1,5 +1,5 @@ @if (session('status')) -
merge(['class' => 'rounded-md bg-green-50 p-4']) }}> +
merge(['class' => 'rounded-lg bg-green-50 p-4 dark:bg-green-800/20']) }}>