Skip to content

Commit 74f32e2

Browse files
committed
feat: (LAR-138) update user dashboard
1 parent 7efd57d commit 74f32e2

File tree

18 files changed

+543
-36
lines changed

18 files changed

+543
-36
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Article;
6+
7+
use App\Models\Article;
8+
use Illuminate\Support\Facades\DB;
9+
10+
final class ArticleDeleteAction
11+
{
12+
public function execute(Article $article): void
13+
{
14+
DB::beginTransaction();
15+
16+
$article->delete();
17+
18+
DB::commit();
19+
}
20+
}

app/Livewire/Pages/Account/Dashboard.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,14 @@ final class Dashboard extends Component
1818
#[Computed]
1919
public function user(): User
2020
{
21-
return User::with('articles')
21+
return User::query()
2222
->scopes('withCounts')
2323
->find(Auth::id());
2424
}
2525

2626
public function render(): View
2727
{
28-
return view('livewire.pages.account.dashboard', [
29-
'articles' => $this->user->articles()
30-
->orderByDesc('created_at')
31-
->orderBy('submitted_at')
32-
->paginate(12),
33-
])->title(__('pages/account.dashboard.title', ['username' => $this->user->username]));
28+
return view('livewire.pages.account.dashboard')
29+
->title(__('pages/account.dashboard.title', ['username' => $this->user->username]));
3430
}
3531
}

app/Livewire/Pages/Forum/DetailThread.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public function deleteAction(): Action
5454
->authorize('delete', $this->thread)
5555
->requiresConfirmation()
5656
->action(function (): void {
57-
5857
app(DeleteThreadAction::class)->execute($this->thread);
5958

6059
$this->redirectRoute('forum.index', navigate: true);

lang/en/pages/article.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@
2727
'canonical_help' => 'If you have already posted this article on your own site, enter the URL here and the content will be attributed to you.',
2828
'draft_help' => 'Putting an article in draft allows you to update it later.',
2929
'unpublished' => 'This article has not yet been published.',
30+
'draft' => 'Draft',
31+
'your_article' => 'Your Articles',
3032

3133
];

lang/en/pages/discussion.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,7 @@
4040
],
4141
'min_discussion_length' => '160 characters maximum',
4242
'placeholder' => 'Your comment here...',
43+
'your_discussion' => 'Your discussion',
44+
'write_discussion' => 'Write discussion',
4345

4446
];

lang/fr/pages/article.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@
2727
'canonical_help' => 'Précisez si l\'article a été publié pour la première fois ailleurs (comme sur votre propre blog).',
2828
'draft_help' => 'Mettre en article en brouillon vous donne la possibilité de le modifier plus tard',
2929
'unpublished' => 'Cet article n\'a pas encore été publié.',
30+
'draft' => 'Brouillon',
31+
'your_article' => 'Vos articles',
3032

3133
];

lang/fr/pages/discussion.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,7 @@
4040
],
4141
'min_discussion_length' => 'Maximum de 160 caractères.',
4242
'placeholder' => 'Votre commentaire',
43+
'your_discussion' => 'Vos Discussions',
44+
'write_discussion' => 'Rédiger une discussion',
4345

4446
];

resources/views/components/discussions/overview.blade.php

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,27 @@
33
'hiddenAuthor' => false,
44
])
55

6-
<div class="py-6">
6+
<div>
77
@if ($discussion->tags->isNotEmpty())
8-
<div class="flex items-center space-x-2 mb-4">
9-
@foreach ($discussion->tags as $tag)
10-
<x-tag
11-
:tag="$tag"
12-
:href="route('discussions.index', ['tag' => $tag->slug])"
13-
/>
14-
@endforeach
8+
<div class="flex justify-between space-x-2 mb-4">
9+
<div class="flex-1">
10+
@foreach ($discussion->tags as $tag)
11+
<x-tag
12+
:tag="$tag"
13+
:href="route('discussions.index', ['tag' => $tag->slug])"
14+
/>
15+
@endforeach
16+
</div>
17+
18+
<div>
19+
<button type="button"
20+
class="inline-flex rounded bg-warning-500 px-2.5 py-0.5 text-xs font-medium text-yellow-800"
21+
onclick="Livewire.dispatch('openPanel', { component: 'components.slideovers.discussion-form', arguments: { discussionId: {{ $discussion->id }} }})">
22+
{{ __('actions.edit') }}
23+
</button>
24+
25+
{{-- Mettre le bouton delete ici --}}
26+
</div>
1527
</div>
1628
@endif
1729

@@ -20,7 +32,7 @@
2032
{{ $discussion->title }}
2133
</x-link>
2234
</h2>
23-
<p class="mt-2 text-gray-500 dark:text-gray-400 line-clamp-2">
35+
<p class="mt-2 text-gray-500 dark:text-white line-clamp-2">
2436
{!! $discussion->excerpt(175) !!}
2537
</p>
2638

resources/views/components/forum/thread-channels.blade.php

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,30 @@
33
])
44

