feat: add employee management features including create, edit, and list functionalities
- Implemented employee columns for data table with sorting and action buttons. - Created employee creation form with validation and default password information. - Developed employee editing form pre-filled with existing data. - Added employee listing page with delete and reset password functionalities. - Introduced leave request management with columns for status and actions. - Created leave request form for adding and editing requests with date pickers. - Implemented confirmation dialogs for delete, approve, and reject actions.
This commit is contained in:
parent
887526bd18
commit
da30f12fc2
@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\SDM;
|
namespace App\Http\Controllers\Admin\HR;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\SDM\EmployeeRequest;
|
use App\Http\Requests\Admin\HR\EmployeeRequest;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Services\Admin\SDM\EmployeeService;
|
use App\Services\Admin\HR\EmployeeService;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
@ -19,14 +19,14 @@ public function __construct(
|
|||||||
|
|
||||||
public function index(): Response
|
public function index(): Response
|
||||||
{
|
{
|
||||||
return Inertia::render('admin/sdm/employee/index', [
|
return Inertia::render('admin/hr/employee/index', [
|
||||||
'employees' => $this->service->getAll(),
|
'employees' => $this->service->getAll(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create(): Response
|
public function create(): Response
|
||||||
{
|
{
|
||||||
return Inertia::render('admin/sdm/employee/create');
|
return Inertia::render('admin/hr/employee/create');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(EmployeeRequest $request): RedirectResponse
|
public function store(EmployeeRequest $request): RedirectResponse
|
||||||
@ -42,12 +42,12 @@ public function store(EmployeeRequest $request): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.employees.index');
|
return to_route('admin.hr.employees.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(User $employee): Response
|
public function edit(User $employee): Response
|
||||||
{
|
{
|
||||||
return Inertia::render('admin/sdm/employee/edit', [
|
return Inertia::render('admin/hr/employee/edit', [
|
||||||
'employee' => $this->service->getById($employee->id),
|
'employee' => $this->service->getById($employee->id),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ public function update(EmployeeRequest $request, User $employee): RedirectRespon
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.employees.index');
|
return to_route('admin.hr.employees.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(User $employee): RedirectResponse
|
public function destroy(User $employee): RedirectResponse
|
||||||
@ -81,7 +81,7 @@ public function destroy(User $employee): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.employees.index');
|
return to_route('admin.hr.employees.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toggleActive(User $employee): RedirectResponse
|
public function toggleActive(User $employee): RedirectResponse
|
||||||
@ -98,7 +98,7 @@ public function toggleActive(User $employee): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.employees.index');
|
return to_route('admin.hr.employees.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resetPassword(User $employee): RedirectResponse
|
public function resetPassword(User $employee): RedirectResponse
|
||||||
@ -114,6 +114,6 @@ public function resetPassword(User $employee): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.employees.index');
|
return to_route('admin.hr.employees.index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\SDM;
|
namespace App\Http\Controllers\Admin\HR;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\SDM\LeaveRequestRequest;
|
use App\Http\Requests\Admin\HR\LeaveRequestRequest;
|
||||||
use App\Models\LeaveRequest;
|
use App\Models\LeaveRequest;
|
||||||
use App\Services\Admin\SDM\LeaveRequestService;
|
use App\Services\Admin\HR\LeaveRequestService;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
@ -19,7 +19,7 @@ public function __construct(
|
|||||||
|
|
||||||
public function index(): Response
|
public function index(): Response
|
||||||
{
|
{
|
||||||
return Inertia::render('admin/sdm/leave-request/index', [
|
return Inertia::render('admin/hr/leave-request/index', [
|
||||||
'leaveRequests' => $this->service->getAll(),
|
'leaveRequests' => $this->service->getAll(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ public function store(LeaveRequestRequest $request): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.leave-requests.index');
|
return to_route('admin.hr.leave-requests.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(LeaveRequestRequest $request, LeaveRequest $leaveRequest): RedirectResponse
|
public function update(LeaveRequestRequest $request, LeaveRequest $leaveRequest): RedirectResponse
|
||||||
@ -53,7 +53,7 @@ public function update(LeaveRequestRequest $request, LeaveRequest $leaveRequest)
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.leave-requests.index');
|
return to_route('admin.hr.leave-requests.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(LeaveRequest $leaveRequest): RedirectResponse
|
public function destroy(LeaveRequest $leaveRequest): RedirectResponse
|
||||||
@ -66,7 +66,7 @@ public function destroy(LeaveRequest $leaveRequest): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.leave-requests.index');
|
return to_route('admin.hr.leave-requests.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function approve(LeaveRequest $leaveRequest): RedirectResponse
|
public function approve(LeaveRequest $leaveRequest): RedirectResponse
|
||||||
@ -79,7 +79,7 @@ public function approve(LeaveRequest $leaveRequest): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.leave-requests.index');
|
return to_route('admin.hr.leave-requests.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reject(LeaveRequest $leaveRequest): RedirectResponse
|
public function reject(LeaveRequest $leaveRequest): RedirectResponse
|
||||||
@ -92,6 +92,6 @@ public function reject(LeaveRequest $leaveRequest): RedirectResponse
|
|||||||
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to_route('admin.sdm.leave-requests.index');
|
return to_route('admin.hr.leave-requests.index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\SDM;
|
namespace App\Http\Requests\Admin\HR;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\SDM;
|
namespace App\Http\Requests\Admin\HR;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Services\Admin\SDM;
|
namespace App\Services\Admin\HR;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Services\Admin\SDM;
|
namespace App\Services\Admin\HR;
|
||||||
|
|
||||||
use App\Enums\LeaveRequestStatus;
|
use App\Enums\LeaveRequestStatus;
|
||||||
use App\Models\LeaveRequest;
|
use App\Models\LeaveRequest;
|
||||||
@ -41,8 +41,8 @@ import { index as suppliersIndex } from '@/routes/admin/master/suppliers';
|
|||||||
import { index as cashAccountsIndex } from '@/routes/admin/finance/cash-accounts';
|
import { index as cashAccountsIndex } from '@/routes/admin/finance/cash-accounts';
|
||||||
import { index as expensesIndex } from '@/routes/admin/finance/expenses';
|
import { index as expensesIndex } from '@/routes/admin/finance/expenses';
|
||||||
import { index as employeeAdvancesIndex } from '@/routes/admin/finance/employee-advances';
|
import { index as employeeAdvancesIndex } from '@/routes/admin/finance/employee-advances';
|
||||||
import { index as employeesIndex } from '@/routes/admin/sdm/employees';
|
import { index as employeesIndex } from '@/routes/admin/hr/employees';
|
||||||
import { index as leaveRequestsIndex } from '@/routes/admin/sdm/leave-requests';
|
import { index as leaveRequestsIndex } from '@/routes/admin/hr/leave-requests';
|
||||||
|
|
||||||
type NavMenuItem = { title: string; href: string; icon: LucideIcon };
|
type NavMenuItem = { title: string; href: string; icon: LucideIcon };
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ const keuanganItems: NavMenuItem[] = [
|
|||||||
{ title: 'Gaji', href: '#', icon: DollarSign },
|
{ title: 'Gaji', href: '#', icon: DollarSign },
|
||||||
];
|
];
|
||||||
|
|
||||||
const sdmItems: NavMenuItem[] = [
|
const hrItems: NavMenuItem[] = [
|
||||||
{ title: 'Pegawai', href: employeesIndex.url(), icon: UserCircle },
|
{ title: 'Pegawai', href: employeesIndex.url(), icon: UserCircle },
|
||||||
{ title: 'Presensi', href: '#', icon: CalendarCheck },
|
{ title: 'Presensi', href: '#', icon: CalendarCheck },
|
||||||
{ title: 'Cuti', href: leaveRequestsIndex.url(), icon: CalendarDays },
|
{ title: 'Cuti', href: leaveRequestsIndex.url(), icon: CalendarDays },
|
||||||
@ -158,7 +158,7 @@ export function AppSidebar() {
|
|||||||
<MenuGroup label="Master" items={masterItems} />
|
<MenuGroup label="Master" items={masterItems} />
|
||||||
<MenuGroup label="Kelola" items={kelolaItems} />
|
<MenuGroup label="Kelola" items={kelolaItems} />
|
||||||
<MenuGroup label="Keuangan" items={keuanganItems} />
|
<MenuGroup label="Keuangan" items={keuanganItems} />
|
||||||
<MenuGroup label="SDM" items={sdmItems} />
|
<MenuGroup label="HR" items={hrItems} />
|
||||||
<MenuGroup label="Sistem" items={sistemItems} />
|
<MenuGroup label="Sistem" items={sistemItems} />
|
||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import {
|
|||||||
SelectValue,
|
SelectValue,
|
||||||
} from '@/components/ui/select';
|
} from '@/components/ui/select';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { index as employeeIndex, store } from '@/routes/admin/sdm/employees';
|
import { index as employeeIndex, store } from '@/routes/admin/hr/employees';
|
||||||
import { Form, Head } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { AlertCircle, ArrowLeft } from 'lucide-react';
|
import { AlertCircle, ArrowLeft } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -222,7 +222,7 @@ export default function EmployeeCreate() {
|
|||||||
EmployeeCreate.layout = {
|
EmployeeCreate.layout = {
|
||||||
breadcrumbs: [
|
breadcrumbs: [
|
||||||
{
|
{
|
||||||
title: 'SDM',
|
title: 'HR',
|
||||||
href: employeeIndex.url(),
|
href: employeeIndex.url(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -14,7 +14,7 @@ import {
|
|||||||
SelectValue,
|
SelectValue,
|
||||||
} from '@/components/ui/select';
|
} from '@/components/ui/select';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { index as employeeIndex, update } from '@/routes/admin/sdm/employees';
|
import { index as employeeIndex, update } from '@/routes/admin/hr/employees';
|
||||||
import { Form, Head } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { ArrowLeft } from 'lucide-react';
|
import { ArrowLeft } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -249,7 +249,7 @@ export default function EmployeeEdit({ employee }: Props) {
|
|||||||
EmployeeEdit.layout = {
|
EmployeeEdit.layout = {
|
||||||
breadcrumbs: [
|
breadcrumbs: [
|
||||||
{
|
{
|
||||||
title: 'SDM',
|
title: 'HR',
|
||||||
href: employeeIndex.url(),
|
href: employeeIndex.url(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { ConfirmDialog } from '@/components/confirm-dialog';
|
import { ConfirmDialog } from '@/components/confirm-dialog';
|
||||||
import { DataTable } from '@/components/data-table';
|
import { DataTable } from '@/components/data-table';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { destroy, create as employeeCreate, edit as employeeEdit, index as employeeIndex, toggleActive, resetPassword as resetPasswordRoute } from '@/routes/admin/sdm/employees';
|
import { destroy, create as employeeCreate, edit as employeeEdit, index as employeeIndex, toggleActive, resetPassword as resetPasswordRoute } from '@/routes/admin/hr/employees';
|
||||||
import { Head, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -106,7 +106,7 @@ export default function EmployeeIndex({ employees }: Props) {
|
|||||||
EmployeeIndex.layout = {
|
EmployeeIndex.layout = {
|
||||||
breadcrumbs: [
|
breadcrumbs: [
|
||||||
{
|
{
|
||||||
title: 'SDM',
|
title: 'HR',
|
||||||
href: employeeIndex.url(),
|
href: employeeIndex.url(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from '@/components/ui/dialog';
|
} from '@/components/ui/dialog';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
import { approve, destroy, index as leaveRequestIndex, reject, store, update } from '@/routes/admin/sdm/leave-requests';
|
import { approve, destroy, index as leaveRequestIndex, reject, store, update } from '@/routes/admin/hr/leave-requests';
|
||||||
import { Form, Head, router } from '@inertiajs/react';
|
import { Form, Head, router } from '@inertiajs/react';
|
||||||
import { Plus } from 'lucide-react';
|
import { Plus } from 'lucide-react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
@ -298,7 +298,7 @@ export default function LeaveRequestIndex({ leaveRequests }: Props) {
|
|||||||
LeaveRequestIndex.layout = {
|
LeaveRequestIndex.layout = {
|
||||||
breadcrumbs: [
|
breadcrumbs: [
|
||||||
{
|
{
|
||||||
title: 'SDM',
|
title: 'HR',
|
||||||
href: leaveRequestIndex(),
|
href: leaveRequestIndex(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -6,8 +6,8 @@
|
|||||||
use App\Http\Controllers\Admin\Master\CategoryController;
|
use App\Http\Controllers\Admin\Master\CategoryController;
|
||||||
use App\Http\Controllers\Admin\Master\CustomerController;
|
use App\Http\Controllers\Admin\Master\CustomerController;
|
||||||
use App\Http\Controllers\Admin\Master\SupplierController;
|
use App\Http\Controllers\Admin\Master\SupplierController;
|
||||||
use App\Http\Controllers\Admin\SDM\EmployeeController;
|
use App\Http\Controllers\Admin\HR\EmployeeController;
|
||||||
use App\Http\Controllers\Admin\SDM\LeaveRequestController;
|
use App\Http\Controllers\Admin\HR\LeaveRequestController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::inertia('/', 'welcome')->name('home');
|
Route::inertia('/', 'welcome')->name('home');
|
||||||
@ -35,7 +35,7 @@
|
|||||||
Route::post('employee-advances/{employeeAdvance}/pay', [EmployeeAdvanceController::class, 'pay'])->name('employee-advances.pay');
|
Route::post('employee-advances/{employeeAdvance}/pay', [EmployeeAdvanceController::class, 'pay'])->name('employee-advances.pay');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::prefix('admin/sdm')->name('admin.sdm.')->group(function () {
|
Route::prefix('admin/hr')->name('admin.hr.')->group(function () {
|
||||||
Route::resource('employees', EmployeeController::class)->except(['show']);
|
Route::resource('employees', EmployeeController::class)->except(['show']);
|
||||||
Route::post('employees/{employee}/toggle-active', [EmployeeController::class, 'toggleActive'])->name('employees.toggle-active');
|
Route::post('employees/{employee}/toggle-active', [EmployeeController::class, 'toggleActive'])->name('employees.toggle-active');
|
||||||
Route::post('employees/{employee}/reset-password', [EmployeeController::class, 'resetPassword'])->name('employees.reset-password');
|
Route::post('employees/{employee}/reset-password', [EmployeeController::class, 'resetPassword'])->name('employees.reset-password');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user