feat: add dashboard page with Nuxt UI components and verified middleware
This commit is contained in:
14
app/Http/Controllers/DashboardController.php
Normal file
14
app/Http/Controllers/DashboardController.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function __invoke(): Response
|
||||
{
|
||||
return Inertia::render('Dashboard');
|
||||
}
|
||||
}
|
||||
@@ -113,9 +113,9 @@ return [
|
||||
*/
|
||||
|
||||
'redirects' => [
|
||||
'login' => env('AUTH_REDIRECT_LOGIN', '/'),
|
||||
'login' => env('AUTH_REDIRECT_LOGIN', '/dashboard'),
|
||||
'logout' => env('AUTH_REDIRECT_LOGOUT', '/'),
|
||||
'register' => env('AUTH_REDIRECT_REGISTER', '/'),
|
||||
'register' => env('AUTH_REDIRECT_REGISTER', '/dashboard'),
|
||||
],
|
||||
|
||||
/*
|
||||
|
||||
99
resources/js/Pages/Dashboard.vue
Normal file
99
resources/js/Pages/Dashboard.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<script setup lang="ts">
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
import DashboardLayout from '@/layouts/DashboardLayout.vue'
|
||||
|
||||
defineOptions({
|
||||
layout: DashboardLayout,
|
||||
})
|
||||
|
||||
const { user } = useAuth()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardPanel>
|
||||
<template #header>
|
||||
<UDashboardNavbar title="Dashboard" />
|
||||
</template>
|
||||
|
||||
<template #body>
|
||||
<div class="flex flex-col gap-6">
|
||||
<UCard>
|
||||
<div class="flex items-center gap-4">
|
||||
<UIcon name="i-lucide-shield-check" class="text-primary size-8" />
|
||||
<div>
|
||||
<h2 class="text-lg font-medium">
|
||||
Welcome back, {{ user?.first_name }}!
|
||||
</h2>
|
||||
<p class="text-muted text-sm">
|
||||
Your email is verified and you have access to this protected page.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<UCard>
|
||||
<div class="flex items-center gap-3">
|
||||
<UIcon name="i-lucide-lock" class="text-primary size-5" />
|
||||
<div>
|
||||
<p class="text-sm font-medium">
|
||||
Auth Middleware
|
||||
</p>
|
||||
<p class="text-muted text-xs">
|
||||
Route requires authentication
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
<UCard>
|
||||
<div class="flex items-center gap-3">
|
||||
<UIcon name="i-lucide-mail-check" class="text-primary size-5" />
|
||||
<div>
|
||||
<p class="text-sm font-medium">
|
||||
Verified Middleware
|
||||
</p>
|
||||
<p class="text-muted text-xs">
|
||||
Route requires email verification
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
<UCard>
|
||||
<div class="flex items-center gap-3">
|
||||
<UIcon name="i-lucide-layout-dashboard" class="text-primary size-5" />
|
||||
<div>
|
||||
<p class="text-sm font-medium">
|
||||
Nuxt UI Dashboard
|
||||
</p>
|
||||
<p class="text-muted text-xs">
|
||||
Built with dashboard components
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
<UCard>
|
||||
<template #header>
|
||||
<h3 class="font-medium">
|
||||
Route Protection
|
||||
</h3>
|
||||
</template>
|
||||
<div class="text-sm space-y-2">
|
||||
<p class="text-muted">
|
||||
This page is protected with both <code class="bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded text-xs">auth</code> and <code class="bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded text-xs">verified</code> middleware. Unauthenticated users are redirected to login, and unverified users are redirected to the email verification page.
|
||||
</p>
|
||||
<UAlert
|
||||
icon="i-lucide-info"
|
||||
color="info"
|
||||
variant="subtle"
|
||||
title="Enable email verification by setting AUTH_ENABLE_EMAIL_VERIFICATION=true in your .env file."
|
||||
/>
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
</template>
|
||||
</UDashboardPanel>
|
||||
</template>
|
||||
@@ -20,6 +20,9 @@ function logout() {
|
||||
<div class="min-h-screen flex flex-col bg-gray-100 dark:bg-gray-900">
|
||||
<header class="flex items-center justify-end gap-4 p-4">
|
||||
<template v-if="isAuthenticated">
|
||||
<UButton to="/dashboard" variant="ghost">
|
||||
Dashboard
|
||||
</UButton>
|
||||
<span class="text-sm text-gray-600 dark:text-gray-400">
|
||||
{{ user?.full_name }}
|
||||
</span>
|
||||
|
||||
58
resources/js/layouts/DashboardLayout.vue
Normal file
58
resources/js/layouts/DashboardLayout.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import { useForm } from '@inertiajs/vue3'
|
||||
import Logo from '@/components/common/Logo.vue'
|
||||
import { useAuth } from '@/composables/useAuth'
|
||||
|
||||
const { user } = useAuth()
|
||||
|
||||
const logoutForm = useForm({})
|
||||
|
||||
function logout() {
|
||||
logoutForm.post('/logout')
|
||||
}
|
||||
|
||||
const sidebarLinks = [
|
||||
{
|
||||
label: 'Dashboard',
|
||||
icon: 'i-lucide-house',
|
||||
to: '/dashboard',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UApp>
|
||||
<UDashboardGroup>
|
||||
<UDashboardSidebar collapsible>
|
||||
<template #header>
|
||||
<Logo :link-to-home="false" size="sm" />
|
||||
</template>
|
||||
|
||||
<UNavigationMenu :items="sidebarLinks" />
|
||||
|
||||
<template #footer>
|
||||
<div class="flex items-center gap-2 px-2">
|
||||
<UAvatar :alt="user?.full_name" size="sm" />
|
||||
<div class="flex-1 truncate text-sm">
|
||||
<p class="font-medium truncate">
|
||||
{{ user?.full_name }}
|
||||
</p>
|
||||
<p class="text-muted truncate text-xs">
|
||||
{{ user?.email }}
|
||||
</p>
|
||||
</div>
|
||||
<UButton
|
||||
icon="i-lucide-log-out"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
:loading="logoutForm.processing"
|
||||
@click="logout"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</UDashboardSidebar>
|
||||
|
||||
<slot />
|
||||
</UDashboardGroup>
|
||||
</UApp>
|
||||
</template>
|
||||
@@ -1,10 +1,20 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\DashboardController;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Inertia\Inertia;
|
||||
|
||||
Route::get('/', function () {
|
||||
if (Auth::check()) {
|
||||
return redirect(config('auth-ui.redirects.login', '/dashboard'));
|
||||
}
|
||||
|
||||
return Inertia::render('Welcome', [
|
||||
'appName' => config('app.name'),
|
||||
]);
|
||||
});
|
||||
|
||||
Route::middleware(['auth', 'verified'])->group(function () {
|
||||
Route::get('/dashboard', DashboardController::class)->name('dashboard');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user