55
@if (count($channels = $thread->channels->load('parent')))
6-
<div {{ $attributes->twMerge(['class' => 'flex mb-2 flex-wrap gap-1.5']) }}>
7-
@foreach ($channels as $channel)
8-
@php
9-
$color = $channel->parent_id ? $channel->parent->color : $channel->color;
10-
@endphp
11-
<x-link :href="route('forum.channels', $channel)" class="flex gap-2">
12-
<x-forum.channel
13-
:channel="$channel"
14-
class="text-xs is-channel is-{{ $channel->slug }}"
15-
style="--channel-color: {{ $color }}"
16-
/>
17-
</x-link>
18-
@endforeach
6+
<div class="flex justify-between">
7+
<div {{ $attributes->twMerge(['class' => 'flex-1 mb-2 flex-wrap gap-1.5']) }}>
8+
@foreach ($channels as $channel)
9+
@php
10+
$color = $channel->parent_id ? $channel->parent->color : $channel->color;
11+
@endphp
12+
<x-link :href="route('forum.channels', $channel)" class="flex gap-2">
13+
<x-forum.channel
14+
:channel="$channel"
15+
class="text-xs is-channel is-{{ $channel->slug }}"
16+
style="--channel-color: {{ $color }}"
17+
/>
18+
</x-link>
19+
@endforeach
20+
</div>
21+
22+
<div>
23+
<button type="button"
24+
class="inline-flex rounded bg-warning-500 px-2.5 py-0.5 text-xs font-medium text-yellow-800"
25+
onclick="Livewire.dispatch('openPanel', { component: 'components.slideovers.thread-form', arguments: { threadId: {{ $thread->id }} }})">
26+
{{ __('actions.edit') }}
27+
</button>
28+
29+
{{-- Mettre le bouton delete ici --}}
30+
</div>
1931
</div>
2032
@endif

resources/views/components/forum/thread.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
'thread',
33
])
44

5-
<article class="rounded-xl cursor-pointer bg-white p-4 ring-1 ring-inset ring-gray-200/60 transition duration-200 ease-in-out dark:bg-gray-800 dark:ring-gray-800 dark:hover:bg-white/10 lg:py-5 lg:px-6" aria-labelledby="{{ $thread->slug }}">
5+
<article class="rounded-xl mb-8 p-6 cursor-pointer bg-white transition duration-200 ease-in-out dark:bg-gray-800 dark:ring-gray-800 dark:hover:bg-white/10 lg:py-5 lg:px-6" aria-labelledby="{{ $thread->slug }}">
66
<x-forum.thread-channels :thread="$thread" />
77

88
<div class="flex items-center gap-4">
9-
<h2 id="question-title-{{ $thread->id }}" class="truncate font-medium text-gray-900 dark:text-white lg:text-xl">
9+
<h2 id="question-title-{{ $thread->id }}" class="truncate text-xl font-medium text-gray-900 dark:text-white lg:text-xl">
1010
<x-link :href="route('forum.show', $thread)" class="hover:underline">
1111
{{ $thread->subject() }}
1212
</x-link>

resources/views/components/icon/tags/aws.blade.php

Whitespace-only changes.

resources/views/components/user/sidebar.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<span>{{ number_format($user->countArticles()) }}</span>
1010
</x-link>
1111

