Skip to content

Commit 985d8cb

Browse files
committed
feat: teacher
1 parent d938794 commit 985d8cb

File tree

13 files changed

+462
-23
lines changed

13 files changed

+462
-23
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Enum\Role;
6+
use App\Http\Requests\StoreTeacherRequest;
7+
use App\Http\Requests\UpdateTeacherRequest;
8+
use App\Models\User;
9+
use Illuminate\Http\JsonResponse;
10+
use Illuminate\Http\RedirectResponse;
11+
use Illuminate\Http\Request;
12+
use Illuminate\Support\Facades\Log;
13+
use Illuminate\View\View;
14+
use Yajra\DataTables\DataTables;
15+
16+
class TeacherController extends Controller
17+
{
18+
/**
19+
* Display a listing of the resource.
20+
*/
21+
public function index(Request $request): View|JsonResponse
22+
{
23+
if ($request->ajax()) {
24+
return DataTables::of(User::role(Role::TEACHER))
25+
->addColumn('action', function ($row) {
26+
return '<div class="dropdown">
27+
<button type="button"
28+
class="btn p-0 dropdown-toggle hide-arrow"
29+
data-bs-toggle="dropdown">
30+
<i class="bx bx-dots-vertical-rounded"></i>
31+
</button>
32+
<div class="dropdown-menu">
33+
<a class="dropdown-item" href="'.route('teacher.edit', $row).'"><i class="bx bx-edit-alt me-1"></i>'.__('label.edit').'</a>
34+
<form action="'.route('teacher.destroy', $row).'" method="post" onsubmit="confirmSubmit(event, this)">
35+
<input type="hidden" name="_method" value="DELETE">
36+
<input type="hidden" name="_token" value="'.csrf_token().'" />
37+
<button class="dropdown-item" type="submit"><i class="bx bx-trash me-1"></i>'.__('label.delete').'</button>
38+
</form>
39+
</div>
40+
</div>';
41+
})
42+
->editColumn('gender', fn ($row) => __('label.'.$row->gender))
43+
->rawColumns(['action'])
44+
->make();
45+
}
46+
47+
return view('pages.teacher.index');
48+
}
49+
50+
/**
51+
* Show the form for creating a new resource.
52+
*/
53+
public function create(): View
54+
{
55+
return view('pages.teacher.create');
56+
}
57+
58+
/**
59+
* Store a newly created resource in storage.
60+
*/
61+
public function store(StoreTeacherRequest $request): RedirectResponse
62+
{
63+
try {
64+
$data = $request->validated();
65+
$data['role'] = Role::TEACHER;
66+
$data['password'] = bcrypt('password');
67+
68+
User::create($data);
69+
70+
return redirect()->route('teacher.index')->with('notification', $this->successNotification('notification.success_create', 'menu.teacher'));
71+
} catch (\Throwable $throwable) {
72+
Log::error($throwable->getMessage());
73+
74+
return back()->with('notification', $this->successNotification('notification.fail_create', 'menu.teacher'));
75+
}
76+
}
77+
78+
/**
79+
* Display the specified resource.
80+
*/
81+
public function show(User $teacher): View
82+
{
83+
return view('pages.teacher.show', [
84+
'teacher' => $teacher,
85+
]);
86+
}
87+
88+
/**
89+
* Show the form for editing the specified resource.
90+
*/
91+
public function edit(User $teacher): View
92+
{
93+
return view('pages.teacher.edit', [
94+
'teacher' => $teacher,
95+
]);
96+
}
97+
98+
/**
99+
* Update the specified resource in storage.
100+
*/
101+
public function update(UpdateTeacherRequest $request, User $teacher): RedirectResponse
102+
{
103+
try {
104+
$teacher->update($request->validated());
105+
106+
return back()->with('notification', $this->successNotification('notification.success_update', 'menu.teacher'));
107+
} catch (\Throwable $throwable) {
108+
Log::error($throwable->getMessage());
109+
110+
return back()->with('notification', $this->successNotification('notification.fail_update', 'menu.teacher'));
111+
}
112+
}
113+
114+
/**
115+
* Remove the specified resource from storage.
116+
*/
117+
public function destroy(User $teacher): RedirectResponse
118+
{
119+
try {
120+
$teacher->delete();
121+
122+
return back()->with('notification', $this->successNotification('notification.success_delete', 'menu.teacher'));
123+
} catch (\Throwable $throwable) {
124+
Log::error($throwable->getMessage());
125+
126+
return back()->with('notification', $this->successNotification('notification.fail_delete', 'menu.teacher'));
127+
}
128+
}
129+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace App\Http\Requests;
4+
5+
use App\Enum\Role;
6+
use Illuminate\Contracts\Validation\ValidationRule;
7+
use Illuminate\Foundation\Http\FormRequest;
8+
use Illuminate\Validation\Rule;
9+
10+
class StoreTeacherRequest extends FormRequest
11+
{
12+
/**
13+
* Determine if the user is authorized to make this request.
14+
*/
15+
public function authorize(): bool
16+
{
17+
return auth()->user()->isRole(Role::OWNER) || auth()->user()->isRole(Role::HEADMASTER) || auth()->user()->isRole(Role::ADMINISTRATOR);
18+
}
19+
20+
/**
21+
* Get the validation rules that apply to the request.
22+
*
23+
* @return array<string, ValidationRule|array|string>
24+
*/
25+
public function rules(): array
26+
{
27+
return [
28+
'name' => ['required'],
29+
'email' => ['required', 'email', Rule::unique('users', 'email')],
30+
'image' => ['nullable', 'image', 'max:2048'],
31+
'phone' => ['required'],
32+
'address' => ['nullable'],
33+
'marital_status' => ['nullable'],
34+
'gender' => ['required'],
35+
];
36+
}
37+
38+
public function attributes(): array
39+
{
40+
return [
41+
'name' => __('field.name'),
42+
'email' => __('field.email'),
43+
'image' => __('field.image'),
44+
'phone' => __('field.phone'),
45+
'address' => __('field.address'),
46+
'marital_status' => __('field.marital_status'),
47+
'gender' => __('field.gender'),
48+
];
49+
}
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace App\Http\Requests;
4+
5+
use App\Enum\Role;
6+
use Illuminate\Contracts\Validation\ValidationRule;
7+
use Illuminate\Foundation\Http\FormRequest;
8+
use Illuminate\Validation\Rule;
9+
10+
class UpdateTeacherRequest extends FormRequest
11+
{
12+
/**
13+
* Determine if the user is authorized to make this request.
14+
*/
15+
public function authorize(): bool
16+
{
17+
return auth()->user()->isRole(Role::OWNER) || auth()->user()->isRole(Role::HEADMASTER) || auth()->user()->isRole(Role::ADMINISTRATOR);
18+
}
19+
20+
/**
21+
* Get the validation rules that apply to the request.
22+
*
23+
* @return array<string, ValidationRule|array|string>
24+
*/
25+
public function rules(): array
26+
{
27+
return [
28+
'name' => ['required'],
29+
'email' => ['required', 'email', Rule::unique('users', 'email')->ignore($this->id)],
30+
'image' => ['nullable', 'image', 'max:2048'],
31+
'phone' => ['required'],
32+
'address' => ['nullable'],
33+
'marital_status' => ['nullable'],
34+
'gender' => ['required'],
35+
];
36+
}
37+
38+
public function attributes(): array
39+
{
40+
return [
41+
'name' => __('field.name'),
42+
'email' => __('field.email'),
43+
'image' => __('field.image'),
44+
'phone' => __('field.phone'),
45+
'address' => __('field.address'),
46+
'marital_status' => __('field.marital_status'),
47+
'gender' => __('field.gender'),
48+
];
49+
}
50+
}

app/Models/User.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace App\Models;
44

5-
// use Illuminate\Contracts\Auth\MustVerifyEmail;
6-
5+
use App\Enum\Role;
6+
use Illuminate\Database\Eloquent\Builder;
77
use Illuminate\Database\Eloquent\Casts\Attribute;
88
use Illuminate\Database\Eloquent\Factories\HasFactory;
99
use Illuminate\Foundation\Auth\User as Authenticatable;
@@ -64,4 +64,14 @@ public function imageUrl(): Attribute
6464
get: fn () => 'https://ui-avatars.com/api/?name='.$this->name,
6565
);
6666
}
67+
68+
public function isRole(Role $role): bool
69+
{
70+
return Role::tryFrom($this->role) === $role;
71+
}
72+
73+
public function scopeRole(Builder $query, Role $role)
74+
{
75+
return $query->where('role', $role);
76+
}
6777
}

