laravel + livewire + tailwind - admin の機能を追加

(2025-01-09)

admin にメンバー削除とメンバー編集の機能を追加します。

livewire コンポーネント作成と編集

php artisan make:livewire Admin/DeleteMember
php artisan make:livewire Admin/MemberEditList
php artisan make:livewire Admin/EditMember

app/Livewire/Admin/DeleteMember.php

app/Livewire/Admin/DeleteMember.php
<?php
namespace App\Livewire\Admin;
use Livewire\Component;
use App\Models\User;
class DeleteMember extends Component
{
public $userId;
public function deleteMember($id)
{
$user = User::find($id);
if ($user) {
$user->delete();
session()->flash('message', 'メンバーが削除されました。');
} else {
session()->flash('error', 'メンバーが見つかりませんでした。');
}
}
public function render()
{
$users = User::where('role', '!=', 'admin')->get(); // 管理者以外を取得
return view('livewire.admin.delete-member', ['users' => $users]);
}
}

app/Livewire/Admin/MemberEditListr.php

app/Livewire/Admin/MemberEditList.php
<?php
namespace App\Livewire\Admin;
use Livewire\Component;
use App\Models\User;
class MemberEditList extends Component
{
public $members;
public function mount()
{
$this->members = User::all(); // すべてのメンバーを取得
}
public function render()
{
return view('livewire.admin.member-edit-list');
}
}

app/Livewire/Admin/EditMember.php

app/Livewire/Admin/EditMember.php
<?php
namespace App\Livewire\Admin;
use Livewire\Component;
use App\Models\User;
use Illuminate\Validation\Rule;
class EditMember extends Component
{
public $userId;
public $name;
public $email;
public $role;
public function mount($userId)
{
$user = User::findOrFail($userId);
$this->userId = $user->id;
$this->name = $user->name;
$this->email = $user->email;
$this->role = $user->role;
}
public function update()
{
$this->validate([
'name' => 'required|string|max:255',
'email' => [
'required',
'email',
'max:255',
Rule::unique('users')->ignore($this->userId),
],
'role' => 'required|string|in:user,admin',
]);
$user = User::findOrFail($this->userId);
$user->update([
'name' => $this->name,
'email' => $this->email,
'role' => $this->role,
]);
session()->flash('message', 'メンバー情報が更新されました。');
return redirect()->route('admin.dashboard');
}
public function render()
{
return view('livewire.admin.edit-member');
}
}

blade の編集

resources/views/livewire/admin/delete-member.blade.php

resources/views/livewire/admin/delete-member.blade.php
<div class="m-3">
<h1 class="text-xl font-bold mb-4 border border-gray-500 bg-slate-200 px-4 py-2">メンバー一覧</h1>
@if (session()->has('message'))
<div class="bg-green-500 text-white p-2 rounded">
{{ session('message') }}
</div>
@elseif (session()->has('error'))
<div class="bg-red-500 text-white p-2 rounded">
{{ session('error') }}
</div>
@endif
<p class="border border-slate-300 p-2 rounded shadow-md bg-gray-50 leading-7">
メンバーを削除します。<br>
削除ボタンを押すと確認画面が表示されることなくメンバー情報が削除されます。<br>
そのユーザー名で記録されたコメント欄のメンバー名も表示されなくなります。
</p>
<div class="mt-5 mx-3"><a href="{{ route('dashboard') }}" class="px-4 py-2 bg-orange-900 text-white rounded hover:bg-orange-700">トップへ</a></div>
<table class=" bg-white shadow-md mt-8">
<thead>
<tr>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white"ID</th>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white">名前</th>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white">メール</th>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white">操作</th>
</tr>
</thead>
<tbody>
@foreach($users as $user)
<tr>
<td class="border px-4 py-1">{{ $user->id }}</td>
<td class="border px-4 py-1">{{ $user->name }}</td>
<td class="border px-4 py-1">{{ $user->email }}</td>
<td class="border px-4 py-1 text-center">
<button
class="bg-red-700 text-white px-4 py-1 rounded"
wire:click="deleteMember({{ $user->id }})"
>
削除
</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>

resources/views/livewire/admin/member-edit-list.blade.php

resources/views/livewire/admin/member-edit-list.blade.php
<div class="p-4">
<h1 class="text-xl font-bold mb-4 border border-gray-500 bg-slate-200 px-4 py-2">メンバーリスト</h1>
<table class="border-collapse border border-gray-600 text-left mx-3">
<thead>
<tr>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white">名前</th>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white">メール</th>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white">ロール</th>
<th class="border border-gray-300 px-4 py-1 bg-sky-900 text-white">操作</th>
</tr>
</thead>
<tbody>
@foreach ($members as $member)
<tr>
<td class="py-2 px-4 border">{{ $member->name }}</td>
<td class="py-2 px-4 border">{{ $member->email }}</td>
<td class="py-2 px-4 border">{{ $member->role }}</td>
<td class="py-2 px-4 border">
<a href="{{ route('admin.edit-member', ['userId' => $member->id]) }}" class="text-blue-600 hover:text-blue-900">編集</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>

resources/views/livewire/admin/edit-member.blade.php

resources/views/livewire/admin/edit-member.blade.php
<!-- edit-member.blade.php -->
<div class="p-4">
<h1 class="text-xl font-bold mb-4 border border-gray-500 bg-slate-200 px-4 py-2">メンバー編集</h2>
<form wire:submit.prevent="update">
<div class="mb-4">
<label for="name" class="block font-medium text-gray-700">名前</label>
<input type="text" id="name" wire:model="name" class="mt-1 block w-96" required>
</div>
<div class="mb-4">
<label for="email" class="block font-medium text-gray-700">メールアドレス</label>
<input type="email" id="email" wire:model="email" class="mt-1 block w-96" required>
</div>
<div class="mb-4">
<label for="role" class="block font-medium text-gray-700">役割</label>
<select id="role" wire:model="role" class="mt-1 block w-96" required>
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
</div>
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">更新</button>
</form>
@if (session()->has('message'))
<div class="mt-4 text-green-600">
{{ session('message') }}
</div>
@endif
</div>

resources/views/livewire/admin/admin-dashboard.blade.php の編集。

resources/views/livewire/admin/edit-member.blade.php
<div class="p-4">
<h1 class="text-xl font-bold mb-4 border border-gray-500 bg-slate-200 px-4 py-2">管理者ダッシュボード</h1>
<p class="border border-slate-300 p-3 rounded mb-5 shadow-md bg-white">
ここで管理者用の情報を管理できます。<br>
以下のメニューから選びます。
</p>
<div class="my-5 mx-3">
<a href="{{ route('admin.create-member') }}" class="btn btn-primary px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">メンバー作成</a>
</div>
<div class="my-5 mx-3">
<a href="{{ route('admin.member-list') }}" class="btn btn-primary px-4 py-2 bg-sky-800 text-white rounded hover:bg-orange-700">メンバー編集</a>
</div>
<div class="my-5 mx-3">
<a href="{{ route('admin.delete-member') }}" class="btn btn-primary px-4 py-2 bg-orange-800 text-white rounded hover:bg-orange-700">メンバー削除</a>
</div>
<div class="mt-8 mx-3">
<a href="{{ route('dashboard') }}" class="px-4 py-2 bg-orange-900 text-white rounded hover:bg-orange-700">トップへ</a>
</div>
</div>

routing

routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Livewire\ThemeCreate;
use App\Livewire\ThemeList;
use App\Livewire\ThemeShow;
use App\Livewire\ZipImage;
use App\Livewire\ThemeImage;
use App\Http\Middleware\AdminMiddleware;
use App\Livewire\Admin\AdminDashboard;
use App\Http\Controllers\ProfileController;
use App\Mail\ThemeCreatedNotification;
use Illuminate\Support\Facades\Log;
use App\Livewire\SendWriteRequest;
Route::get('/', function () {
return view('welcome');
})->name('home');
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
Route::middleware('auth')->group(function () {
Route::get('/theme/create', ThemeCreate::class)->name('theme.create');
Route::get('/theme/list', ThemeList::class)->name('theme.list');
Route::get('/theme/{theme_id}', ThemeShow::class)->name('theme.show');
Route::get('/zip-image', ZipImage::class)->name('zip.image');
Route::get('/theme/{theme_id}/images/{folderName?}', ThemeImage::class)->name('theme.image');
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
Route::get('/send-request', SendWriteRequest::class)->name('send.request');
});
Route::middleware(['auth', AdminMiddleware::class])->group(function () {
Route::get('/admin/dashboard', AdminDashboard::class)->name('admin.dashboard');
Route::get('/admin/create-member', \App\Livewire\Admin\CreateMember::class)->name('admin.create-member');
Route::get('/admin/delete-member', \App\Livewire\Admin\DeleteMember::class)->name('admin.delete-member');
Route::get('/admin/member-list', \App\Livewire\Admin\MemberEditList::class)->name('admin.member-list');
Route::get('/admin/edit-member/{userId}', \App\Livewire\Admin\EditMember::class)->name('admin.edit-member');
});
require __DIR__.'/auth.php';