12-
<x-link :href="route('discussions.me')" :active="request()->routeIs('discussions.me')">
12+
<x-link :href="route('discussions.index')" :active="request()->routeIs('discussions.index')">
1313
<span class="flex-1">Discussions</span>
1414
<span>{{ number_format($user->countDiscussions()) }}</span>
1515
</x-link>
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use App\Actions\Article\ArticleDeleteAction;
6+
use App\Actions\Discussion\DeleteDiscussionAction;
7+
use App\Models\Article;
8+
use Filament\Actions\Action;
9+
use Filament\Actions\DeleteAction;
10+
use Filament\Notifications\Notification;
11+
use Livewire\Volt\Component;
12+
use Livewire\WithPagination;
13+
use Livewire\Attributes\Computed;
14+
use Livewire\WithoutUrlPagination;
15+
use Illuminate\Support\Facades\Auth;
16+
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
17+
18+
new class extends Component {
19+
20+
use WithPagination, WithoutUrlPagination;
21+
22+
#[Computed]
23+
public function articles(): LengthAwarePaginator
24+
{
25+
return Article::query()
26+
->where('user_id', Auth::id())
27+
->with(['user', 'tags', 'reactions'])
28+
->latest()
29+
->paginate(3);
30+
}
31+
32+
public function deleteArticle(Article $article): void
33+
{
34+
app(ArticleDeleteAction::class)->handle($article);
35+
36+
Notification::make()
37+
->title('Article supprimé avec succès')
38+
->success()
39+
->send();
40+
}
41+
42+
};
43+
?>
44+
45+
<div xmlns:x-filament-action="http://www.w3.org/1999/html">
46+
<main class="lg:col-span-9">
47+
<div class="md:flex md:items-center md:justify-between">
48+
<div class="min-w-0 flex-1">
49+
<h2 class="font-heading text-lg font-bold leading-7 text-gray-900 sm:truncate sm:text-xl">
50+
{{ __('pages/article.your_article') }}
51+
</h2>
52+
</div>
53+
<div class="mt-4 flex md:ml-4 md:mt-0">
54+
<x-buttons.primary class="justify-items-center" type="button"
55+
onclick="Livewire.dispatch('openPanel', { component: 'components.slideovers.article-form' })">
56+
<x-untitledui-message-text-square class="size-5 mr-2" aria-hidden="true" />
57+
{{ __('Rédiger un article') }}
58+
</x-buttons.primary>
59+
</div>
60+
</div>
61+
62+
<div class="mt-5 space-y-4">
63+
64+
@forelse ($this->articles as $article)
65+
<div
66+
class="rounded-xl mb-8 p-6 cursor-pointer bg-white transition duration-200 ease-in-out dark:bg-gray-800 dark:ring-gray-800 dark:hover:bg-white/10 lg:py-5 lg:px-6">
67+
<div class="flex justify-between space-x-3">
68+
<div class="flex-1">
69+
@if ($article->isNotPublished())
70+
<span
71+
class="inline-flex items-center rounded-full bg-yellow-100 px-2.5 py-0.5 text-xs font-medium text-yellow-800">
72+
{{ __('pages/article.draft') }}
73+
</span>
74+
@endif
75+
76+
@foreach ($article->tags as $tag)
77+
<x-tag :tag="$tag" />
78+
@endforeach
79+
</div>
80+
<div>
81+
@if ($article->isNotPublished())
82+
<button type="button"
83+
class="inline-flex rounded bg-warning-500 px-2.5 py-0.5 text-xs font-medium text-yellow-800"
84+
onclick="Livewire.dispatch('openPanel', { component: 'components.slideovers.article-form', arguments: { articleId: {{ $article->id }} }})">
85+
{{ __('actions.edit') }}
86+
</button>
87+
@endif
88+
89+
{{-- Mettre le bouton delete ici --}}
90+
91+
</div>
92+
</div>
93+
94+
<a href="{{ route('articles.show', $article->slug) }}" class="block">
95+
<div class="mt-4 flex items-center justify-between">
96+
<h3 class="font-heading/7 text-xl font-semibold text-gray-900 dark:text-white">
97+
{{ $article->title }}
98+
</h3>
99+
100+
<div class="flex items-center font-sans text-gray-400 dark:text-gray-500">
101+
@if ($article->isPublished())
102+
<a href="{{ route('articles.show', $article->slug) }}"
103+
class="hover:text-gray-500 dark:text-gray-400 hover:underline">
104+
Voir
105+
</a>
106+
<span class="mx-1">&middot;</span>
107+
@endif
108+
</div>
109+
</div>
110+
111+
<p class="mt-3 text-base font-normal leading-6 text-gray-500 dark:text-white">
112+
{{ $article->excerpt() }}
113+
</p>
114+
</a>
115+
116+
<div class="mt-6 flex items-center justify-between">
117+
<div class="flex items-center">
118+
<a href="{{ route('profile', $article->user->username) }}" class="shrink-0">
119+
<img class="size-10 rounded-full object-cover"
120+
src="{{ $article->user->profile_photo_url }}"
121+
alt="{{ $article->user->username }}" />
122+
</a>
123+
124+
<div class="ml-3 font-sans">
125+
<p class="text-sm font-medium leading-5 text-gray-700 dark:text-white">
126+
<a href="{{ route('profile', $article->user->username) }}" class="hover:underline">
127+
{{ $article->user->name }}
128+
</a>
129+
</p>
130+
131+
<div class="flex text-sm leading-5 text-gray-500 dark:text-gray-400">
132+
@if ($article->isPublished())
133+
<time datetime="{{ $article->submitted_at->format('Y-m-d') }}">
134+
{{ __('Publié le :date', ['date' => $article->submitted_at->format('j M, Y')]) }}
135+
</time>
136+
@else
137+
@if ($article->isAwaitingApproval())
138+
<span>En attente d'approbation</span>
139+
@else
140+
<time datetime="{{ $article->updated_at->format('Y-m-d') }}">
141+
Rédigé
142+
<time-ago time="{{ $article->updated_at->getTimestamp() }}" />
143+
</time>
144+
@endif
145+
@endif
146+
147+
<span class="mx-1">&middot;</span>
148+
<span>{{ $article->readTime() }} min de lecture</span>
149+
</div>
150+
</div>
151+
</div>
152+
153+
<div class="flex items-center text-gray-500 dark:text-gray-400">
154+
<span class="mr-2 text-xl">👏</span>
155+
{{ count($article->reactions) }}
156+
</div>
157+
</div>
158+
</div>
159+
@empty
160+
<p class="text-base text-gray-500 dark:text-gray-400">Vous n'avez pas encore créé d'articles.</p>
161+
@endforelse
162+
163+
</div>
164+
</main>
165+
</div>

0 commit comments

Comments
 (0)