Pengaturan Profil
Profile Settings adalah Account Page tempat signed-in user dapat:
- mengubah nama;
- mengubah alamat email;
- resend verification link;
- menghapus account.
Page dirender di dalam Panel aktif.
PandaBear bertanggung jawab terhadap screen, sedangkan application tetap bertanggung jawab terhadap write.
Gunakan dokumentasi ini untuk mengetahui:
- props yang dikirim;
- endpoint yang digunakan;
- dependency host application;
- serta bagian yang harus tetap disediakan application.
Contoh Minimal
Tidak ada registrasi tambahan.
Panel biasa sudah mendapatkan Settings Pages:
<?php
declare(strict_types=1);
namespace App\Panels\Admin;
use PandaPanel\Core\Panel;
use PandaPanel\Core\PanelProvider;
final class AdminPanelProvider
extends PanelProvider
{
public function panel(
Panel $panel
): Panel {
return $panel
->path('admin')
->auth();
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Route:
php artisan route:list --name=panel.admin.pages.settings-profileGET admin/settings/profile panel.admin.pages.settings-profilePage Class
PandaPanel\Pages\Settings\ProfileSettingsextends:
PandaPanel\Pages\Page| Member | Value |
|---|---|
$title | 'Profile' |
$subheading | 'Update your name and email address.' |
$slug | 'settings-profile' |
$component | 'panel/settings/Profile' |
$navigationIcon | 'user' |
$navigationGroup | 'Account' |
$navigationSort | 10 |
$middleware | tidak ada |
routePath() | 'settings/profile' |
Slug tetap satu segment:
settings-profilesementara route path:
settings/profileSlug digunakan sebagai registry/route-name key.
Path adalah URL yang dilihat user.
Contoh:
use PandaPanel\Pages\Settings\ProfileSettings;
ProfileSettings::routeName(
'admin'
);
// panel.admin.pages.settings-profile
ProfileSettings::url(
'admin'
);
// /admin/settings/profile
ProfileSettings::url(
'app'
);
// /app/settings/profile2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Setiap Panel memiliki copy Page-nya sendiri.
Props
public function props(): array
{
return [
'mustVerifyEmail' =>
Auth::user()
instanceof MustVerifyEmail,
'status' =>
session(
'status'
),
];
}2
3
4
5
6
7
8
9
10
11
12
13
| Prop | Type | Arti |
|---|---|---|
mustVerifyEmail | bool | User mengimplementasikan MustVerifyEmail |
status | string|null | Session flash status |
User sendiri tidak dikirim oleh Page.
Vue membaca:
usePage().props.auth.useryang harus dibagikan application melalui HandleInertiaRequests.
Contoh:
public function share(
Request $request
): array {
return [
...parent::share(
$request
),
'auth' => [
'user' =>
$request->user(),
],
];
}2
3
4
5
6
7
8
9
10
11
12
13
14
PandaBear SharePanelData sengaja tidak membagikan auth.
Authenticated user adalah concern application-wide, bukan Panel-only concern.
Frontend
resources/js/pages/panel/settings/Profile.vueContoh:
<script setup lang="ts">
import {
Form,
usePage,
} from '@inertiajs/vue3';
import {
computed,
} from 'vue';
import ProfileController
from '@/actions/App/Http/Controllers/Settings/ProfileController';
import DeleteUser
from '@/components/DeleteUser.vue';
import {
send,
} from '@/routes/verification';
const user = computed(
() =>
usePage()
.props
.auth
.user,
);
</script>
<template>
<Form
v-slot="{ errors, processing }"
v-bind="ProfileController.update.form()"
>
<!-- name, email -->
</Form>
<DeleteUser />
</template>2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Tiga write operation:
| Control | Target |
|---|---|
| Save Profile | PATCH /settings/profile melalui application ProfileController |
| Resend Verification | Fortify verification.send |
| Delete Account | DELETE /settings/profile melalui application |
Tidak satupun merupakan PandaBear write route.
Write Tetap Milik Application
Contoh application controller:
<?php
declare(strict_types=1);
namespace App\Http\Controllers\Settings;
use App\Models\User;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
final class ProfileController
{
public function update(
Request $request
): RedirectResponse {
$user =
$request->user();
abort_if(
! $user instanceof User,
403
);
$validated =
$request->validate([
'name' => [
'required',
'string',
'max:255',
],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique(
User::class
)
->ignore(
$user->id
),
],
]);
$user->fill(
$validated
);
if (
$user
->isDirty(
'email'
)
&& $user
instanceof
MustVerifyEmail
) {
$user
->email_verified_at =
null;
}
$user->save();
return back()
->with(
'success',
'Profile updated.'
);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
Dua detail penting:
- hanya validated attributes yang diassign;
- email verification direset ketika address berubah.
Dengan whitelist validation, request tambahan seperti:
is_admin=truetidak ikut masuk.
back()->with('success') kemudian diterjemahkan ShareFlashToast menjadi Panel toast.
Mempertahankan /settings/profile
Jika screen lama dipindahkan ke Panel, application dapat mempertahankan URL lama sebagai redirect alias.
Contoh:
Route::middleware(
'auth'
)
->group(
function (): void {
Route::get(
'settings',
[
SettingsRedirectController::class,
'profile',
]
);
Route::get(
'settings/profile',
[
SettingsRedirectController::class,
'profile',
]
)
->name(
'profile.edit'
);
Route::patch(
'settings/profile',
[
ProfileController::class,
'update',
]
)
->name(
'profile.update'
);
}
);2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Screen berpindah ke Panel.
Write endpoint tetap sama.
Redirect dapat mencari Panel pertama yang benar-benar dapat diakses:
private function toPanel(
Request $request,
string $page
): RedirectResponse {
$panel =
app(
PandaPanel\Core\PanelManager::class
)
->firstAccessibleTo(
$request->user()
);
abort_if(
$panel === null
|| ! $panel
->hasSettings(),
403
);
return redirect(
$page::url(
$panel
)
);
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Mematikan Page
public function settings(
bool $settings = true
): self;
public function hasSettings():
bool;2
3
4
5
6
Panel::make(
'kiosk'
)
->settings(false)
->getPages();
// []2
3
4
5
6
7
Settings bersifat:
Profile + Security + Appearancesecara sekaligus.
Testing
use Inertia\Testing\AssertableInertia;
it(
'renders the profile settings page in the panel shell',
function (): void {
$this
->actingAs(
$admin
)
->get(
'/admin/settings/profile'
)
->assertOk()
->assertInertia(
fn (
AssertableInertia $page
) =>
$page
->component(
'panel/settings/Profile'
)
->where(
'panel.id',
'admin'
)
->where(
'page.title',
'Profile'
)
->has(
'mustVerifyEmail'
)
);
}
);2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Panel access:
$this
->actingAs(
$member
)
->get(
'/admin/settings/profile'
)
->assertForbidden();2
3
4
5
6
7
8
Guest:
$this
->get(
'/app/settings/profile'
)
->assertRedirect(
route(
'login'
)
);2
3
4
5
6
7
8
9
Hal yang Perlu Diperhatikan
- Route Page hanya GET.
- POST ke
/admin/settings/profilemenghasilkan 405. - Page membutuhkan host modules seperti ProfileController, verification route, dan DeleteUser dependencies.
auth.userharus dibagikan application melalui Inertia.- Delete Account juga tetap menggunakan application endpoint.
- Panel access diperiksa sebelum Page.
- PandaBear tidak otomatis mengosongkan
email_verified_atketika email berubah. Logic tersebut harus ada di application controller.