Add user role support and UI
This commit is contained in:
parent
e38215b1b4
commit
fa3902fcea
|
|
@ -41,6 +41,7 @@ public function store(Request $request)
|
|||
$validatedData = $request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'email' => 'required|string|email|max:255|unique:users',
|
||||
'role' => 'required|in:user,admin',
|
||||
'password' => 'required|string|min:8|confirmed',
|
||||
]);
|
||||
|
||||
|
|
@ -49,6 +50,7 @@ public function store(Request $request)
|
|||
$user = User::create([
|
||||
'name' => $validatedData['name'],
|
||||
'email' => $validatedData['email'],
|
||||
'role' => $validatedData['role'],
|
||||
'password' => Hash::make($validatedData['password']),
|
||||
]);
|
||||
|
||||
|
|
@ -90,6 +92,7 @@ public function update(Request $request, string $id)
|
|||
$validatedData = $request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'email' => 'required|string|email|max:255|unique:users,email,' . $id,
|
||||
'role' => 'required|in:user,admin',
|
||||
'password' => 'nullable|string|min:8|confirmed',
|
||||
]);
|
||||
$password = $validatedData['password'];
|
||||
|
|
@ -102,6 +105,7 @@ public function update(Request $request, string $id)
|
|||
$update = [
|
||||
'name' => $validatedData['name'],
|
||||
'email' => $validatedData['email'],
|
||||
'role' => $validatedData['role'],
|
||||
];
|
||||
if ($password) {
|
||||
$update['password'] = $password;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public function run(): void
|
|||
'name' => 'Admin',
|
||||
'email' => 'admin@example.com',
|
||||
'password' => Hash::make('password'),
|
||||
'role' => 'super_user',
|
||||
'role' => 'admin',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<section id="features" class="py-24 px-4">
|
||||
<section id="keunggulan" class="py-24 px-4">
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-3xl sm:text-4xl font-bold text-white mb-4 font-display">Keunggulan Sistem Kami</h2>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,22 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<Label for="role">Role</Label>
|
||||
<Select v-model="form.role">
|
||||
<SelectTrigger class="w-full">
|
||||
<SelectValue placeholder="Pilih Role" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="user">User</SelectItem>
|
||||
<SelectItem value="admin">Admin</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p v-if="form.errors.role" class="mt-1 text-sm text-red-500">
|
||||
{{ form.errors.role }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<Label for="password">Password</Label>
|
||||
<div class="relative">
|
||||
|
|
@ -89,8 +105,7 @@ import { Button } from '@/components/ui/button';
|
|||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { MultipleSelect } from '@/components/ui/multiple-select';
|
||||
import { SelectSearch } from '@/components/ui/select-search';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import { Eye, EyeOff, UserPlus } from 'lucide-vue-next';
|
||||
import { computed, ref } from 'vue';
|
||||
|
|
@ -102,6 +117,7 @@ const showPasswordConfirmation = ref(false);
|
|||
const form = useForm({
|
||||
name: '',
|
||||
email: '',
|
||||
role: '',
|
||||
password: '',
|
||||
password_confirmation: '',
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,6 +30,22 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<Label for="role">Role</Label>
|
||||
<Select v-model="form.role">
|
||||
<SelectTrigger class="w-full">
|
||||
<SelectValue placeholder="Pilih Role" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="user">User</SelectItem>
|
||||
<SelectItem value="admin">Admin</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p v-if="form.errors.role" class="mt-1 text-sm text-red-500">
|
||||
{{ form.errors.role }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<Label for="password">Password</Label>
|
||||
<div class="relative">
|
||||
|
|
@ -89,8 +105,7 @@ import { Button } from '@/components/ui/button';
|
|||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { MultipleSelect } from '@/components/ui/multiple-select';
|
||||
import { SelectSearch } from '@/components/ui/select-search';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import { Edit, Eye, EyeOff, UserPlus } from 'lucide-vue-next';
|
||||
import { computed, ref,watch } from 'vue';
|
||||
|
|
@ -105,12 +120,14 @@ const props = defineProps<{
|
|||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
};
|
||||
}>();
|
||||
|
||||
const form = useForm({
|
||||
name: props.user.name || '',
|
||||
email: props.user.email || '',
|
||||
role: props.user.role || '',
|
||||
password: '',
|
||||
password_confirmation: '',
|
||||
});
|
||||
|
|
@ -119,6 +136,7 @@ watch(open, (value) => {
|
|||
if (value) {
|
||||
form.name = props.user.name || '';
|
||||
form.email = props.user.email || '';
|
||||
form.role = props.user.role || '';
|
||||
form.password = '';
|
||||
form.password_confirmation = '';
|
||||
form.clearErrors();
|
||||
|
|
|
|||
|
|
@ -112,6 +112,12 @@ const changePage = (page: number) => {
|
|||
{{ sortOrder === 'asc' ? '↑' : '↓' }}
|
||||
</span>
|
||||
</TableHead>
|
||||
<TableHead class="cursor-pointer" @click="sortBy('role')">
|
||||
Role
|
||||
<span v-if="sortField === 'role'" class="ml-1">
|
||||
{{ sortOrder === 'asc' ? '↑' : '↓' }}
|
||||
</span>
|
||||
</TableHead>
|
||||
<TableHead class="text-center">Aksi</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
|
@ -125,6 +131,11 @@ const changePage = (page: number) => {
|
|||
<div class="font-medium">{{ user.name }}</div>
|
||||
</TableCell>
|
||||
<TableCell>{{ user.email }}</TableCell>
|
||||
<TableCell>
|
||||
<div class="font-medium">
|
||||
{{ user.role === 'admin' ? 'Admin' : 'User' }}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<UserEdit :user="user" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue