feat: add export functionality for lecturers and students, including styled heading rows in exports
Some checks failed
tests / ci (pull_request) Has been cancelled
Some checks failed
tests / ci (pull_request) Has been cancelled
This commit is contained in:
parent
c321c99ac1
commit
c77f6ae603
49
app/Exports/Concerns/StyledHeadingRow.php
Normal file
49
app/Exports/Concerns/StyledHeadingRow.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports\Concerns;
|
||||||
|
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
trait StyledHeadingRow
|
||||||
|
{
|
||||||
|
abstract public function title(): string;
|
||||||
|
|
||||||
|
public function styles(Worksheet $sheet): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
1 => [
|
||||||
|
'font' => ['bold' => true, 'color' => ['rgb' => '733E0A']],
|
||||||
|
'fill' => [
|
||||||
|
'fillType' => Fill::FILL_SOLID,
|
||||||
|
'startColor' => ['rgb' => 'FDC700'],
|
||||||
|
],
|
||||||
|
'alignment' => [
|
||||||
|
'horizontal' => Alignment::HORIZONTAL_LEFT,
|
||||||
|
'vertical' => Alignment::VERTICAL_CENTER,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function (AfterSheet $event) {
|
||||||
|
$sheet = $event->sheet->getDelegate();
|
||||||
|
$lastColumn = $sheet->getHighestColumn();
|
||||||
|
|
||||||
|
$sheet->insertNewRowBefore(1, 1);
|
||||||
|
$sheet->mergeCells("A1:{$lastColumn}1");
|
||||||
|
$sheet->setCellValue('A1', $this->title().' '.config('app.name'));
|
||||||
|
$sheet->getRowDimension(1)->setRowHeight(24);
|
||||||
|
|
||||||
|
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14);
|
||||||
|
$sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
||||||
|
$sheet->getStyle('A1')->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
68
app/Exports/LecturersExport.php
Normal file
68
app/Exports/LecturersExport.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Exports\Concerns\StyledHeadingRow;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Services\Admin\Users\LecturerService;
|
||||||
|
use Illuminate\Support\Enumerable;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
|
||||||
|
class LecturersExport implements FromCollection, ShouldAutoSize, WithEvents, WithHeadings, WithMapping, WithStyles
|
||||||
|
{
|
||||||
|
use StyledHeadingRow;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private readonly string $search = '',
|
||||||
|
private readonly ?string $gender = null,
|
||||||
|
private readonly ?int $departmentId = null,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Data Dosen';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collection(): Enumerable
|
||||||
|
{
|
||||||
|
return app(LecturerService::class)->forExport($this->search, $this->gender, $this->departmentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'NIDN',
|
||||||
|
'Nama Lengkap',
|
||||||
|
'Username',
|
||||||
|
'Email',
|
||||||
|
'Nomor Telepon',
|
||||||
|
'Jurusan',
|
||||||
|
'Jenis Kelamin',
|
||||||
|
'Tempat Lahir',
|
||||||
|
'Tanggal Lahir',
|
||||||
|
'Alamat',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function map($user): array
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
return [
|
||||||
|
$user->lecturer?->lecturer_number ?? '-',
|
||||||
|
$user->profile?->full_name ?? '-',
|
||||||
|
$user->username,
|
||||||
|
$user->email,
|
||||||
|
$user->profile?->phone_number ?? '-',
|
||||||
|
$user->lecturer?->department?->name ?? '-',
|
||||||
|
$user->profile?->gender?->label() ?? '-',
|
||||||
|
$user->profile?->birth_place ?? '-',
|
||||||
|
$user->profile?->birth_date?->format('d M Y') ?? '-',
|
||||||
|
$user->profile?->address ?? '-',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
73
app/Exports/StudentsExport.php
Normal file
73
app/Exports/StudentsExport.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Exports\Concerns\StyledHeadingRow;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Services\Admin\Users\StudentService;
|
||||||
|
use Illuminate\Support\Enumerable;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
|
||||||
|
class StudentsExport implements FromCollection, ShouldAutoSize, WithEvents, WithHeadings, WithMapping, WithStyles
|
||||||
|
{
|
||||||
|
use StyledHeadingRow;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private readonly string $search = '',
|
||||||
|
private readonly ?string $gender = null,
|
||||||
|
private readonly ?int $departmentId = null,
|
||||||
|
private readonly ?string $status = null,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return 'Data Mahasiswa';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collection(): Enumerable
|
||||||
|
{
|
||||||
|
return app(StudentService::class)->forExport($this->search, $this->gender, $this->departmentId, $this->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'NIM',
|
||||||
|
'Nama Lengkap',
|
||||||
|
'Username',
|
||||||
|
'Email',
|
||||||
|
'Nomor Telepon',
|
||||||
|
'Jurusan',
|
||||||
|
'Angkatan',
|
||||||
|
'Status',
|
||||||
|
'Jenis Kelamin',
|
||||||
|
'Tempat Lahir',
|
||||||
|
'Tanggal Lahir',
|
||||||
|
'Alamat',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function map($user): array
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
return [
|
||||||
|
$user->student?->student_number ?? '-',
|
||||||
|
$user->profile?->full_name ?? '-',
|
||||||
|
$user->username,
|
||||||
|
$user->email,
|
||||||
|
$user->profile?->phone_number ?? '-',
|
||||||
|
$user->student?->department?->name ?? '-',
|
||||||
|
$user->student?->enrollment_year ?? '-',
|
||||||
|
$user->student?->status?->label() ?? '-',
|
||||||
|
$user->profile?->gender?->label() ?? '-',
|
||||||
|
$user->profile?->birth_place ?? '-',
|
||||||
|
$user->profile?->birth_date?->format('d M Y') ?? '-',
|
||||||
|
$user->profile?->address ?? '-',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Users;
|
namespace App\Http\Controllers\Admin\Users;
|
||||||
|
|
||||||
|
use App\Exports\LecturersExport;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\Users\LecturerRequest;
|
use App\Http\Requests\Admin\Users\LecturerRequest;
|
||||||
use App\Http\Requests\PaginatedRequest;
|
use App\Http\Requests\PaginatedRequest;
|
||||||
@ -11,6 +12,8 @@
|
|||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
use Inertia\Response;
|
use Inertia\Response;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
|
|
||||||
class LecturerController extends Controller
|
class LecturerController extends Controller
|
||||||
{
|
{
|
||||||
@ -80,4 +83,13 @@ public function resetPassword(User $user): RedirectResponse
|
|||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Kata sandi berhasil direset.'])->back();
|
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Kata sandi berhasil direset.'])->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function export(PaginatedRequest $request): BinaryFileResponse
|
||||||
|
{
|
||||||
|
return Excel::download(new LecturersExport(
|
||||||
|
search: $request->validated('search') ?? '',
|
||||||
|
gender: $request->validated('gender'),
|
||||||
|
departmentId: $request->validated('department_id'),
|
||||||
|
), 'dosen.xlsx');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\Admin\Users;
|
namespace App\Http\Controllers\Admin\Users;
|
||||||
|
|
||||||
use App\Enums\StudentStatus;
|
use App\Enums\StudentStatus;
|
||||||
|
use App\Exports\StudentsExport;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\Users\StudentRequest;
|
use App\Http\Requests\Admin\Users\StudentRequest;
|
||||||
use App\Http\Requests\Admin\Users\StudentStatusRequest;
|
use App\Http\Requests\Admin\Users\StudentStatusRequest;
|
||||||
@ -14,6 +15,8 @@
|
|||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
use Inertia\Response;
|
use Inertia\Response;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
|
|
||||||
class StudentController extends Controller
|
class StudentController extends Controller
|
||||||
{
|
{
|
||||||
@ -95,4 +98,14 @@ public function updateStatus(StudentStatusRequest $request, User $user): Redirec
|
|||||||
|
|
||||||
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status mahasiswa berhasil diperbarui.'])->back();
|
return Inertia::flash('toast', ['type' => 'success', 'message' => 'Status mahasiswa berhasil diperbarui.'])->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function export(PaginatedRequest $request): BinaryFileResponse
|
||||||
|
{
|
||||||
|
return Excel::download(new StudentsExport(
|
||||||
|
search: $request->validated('search') ?? '',
|
||||||
|
gender: $request->validated('gender'),
|
||||||
|
departmentId: $request->validated('department_id'),
|
||||||
|
status: $request->validated('status'),
|
||||||
|
), 'mahasiswa.xlsx');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
use App\Models\Lecturer;
|
use App\Models\Lecturer;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@ -17,6 +18,20 @@ public function getAllForSelect(): Collection
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function paginated(int $perPage = 25, string $search = '', string $sort = 'created_at', string $direction = 'desc', ?string $gender = null, ?int $departmentId = null): LengthAwarePaginator
|
public function paginated(int $perPage = 25, string $search = '', string $sort = 'created_at', string $direction = 'desc', ?string $gender = null, ?int $departmentId = null): LengthAwarePaginator
|
||||||
|
{
|
||||||
|
return $this->filteredQuery($search, $gender, $departmentId)
|
||||||
|
->orderBy($sort, $direction)
|
||||||
|
->paginate($perPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function forExport(string $search = '', ?string $gender = null, ?int $departmentId = null): Collection
|
||||||
|
{
|
||||||
|
return $this->filteredQuery($search, $gender, $departmentId)
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function filteredQuery(string $search, ?string $gender, ?int $departmentId): Builder
|
||||||
{
|
{
|
||||||
return User::with(['profile', 'lecturer.department'])
|
return User::with(['profile', 'lecturer.department'])
|
||||||
->whereHas('roles', fn ($q) => $q->where('name', 'dosen'))
|
->whereHas('roles', fn ($q) => $q->where('name', 'dosen'))
|
||||||
@ -27,9 +42,7 @@ public function paginated(int $perPage = 25, string $search = '', string $sort =
|
|||||||
->orWhereHas('lecturer', fn ($q) => $q->where('lecturer_number', 'like', "%{$search}%"));
|
->orWhereHas('lecturer', fn ($q) => $q->where('lecturer_number', 'like', "%{$search}%"));
|
||||||
}))
|
}))
|
||||||
->when($gender, fn ($q) => $q->whereHas('profile', fn ($q) => $q->where('gender', $gender)))
|
->when($gender, fn ($q) => $q->whereHas('profile', fn ($q) => $q->where('gender', $gender)))
|
||||||
->when($departmentId, fn ($q) => $q->whereHas('lecturer', fn ($q) => $q->where('department_id', $departmentId)))
|
->when($departmentId, fn ($q) => $q->whereHas('lecturer', fn ($q) => $q->where('department_id', $departmentId)));
|
||||||
->orderBy($sort, $direction)
|
|
||||||
->paginate($perPage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create(array $data): User
|
public function create(array $data): User
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@ -17,6 +18,20 @@ public function getAllForSelect(): Collection
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function paginated(int $perPage = 25, string $search = '', string $sort = 'created_at', string $direction = 'desc', ?string $gender = null, ?int $departmentId = null, ?string $status = null): LengthAwarePaginator
|
public function paginated(int $perPage = 25, string $search = '', string $sort = 'created_at', string $direction = 'desc', ?string $gender = null, ?int $departmentId = null, ?string $status = null): LengthAwarePaginator
|
||||||
|
{
|
||||||
|
return $this->filteredQuery($search, $gender, $departmentId, $status)
|
||||||
|
->orderBy($sort, $direction)
|
||||||
|
->paginate($perPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function forExport(string $search = '', ?string $gender = null, ?int $departmentId = null, ?string $status = null): Collection
|
||||||
|
{
|
||||||
|
return $this->filteredQuery($search, $gender, $departmentId, $status)
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function filteredQuery(string $search, ?string $gender, ?int $departmentId, ?string $status): Builder
|
||||||
{
|
{
|
||||||
return User::with(['profile', 'student.department'])
|
return User::with(['profile', 'student.department'])
|
||||||
->whereHas('roles', fn ($q) => $q->where('name', 'mahasiswa'))
|
->whereHas('roles', fn ($q) => $q->where('name', 'mahasiswa'))
|
||||||
@ -28,9 +43,7 @@ public function paginated(int $perPage = 25, string $search = '', string $sort =
|
|||||||
}))
|
}))
|
||||||
->when($gender, fn ($q) => $q->whereHas('profile', fn ($q) => $q->where('gender', $gender)))
|
->when($gender, fn ($q) => $q->whereHas('profile', fn ($q) => $q->where('gender', $gender)))
|
||||||
->when($departmentId, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('department_id', $departmentId)))
|
->when($departmentId, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('department_id', $departmentId)))
|
||||||
->when($status, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('status', $status)))
|
->when($status, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('status', $status)));
|
||||||
->orderBy($sort, $direction)
|
|
||||||
->paginate($perPage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create(array $data): User
|
public function create(array $data): User
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
"laravel/framework": "^13.17",
|
"laravel/framework": "^13.17",
|
||||||
"laravel/tinker": "^3.0",
|
"laravel/tinker": "^3.0",
|
||||||
"laravel/wayfinder": "^0.1.14",
|
"laravel/wayfinder": "^0.1.14",
|
||||||
|
"maatwebsite/excel": "^4.0",
|
||||||
"spatie/laravel-medialibrary": "^11.23",
|
"spatie/laravel-medialibrary": "^11.23",
|
||||||
"spatie/laravel-permission": "^8.3",
|
"spatie/laravel-permission": "^8.3",
|
||||||
"symfony/html-sanitizer": "^8.1"
|
"symfony/html-sanitizer": "^8.1"
|
||||||
|
|||||||
383
composer.lock
generated
383
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "3fabe2a835a47ecc56faf22b029cda13",
|
"content-hash": "379c97a9e3b22c91d1427f44e711a975",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
@ -189,6 +189,82 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-02-09T16:56:22+00:00"
|
"time": "2024-02-09T16:56:22+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "composer/pcre",
|
||||||
|
"version": "3.4.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/composer/pcre.git",
|
||||||
|
"reference": "d5a341b3fb61f3001970940afb1d332968a183ed"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/composer/pcre/zipball/d5a341b3fb61f3001970940afb1d332968a183ed",
|
||||||
|
"reference": "d5a341b3fb61f3001970940afb1d332968a183ed",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.4 || ^8.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"phpstan/phpstan": "<2.2.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^2",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^2",
|
||||||
|
"phpstan/phpstan-strict-rules": "^2",
|
||||||
|
"phpunit/phpunit": "^9"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"phpstan": {
|
||||||
|
"includes": [
|
||||||
|
"extension.neon"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Composer\\Pcre\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jordi Boggiano",
|
||||||
|
"email": "j.boggiano@seld.be",
|
||||||
|
"homepage": "http://seld.be"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||||
|
"keywords": [
|
||||||
|
"PCRE",
|
||||||
|
"preg",
|
||||||
|
"regex",
|
||||||
|
"regular expression"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
|
"source": "https://github.com/composer/pcre/tree/3.4.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://packagist.com",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/composer",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-06-07T11:47:49+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
"version": "3.4.4",
|
"version": "3.4.4",
|
||||||
@ -2581,6 +2657,95 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-03-08T20:05:35+00:00"
|
"time": "2026-03-08T20:05:35+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "maatwebsite/excel",
|
||||||
|
"version": "4.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
|
||||||
|
"reference": "3f3e73956f87e3d229b244cec8cbc3bbda4fc8dd"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/3f3e73956f87e3d229b244cec8cbc3bbda4fc8dd",
|
||||||
|
"reference": "3f3e73956f87e3d229b244cec8cbc3bbda4fc8dd",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer/semver": "^3.4",
|
||||||
|
"illuminate/support": "^12.0 || ^13.0",
|
||||||
|
"php": "^8.3",
|
||||||
|
"phpoffice/phpspreadsheet": "^5.8",
|
||||||
|
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"brianium/paratest": "^7.20",
|
||||||
|
"driftingly/rector-laravel": "^2.5",
|
||||||
|
"ext-sqlite3": "*",
|
||||||
|
"larastan/larastan": "^3.10",
|
||||||
|
"laravel/pint": "^1.29",
|
||||||
|
"laravel/scout": "^10.25 || ^11.2",
|
||||||
|
"orchestra/testbench": "^10.11 || ^11.1",
|
||||||
|
"phpstan/extension-installer": "^1.4",
|
||||||
|
"phpstan/phpstan-mockery": "^2.0",
|
||||||
|
"phpunit/phpunit": "^12.5 || ~13.1.14",
|
||||||
|
"predis/predis": "^2.3 || ^3.0",
|
||||||
|
"rector/rector": "^2.4.2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"Maatwebsite\\Excel\\ExcelServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Maatwebsite\\Excel\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Patrick Brouwers",
|
||||||
|
"email": "patrick@spartner.nl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Supercharged Excel exports and imports in Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"PHPExcel",
|
||||||
|
"batch",
|
||||||
|
"csv",
|
||||||
|
"excel",
|
||||||
|
"export",
|
||||||
|
"import",
|
||||||
|
"laravel",
|
||||||
|
"php",
|
||||||
|
"phpspreadsheet"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
|
||||||
|
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/4.0.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://laravel-excel.com/commercial-support",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/patrickbrouwers",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-08-24T13:06:48+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "maennchen/zipstream-php",
|
"name": "maennchen/zipstream-php",
|
||||||
"version": "3.2.2",
|
"version": "3.2.2",
|
||||||
@ -2659,6 +2824,113 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-04-11T18:38:28+00:00"
|
"time": "2026-04-11T18:38:28+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "markbaker/complex",
|
||||||
|
"version": "3.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||||
|
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||||
|
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Complex\\": "classes/src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"email": "mark@lange.demon.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Class for working with complex numbers",
|
||||||
|
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||||
|
"keywords": [
|
||||||
|
"complex",
|
||||||
|
"mathematics"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||||
|
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
|
||||||
|
},
|
||||||
|
"time": "2022-12-06T16:21:08+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "markbaker/matrix",
|
||||||
|
"version": "3.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||||
|
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
|
||||||
|
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpdocumentor/phpdocumentor": "2.*",
|
||||||
|
"phploc/phploc": "^4.0",
|
||||||
|
"phpmd/phpmd": "2.*",
|
||||||
|
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||||
|
"sebastian/phpcpd": "^4.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Matrix\\": "classes/src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"email": "mark@demon-angel.eu"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Class for working with matrices",
|
||||||
|
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||||
|
"keywords": [
|
||||||
|
"mathematics",
|
||||||
|
"matrix",
|
||||||
|
"vector"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||||
|
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
|
||||||
|
},
|
||||||
|
"time": "2022-12-02T22:17:43+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "3.10.0",
|
"version": "3.10.0",
|
||||||
@ -3414,6 +3686,115 @@
|
|||||||
},
|
},
|
||||||
"time": "2026-01-06T21:53:42+00:00"
|
"time": "2026-01-06T21:53:42+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "phpoffice/phpspreadsheet",
|
||||||
|
"version": "5.9.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||||
|
"reference": "05e99ebf61238a70227b4d9cc02d0030d34f6339"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/05e99ebf61238a70227b4d9cc02d0030d34f6339",
|
||||||
|
"reference": "05e99ebf61238a70227b4d9cc02d0030d34f6339",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer/pcre": "^1||^2||^3",
|
||||||
|
"ext-ctype": "*",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-fileinfo": "*",
|
||||||
|
"ext-filter": "*",
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"ext-libxml": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"ext-simplexml": "*",
|
||||||
|
"ext-xml": "*",
|
||||||
|
"ext-xmlreader": "*",
|
||||||
|
"ext-xmlwriter": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"maennchen/zipstream-php": "^2.1 || ^3.0",
|
||||||
|
"markbaker/complex": "^3.0",
|
||||||
|
"markbaker/matrix": "^3.0",
|
||||||
|
"php": "^8.2",
|
||||||
|
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
|
||||||
|
"dompdf/dompdf": "^2.0 || ^3.0",
|
||||||
|
"ext-intl": "*",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.2",
|
||||||
|
"mitoteam/jpgraph": "^10.5",
|
||||||
|
"mpdf/mpdf": "^8.1.1",
|
||||||
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
|
"phpstan/phpstan": "^1.1 || ^2.0",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0",
|
||||||
|
"phpstan/phpstan-phpunit": "^1.0 || ^2.0",
|
||||||
|
"phpunit/phpunit": "^10.5 || ^11.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7",
|
||||||
|
"tecnickcom/tcpdf": "^6.5"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
|
||||||
|
"ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard and StringHelper::setLocale()",
|
||||||
|
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
|
||||||
|
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||||
|
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Maarten Balliauw",
|
||||||
|
"homepage": "https://blog.maartenballiauw.be"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mark Baker",
|
||||||
|
"homepage": "https://markbakeruk.net"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Franck Lefevre",
|
||||||
|
"homepage": "https://rootslabs.net"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Erik Tilt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Adrien Crivelli"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Owen Leibman"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
||||||
|
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
|
||||||
|
"keywords": [
|
||||||
|
"OpenXML",
|
||||||
|
"excel",
|
||||||
|
"gnumeric",
|
||||||
|
"ods",
|
||||||
|
"php",
|
||||||
|
"spreadsheet",
|
||||||
|
"xls",
|
||||||
|
"xlsx"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||||
|
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.9.0"
|
||||||
|
},
|
||||||
|
"time": "2026-07-12T19:17:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "phpoption/phpoption",
|
"name": "phpoption/phpoption",
|
||||||
"version": "1.9.5",
|
"version": "1.9.5",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Head, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import { Plus, RotateCcw } from 'lucide-react';
|
import { FileSpreadsheet, Plus, RotateCcw } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ConfirmDialog } from '@/components/confirm-dialog';
|
import { ConfirmDialog } from '@/components/confirm-dialog';
|
||||||
import type { PaginationState } from '@/components/data-table';
|
import type { PaginationState } from '@/components/data-table';
|
||||||
@ -16,6 +16,7 @@ import {
|
|||||||
edit,
|
edit,
|
||||||
destroy,
|
destroy,
|
||||||
reset_password,
|
reset_password,
|
||||||
|
exportMethod as exportLecturers,
|
||||||
} from '@/routes/admin/users/lecturers';
|
} from '@/routes/admin/users/lecturers';
|
||||||
import type { Lecturer } from './columns';
|
import type { Lecturer } from './columns';
|
||||||
import { createLecturerColumns } from './columns';
|
import { createLecturerColumns } from './columns';
|
||||||
@ -123,12 +124,24 @@ export default function LecturerIndex({
|
|||||||
<PageHeader
|
<PageHeader
|
||||||
title="Dosen"
|
title="Dosen"
|
||||||
actions={
|
actions={
|
||||||
<Button asChild>
|
<div className="flex items-center gap-2">
|
||||||
<a href={create.url()}>
|
<Button variant="outline" asChild>
|
||||||
<Plus className="h-4 w-4" />
|
<a
|
||||||
Tambah
|
href={exportLecturers.url({
|
||||||
</a>
|
query: { search, ...filters },
|
||||||
</Button>
|
})}
|
||||||
|
>
|
||||||
|
<FileSpreadsheet className="h-4 w-4" />
|
||||||
|
Export
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
<Button asChild>
|
||||||
|
<a href={create.url()}>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
Tambah
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Head, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import { Info, Plus, RotateCcw } from 'lucide-react';
|
import { FileSpreadsheet, Info, Plus, RotateCcw } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ConfirmDialog } from '@/components/confirm-dialog';
|
import { ConfirmDialog } from '@/components/confirm-dialog';
|
||||||
import type { PaginationState } from '@/components/data-table';
|
import type { PaginationState } from '@/components/data-table';
|
||||||
@ -17,6 +17,7 @@ import {
|
|||||||
edit,
|
edit,
|
||||||
reset_password,
|
reset_password,
|
||||||
update_status,
|
update_status,
|
||||||
|
exportMethod as exportStudents,
|
||||||
index as studentsIndex,
|
index as studentsIndex,
|
||||||
} from '@/routes/admin/users/students';
|
} from '@/routes/admin/users/students';
|
||||||
import { createStudentColumns } from './columns';
|
import { createStudentColumns } from './columns';
|
||||||
@ -144,12 +145,24 @@ export default function StudentIndex({
|
|||||||
<PageHeader
|
<PageHeader
|
||||||
title="Mahasiswa"
|
title="Mahasiswa"
|
||||||
actions={
|
actions={
|
||||||
<Button asChild>
|
<div className="flex items-center gap-2">
|
||||||
<a href={create.url()}>
|
<Button variant="outline" asChild>
|
||||||
<Plus className="h-4 w-4" />
|
<a
|
||||||
Tambah
|
href={exportStudents.url({
|
||||||
</a>
|
query: { search, ...filters },
|
||||||
</Button>
|
})}
|
||||||
|
>
|
||||||
|
<FileSpreadsheet className="h-4 w-4" />
|
||||||
|
Export
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
<Button asChild>
|
||||||
|
<a href={create.url()}>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
Tambah
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@ -119,10 +119,12 @@
|
|||||||
Route::prefix('admin/users')->name('admin.users.')->group(function () {
|
Route::prefix('admin/users')->name('admin.users.')->group(function () {
|
||||||
Route::resource('lecturers', LecturerController::class)->except(['show'])->parameters(['lecturers' => 'user']);
|
Route::resource('lecturers', LecturerController::class)->except(['show'])->parameters(['lecturers' => 'user']);
|
||||||
Route::patch('lecturers/{user}/reset-password', [LecturerController::class, 'resetPassword'])->name('lecturers.reset_password');
|
Route::patch('lecturers/{user}/reset-password', [LecturerController::class, 'resetPassword'])->name('lecturers.reset_password');
|
||||||
|
Route::get('lecturers/export', [LecturerController::class, 'export'])->name('lecturers.export');
|
||||||
|
|
||||||
Route::resource('students', StudentController::class)->except(['show'])->parameters(['students' => 'user']);
|
Route::resource('students', StudentController::class)->except(['show'])->parameters(['students' => 'user']);
|
||||||
Route::patch('students/{user}/reset-password', [StudentController::class, 'resetPassword'])->name('students.reset_password');
|
Route::patch('students/{user}/reset-password', [StudentController::class, 'resetPassword'])->name('students.reset_password');
|
||||||
Route::patch('students/{user}/status', [StudentController::class, 'updateStatus'])->name('students.update_status');
|
Route::patch('students/{user}/status', [StudentController::class, 'updateStatus'])->name('students.update_status');
|
||||||
|
Route::get('students/export', [StudentController::class, 'export'])->name('students.export');
|
||||||
|
|
||||||
Route::resource('administrators', AdministratorController::class)->except(['show'])->parameters(['administrators' => 'user']);
|
Route::resource('administrators', AdministratorController::class)->except(['show'])->parameters(['administrators' => 'user']);
|
||||||
Route::patch('administrators/{user}/reset-password', [AdministratorController::class, 'resetPassword'])->name('administrators.reset_password');
|
Route::patch('administrators/{user}/reset-password', [AdministratorController::class, 'resetPassword'])->name('administrators.reset_password');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user