lang/en/field.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@
1717
'password' => 'Password',
1818
'password_confirmation' => 'Password Confirmation',
1919
'current_password' => 'Current Password',
20+
'role' => 'Role',
21+
'image' => 'Image',
22+
'phone' => 'Phone',
23+
'address' => 'Address',
24+
'marital_status' => 'Marital Status',
25+
'gender' => 'Gender',
2026
];

lang/en/menu.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
'profile' => 'Profile',
1717
'change_password' => 'Change Password',
1818
'locale' => 'Language',
19+
'teacher' => 'Teacher',
1920
];

lang/id/field.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@
1717
'password' => 'Password',
1818
'password_confirmation' => 'Konfirmasi Password',
1919
'current_password' => 'Password Sekarang',
20+
'role' => 'Peran',
21+
'image' => 'Gambar',
22+
'phone' => 'Nomor Telepon',
23+
'address' => 'Alamat',
24+
'marital_status' => 'Status Perkawinan',
25+
'gender' => 'Jenis Kelamin',
2026
];

lang/id/menu.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
'profile' => 'Profil',
1717
'change_password' => 'Ganti Password',
1818
'locale' => 'Bahasa',
19+
'teacher' => 'Pengajar',
1920
];

resources/menu/verticalMenu.json

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,63 @@
11
{
2-
"menu": [
3-
{
4-
"url": "dashboard",
5-
"name": "menu.dashboard",
6-
"icon": "menu-icon tf-icons bx bx-home-circle",
7-
"slug": "dashboard"
8-
},
9-
{
10-
"name": "menu.account",
11-
"icon": "menu-icon tf-icons bx bx bx-user",
12-
"slug": "account.*",
13-
"submenu": [
2+
"menu": [
143
{
15-
"url": "account.profile.edit",
16-
"name": "menu.profile",
17-
"slug": "account.profile.edit"
4+
"url": "dashboard",
5+
"name": "menu.dashboard",
6+
"icon": "menu-icon tf-icons bx bx-home-circle",
7+
"slug": "dashboard",
8+
"role": [
9+
"owner",
10+
"headmaster",
11+
"admin",
12+
"student_guardian"
13+
]
1814
},
1915
{
20-
"url": "account.password.edit",
21-
"name": "menu.change_password",
22-
"slug": "account.password.edit"
16+
"url": "teacher.index",
17+
"name": "menu.teacher",
18+
"icon": "menu-icon tf-icons bx bx-user-voice",
19+
"slug": "teacher.*",
20+
"role": [
21+
"owner",
22+
"headmaster",
23+
"admin",
24+
"student_guardian"
25+
]
26+
},
27+
{
28+
"name": "menu.account",
29+
"icon": "menu-icon tf-icons bx bx bx-user",
30+
"slug": "account.*",
31+
"role": [
32+
"owner",
33+
"headmaster",
34+
"admin",
35+
"student_guardian"
36+
],
37+
"submenu": [
38+
{
39+
"url": "account.profile.edit",
40+
"name": "menu.profile",
41+
"slug": "account.profile.edit",
42+
"role": [
43+
"owner",
44+
"headmaster",
45+
"admin",
46+
"student_guardian"
47+
]
48+
},
49+
{
50+
"url": "account.password.edit",
51+
"name": "menu.change_password",
52+
"slug": "account.password.edit",
53+
"role": [
54+
"owner",
55+
"headmaster",
56+
"admin",
57+
"student_guardian"
58+
]
59+
}
60+
]
2361
}
24-
]
25-
}
26-
]
62+
]
2763
}

0 commit comments

Comments
 (0)