diff --git a/app/Http/Controllers/DynamicController.php b/app/Http/Controllers/DynamicController.php index 6187a4a..00d581f 100644 --- a/app/Http/Controllers/DynamicController.php +++ b/app/Http/Controllers/DynamicController.php @@ -52,17 +52,7 @@ class DynamicController extends Controller $activityService->updateCursor($request->user(), $dynamic); - $dynamic->load([ - 'ledgers.media', - 'participants' => fn($query) => $query->withPivot('display_name'), - 'chat.messages.user', - 'chat.messages.media', - 'chat.messages.subject' => function ($morphTo) { - $morphTo->morphWith([ - \App\Models\Mutation::class => ['ledger'], - ]); - } - ]); + $dynamic->load(['ledgers.media', 'participants', 'chat']); $isOwner = $dynamic->participants() ->where('user_id', $request->user()->id) @@ -72,9 +62,17 @@ class DynamicController extends Controller return Inertia::render('Dynamics/Show', [ 'dynamic' => $dynamic, 'isOwner' => $isOwner, + 'messages' => $dynamic->chat->messages()->with(['user', 'media'])->latest()->paginate(20), ]); } + public function messages(Request $request, Dynamic $dynamic) + { + $this->authorize('view', $dynamic); + + return $dynamic->chat->messages()->with(['user', 'media'])->latest()->paginate(20); + } + /** * Show the form for editing the specified resource. */ diff --git a/app/Http/Controllers/LedgerController.php b/app/Http/Controllers/LedgerController.php index 7968190..efb3abf 100644 --- a/app/Http/Controllers/LedgerController.php +++ b/app/Http/Controllers/LedgerController.php @@ -64,7 +64,7 @@ class LedgerController extends Controller $activityService->updateCursor($request->user(), $ledger); - $dynamic->load(['chat', 'participants' => fn($query) => $query->withPivot('display_name')]); + $dynamic->load('chat', 'participants'); $ledger->load([ 'media', @@ -91,9 +91,17 @@ class LedgerController extends Controller 'dynamic' => $dynamic, 'ledger' => $ledger, 'isOwner' => $isOwner, + 'messages' => $dynamic->chat->messages()->with(['user', 'media'])->latest()->paginate(20), ]); } + public function messages(Request $request, Dynamic $dynamic, Ledger $ledger) + { + $this->authorize('view', $ledger); + + return $dynamic->chat->messages()->with(['user', 'media'])->latest()->paginate(20); + } + /** * Show the form for editing the specified resource. */ diff --git a/app/Http/Controllers/ParticipantController.php b/app/Http/Controllers/ParticipantController.php index ee3fbb1..040db65 100644 --- a/app/Http/Controllers/ParticipantController.php +++ b/app/Http/Controllers/ParticipantController.php @@ -4,11 +4,29 @@ namespace App\Http\Controllers; use App\Models\Dynamic; use App\Models\User; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Http\Request; use Inertia\Inertia; class ParticipantController extends Controller { + use AuthorizesRequests; + + public function update(Request $request, Dynamic $dynamic) + { + $request->validate([ + 'display_name' => ['required', 'string', 'max:255'], + ]); + + $participant = $dynamic->participants()->where('user_id', $request->user()->id)->firstOrFail(); + + $dynamic->participants()->updateExistingPivot($participant->id, [ + 'display_name' => $request->input('display_name'), + ]); + + return redirect()->back()->with('success', 'Display name updated successfully!'); + } + public function show(Request $request, Dynamic $dynamic, User $user) { // Ensure both the authenticated user and the target user are in the dynamic @@ -25,7 +43,7 @@ class ParticipantController extends Controller ->take(10) ->get(); - return Inertia::render('Participants/Show', [ + return Inertia::render('Dynamics/Participants/Show', [ 'dynamic' => $dynamic, 'participant' => [ 'id' => $user->id, @@ -37,18 +55,4 @@ class ParticipantController extends Controller ]); } - public function update(Request $request, Dynamic $dynamic) - { - $request->validate([ - 'display_name' => ['required', 'string', 'max:255'], - ]); - - $participant = $dynamic->participants()->where('user_id', $request->user()->id)->firstOrFail(); - - $dynamic->participants()->updateExistingPivot($participant->id, [ - 'display_name' => $request->input('display_name'), - ]); - - return redirect()->back()->with('success', 'Display name updated successfully!'); - } } diff --git a/resources/css/components/chat.css b/resources/css/components/chat.css index 9b8180a..21aa081 100644 --- a/resources/css/components/chat.css +++ b/resources/css/components/chat.css @@ -10,6 +10,19 @@ .c-chat__list { @apply mt-4 flex flex-col gap-3; + .c-chat__load-more { + @apply mb-4 text-center; + + .c-chat__load-more-btn { + @apply text-sm font-semibold; + color: var(--primary); + + &:hover { + text-decoration: underline; + } + } + } + .c-chat__message { @apply overflow-hidden p-4 shadow-sm sm:rounded-lg; border: 1px solid var(--border); diff --git a/resources/js/components/Chat.vue b/resources/js/components/Chat.vue index 3a70cf8..4b6d5cc 100644 --- a/resources/js/components/Chat.vue +++ b/resources/js/components/Chat.vue @@ -1,15 +1,15 @@ + + diff --git a/resources/js/components/ParticipantsList.vue b/resources/js/components/ParticipantsList.vue index 61bb71e..9c6215a 100644 --- a/resources/js/components/ParticipantsList.vue +++ b/resources/js/components/ParticipantsList.vue @@ -1,5 +1,9 @@ + + + + diff --git a/resources/js/pages/Dynamics/Show.vue b/resources/js/pages/Dynamics/Show.vue index e806e28..8b2a8a9 100644 --- a/resources/js/pages/Dynamics/Show.vue +++ b/resources/js/pages/Dynamics/Show.vue @@ -21,6 +21,10 @@ const props = defineProps<{ }>; }; isOwner: boolean; + messages: { + data: Array; + next_page_url: string | null; + }; }>(); @@ -58,7 +62,7 @@ const breadcrumbs = [ - + diff --git a/resources/js/pages/Ledgers/Show.vue b/resources/js/pages/Ledgers/Show.vue index 03b3587..dff1c6c 100644 --- a/resources/js/pages/Ledgers/Show.vue +++ b/resources/js/pages/Ledgers/Show.vue @@ -4,6 +4,7 @@ import { useEcho } from '@laravel/echo-vue'; import { ref } from 'vue'; import { route } from 'ziggy-js'; import AddMutationForm from '@/components/AddMutationForm.vue'; +import Chat from '@/components/Chat.vue'; import MutationList from '@/components/MutationList.vue'; const props = defineProps<{ @@ -37,6 +38,10 @@ const props = defineProps<{ }>; }; isOwner: boolean; + messages: { + data: Array; + next_page_url: string | null; + }; }>(); const breadcrumbs = [ @@ -258,6 +263,8 @@ function isOwnerUser(userId: number): boolean { :ledger-alignment="ledger.alignment" @open-lightbox="openLightbox" /> + + diff --git a/routes/web.php b/routes/web.php index 2773721..2fc2830 100644 --- a/routes/web.php +++ b/routes/web.php @@ -15,8 +15,10 @@ Route::middleware(['auth', 'verified'])->group(function () { Route::resource('dynamics', DynamicController::class)->except(['edit', 'update']); Route::get('/dynamics/{dynamic}/settings', [DynamicController::class, 'edit'])->name('dynamics.edit'); Route::patch('/dynamics/{dynamic}/settings', [DynamicController::class, 'update'])->name('dynamics.update'); + Route::get('/dynamics/{dynamic}/messages', [DynamicController::class, 'messages'])->name('dynamics.messages'); Route::get('/dynamics/{dynamic}/ledgers/create', [LedgerController::class, 'create'])->name('dynamics.ledgers.create'); + Route::get('/dynamics/{dynamic}/ledgers/{ledger}/messages', [LedgerController::class, 'messages'])->name('dynamics.ledgers.messages'); Route::resource('dynamics.ledgers', LedgerController::class)->scoped()->except(['create']); Route::resource('dynamics.ledgers.predefined-mutations', \App\Http\Controllers\PredefinedMutationController::class)->scoped(); diff --git a/tests/Feature/ParticipantDetailTest.php b/tests/Feature/ParticipantDetailTest.php index e39b4db..185cfcc 100644 --- a/tests/Feature/ParticipantDetailTest.php +++ b/tests/Feature/ParticipantDetailTest.php @@ -19,7 +19,7 @@ test('authenticated participant can view another participant detail page in dyna $response->assertOk(); $response->assertInertia(fn ($page) => $page - ->component('Participants/Show') + ->component('Dynamics/Participants/Show') ->has('dynamic') ->where('participant.id', $participant->id) ->where('participant.name', $participant->name) @@ -86,7 +86,7 @@ test('participant detail page displays their recent mutations in dynamic', funct $response->assertOk(); $response->assertInertia(fn ($page) => $page - ->component('Participants/Show') + ->component('Dynamics/Participants/Show') ->where('participant.display_name', 'Bitch') ->has('mutations', 2) ->where('mutations.0.description', 'Infraction 1') // Ordered latest first