commit
2c90c8a43a
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$user = Auth::user();
|
||||
return view('auth.profile', compact('user'));
|
||||
}
|
||||
|
||||
public function updateData(request $request)
|
||||
{
|
||||
$customMessage = [
|
||||
'username.required' => 'Username wajib diisi',
|
||||
'username.max' => 'Username maksimal 12 karakter',
|
||||
'username.string' => 'Username harus berupa string',
|
||||
'username.unique' => 'Username sudah terdaftar',
|
||||
|
||||
'name.required' => 'Nama wajib diisi',
|
||||
'name.max' => 'Nama maksimal 255 karakter',
|
||||
'name.string' => 'Nama harus berupa string',
|
||||
'name.unique' => 'Nama sudah terdaftar',
|
||||
|
||||
'email.required' => 'Email wajib diisi',
|
||||
'email.email' => 'Email tidak valid',
|
||||
'email.unique' => 'Email sudah terdaftar',
|
||||
'email.max' => 'Email maksimal 255 karakter',
|
||||
'email.string' => 'Email harus berupa string',
|
||||
|
||||
'avatar.image' => 'Foto profile harus berupa gambar',
|
||||
'avatar.mimes' => 'Format foto profile tidak sesuai, harus jpeg, png, atau jpg',
|
||||
'avatar.max' => 'Ukuran foto profile maksimal 2MB',
|
||||
];
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'username' => 'required|string|max:12|unique:users,username,' . Auth::user()->id,
|
||||
'name' => 'required|string|max:255|unique:users,name,' . Auth::user()->id,
|
||||
'email' => 'required|string|email|max:255|unique:users,email,' . Auth::user()->id,
|
||||
'avatar' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
|
||||
], $customMessage);
|
||||
|
||||
if ($validator->fails()) {
|
||||
toast($validator->messages()->all()[0], 'error')->position('top-right')->autoclose(3000);
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
|
||||
try {
|
||||
$user = User::findOrFail(Auth::id());
|
||||
$user->username = $request->username;
|
||||
$user->name = $request->name;
|
||||
$user->email = $request->email;
|
||||
|
||||
if ($request->hasFile('avatar')) {
|
||||
|
||||
$path = $request->file('avatar')->store('avatars', 'public');
|
||||
|
||||
if (!empty($user->avatar) && Storage::disk('public')->exists($user->avatar)) {
|
||||
Storage::disk('public')->delete($user->avatar);
|
||||
}
|
||||
$user->avatar = $path;
|
||||
}
|
||||
|
||||
$user->save();
|
||||
toast('Data berhasil diubah', 'success')->position('top-right')->autoclose(3000);
|
||||
return redirect()->back();
|
||||
} catch (\Throwable $th) {
|
||||
toast('Terjadi kesalahan', 'error')->position('top-right')->autoclose(3000);
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePassword(request $request)
|
||||
{
|
||||
$customMessage = [
|
||||
'new_password.required' => 'Password wajib diisi',
|
||||
'new_password.confirmed' => 'Konfirmasi password tidak cocok',
|
||||
'new_password.min' => 'Password minimal 8 karakter',
|
||||
];
|
||||
|
||||
$user = User::find(Auth::user()->id);
|
||||
if (Hash::check($request->old_password, $user->password)) {
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'new_password' => 'required|string|min:8|confirmed',
|
||||
], $customMessage);
|
||||
|
||||
if ($validator->fails()) {
|
||||
toast($validator->messages()->all()[0], 'error')->position('top-right')->autoclose(3000);
|
||||
return redirect()->back()->withInput();
|
||||
}
|
||||
|
||||
$user->password = Hash::make($request->new_password);
|
||||
|
||||
try {
|
||||
$user->save();
|
||||
toast('Password berhasil diubah', 'success')->position('top-right')->autoclose(3000);
|
||||
return redirect()->back();
|
||||
} catch (\Throwable $th) {
|
||||
toast('Terjadi kesalahan', 'error')->position('top-right')->autoclose(3000);
|
||||
return redirect()->back();
|
||||
}
|
||||
} else {
|
||||
toast('Password lama tidak cocok', 'error')->position('top-right')->autoclose(3000);
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ class User extends Authenticatable
|
|||
'email',
|
||||
'password',
|
||||
'role',
|
||||
'avatar'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,7 @@ public function up(): void
|
|||
$table->enum('role', ['admin', 'user'])->default('user');
|
||||
$table->string('activation_code')->nullable();
|
||||
$table->boolean('is_active')->default(false);
|
||||
$table->string('avatar')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
|||
function previewImage(event) {
|
||||
var input = event.target;
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onload = function () {
|
||||
var previewImg = document.getElementById("preview-img");
|
||||
|
||||
previewImg.src = reader.result;
|
||||
};
|
||||
|
||||
if (input.files && input.files[0]) {
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,195 @@
|
|||
@extends('layouts.app')
|
||||
@push('title', 'Profile')
|
||||
@section('content')
|
||||
<div class="page-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="position-relative mx-n4 mt-n4">
|
||||
<div class="profile-wid-bg profile-setting-img">
|
||||
<img src="assets/images/profile-bg.jpg" class="profile-wid-img" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xxl-3">
|
||||
<div class="card mt-n5">
|
||||
<div class="card-body p-4">
|
||||
<div class="text-center">
|
||||
<div class="profile-user position-relative d-inline-block mx-auto mb-4">
|
||||
<img src="{{ $user->avatar ? asset('storage/' . $user->avatar) : asset('assets/images/users/user-dummy-img.jpg') }}"
|
||||
class="rounded-circle avatar-xl img-thumbnail user-profile-image"
|
||||
alt="user-profile-image" id="preview-img">
|
||||
</div>
|
||||
<h5 class="fs-16 mb-1">{{ $user->name }}</h5>
|
||||
<p class="text-muted mb-0">{{ $user->role }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end card-->
|
||||
</div>
|
||||
<!--end col-->
|
||||
<div class="col-xxl-9">
|
||||
<div class="card mt-xxl-n5">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs-custom rounded card-header-tabs border-bottom-0" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-bs-toggle="tab" href="#personalDetails" role="tab">
|
||||
<i class="fas fa-home"></i>
|
||||
Data Personal
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#changePassword" role="tab">
|
||||
<i class="far fa-user"></i>
|
||||
Ubah Password
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="personalDetails" role="tabpanel">
|
||||
<form action="{{ route('profile.update_data') }}" class="needs-validation" novalidate
|
||||
id="personalDetailsForm" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="username"
|
||||
placeholder="Masukan username anda" name="username"
|
||||
value="{{ old('username', $user->username) }}" required>
|
||||
<div class="invalid-feedback">
|
||||
Harap masukan username anda
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
<div class="col-lg-6">
|
||||
<div class="mb-3">
|
||||
<label for="fullname" class="form-label">Nama Lengkap</label>
|
||||
<input type="text" class="form-control" id="name"
|
||||
placeholder="Masukan nama lengkap anda" name="name"
|
||||
value="{{ old('name', $user->name) }}" required>
|
||||
<div class="invalid-feedback">
|
||||
Harap masukan nama lengkap anda
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
<div class="col-lg-6">
|
||||
<div class="mb-3">
|
||||
<label for="emailInput" class="form-label">Alamat Email</label>
|
||||
<input type="email" class="form-control" id="email"
|
||||
placeholder="Masukan alamat email anda" name="email"
|
||||
value="{{ old('email', $user->email) }}" required>
|
||||
<div class="invalid-feedback">
|
||||
Harap masukan alamat email anda
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
<div class="col-lg-6">
|
||||
<div class="mb-3">
|
||||
<label for="avatarInput" class="form-label">Foto Profile</label>
|
||||
<input type="file" class="form-control" id="avatar" name="avatar"
|
||||
accept="image/jpeg,image/png,image/jpg"
|
||||
onchange="previewImage(event)">
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
<div class="col-lg-12">
|
||||
<div class="hstack gap-2 justify-content-end">
|
||||
<button type="submit" class="btn btn-success">Ubah</button>
|
||||
<button type="button" class="btn btn-soft-secondary">Batal</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
</div>
|
||||
<!--end row-->
|
||||
</form>
|
||||
</div>
|
||||
<!--end tab-pane-->
|
||||
<div class="tab-pane" id="changePassword" role="tabpanel">
|
||||
<form action="{{ route('profile.update_password') }}" class="needs-validation"
|
||||
novalidate id="changePasswordForm" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="row g-2">
|
||||
<div class="col-lg-4">
|
||||
<div>
|
||||
<label for="oldpasswordInput" class="form-label">Password
|
||||
Lama</label>
|
||||
<input type="password" class="form-control" id="oldpasswordInput"
|
||||
placeholder="Masukan password lama anda" name="old_password"
|
||||
required>
|
||||
<div class="invalid-feedback">
|
||||
Harap masukan password lama anda
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
<div class="col-lg-4">
|
||||
<div>
|
||||
<label for="newpasswordInput" class="form-label">Password
|
||||
Baru</label>
|
||||
<input type="password" class="form-control" id="newpasswordInput"
|
||||
placeholder="Masukan password baru anda" name="new_password"
|
||||
required>
|
||||
<div class="invalid-feedback">
|
||||
Harap masukan password baru anda
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
<div class="col-lg-4">
|
||||
<div>
|
||||
<label for="confirmpasswordInput" class="form-label">Konfirmasi
|
||||
Password</label>
|
||||
<input type="password" class="form-control" id="confirmpasswordInput"
|
||||
placeholder="Masukan konfirmasi password baru anda"
|
||||
name="new_password_confirmation" required>
|
||||
<div class="invalid-feedback">
|
||||
Harap masukan konfirmasi password baru anda
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
{{-- <div class="col-lg-12">
|
||||
<div class="mb-3">
|
||||
<a href="javascript:void(0);"
|
||||
class="link-primary text-decoration-underline">Lupa Password ?</a>
|
||||
</div>
|
||||
</div> --}}
|
||||
<!--end col-->
|
||||
<div class="col-lg-12">
|
||||
<div class="text-end">
|
||||
<button type="submit" class="btn btn-success">Ubah Password</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
</div>
|
||||
<!--end row-->
|
||||
</form>
|
||||
</div>
|
||||
<!--end tab-pane-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end col-->
|
||||
</div>
|
||||
<!--end row-->
|
||||
|
||||
</div>
|
||||
<!-- container-fluid -->
|
||||
</div><!-- End Page-content -->
|
||||
|
||||
@push('other-js')
|
||||
<!-- profile-setting init js -->
|
||||
<script src="{{ asset('assets/js/pages/customJs/auth/profile.js') }}"></script>
|
||||
|
||||
<script src="{{ asset('assets/js/pages/form-validation.init.js') }}"></script>
|
||||
@endpush
|
||||
@endsection
|
|
@ -604,7 +604,7 @@ class="form-check-input">
|
|||
@stack('other-js')
|
||||
|
||||
<!-- App js -->
|
||||
<script src="assets/js/app.js"></script>
|
||||
<script src="assets/js/customApp.js"></script>
|
||||
<script src="assets/libs/jquery/jquery.min.js"></script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -168,7 +168,8 @@ class="btn btn-icon btn-topbar btn-ghost-secondary rounded-circle light-dark-mod
|
|||
<button type="button" class="btn" id="page-header-user-dropdown" data-bs-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
<span class="d-flex align-items-center">
|
||||
<img class="rounded-circle header-profile-user" src="assets/images/users/avatar-1.jpg"
|
||||
<img class="rounded-circle header-profile-user"
|
||||
src="{{ Auth::user()->avatar ? asset('storage/' . Auth::user()->avatar) : asset('assets/images/users/user-dummy-img.jpg') }}"
|
||||
alt="Header Avatar">
|
||||
<span class="text-start ms-xl-2">
|
||||
<span
|
||||
|
@ -181,29 +182,10 @@ class="d-none d-xl-block ms-1 fs-12 text-muted user-name-sub-text">{{ Auth::user
|
|||
<div class="dropdown-menu dropdown-menu-end">
|
||||
<!-- item-->
|
||||
<h6 class="dropdown-header">Selamat Datang {{ Auth::user()->name }}!</h6>
|
||||
<a class="dropdown-item" href="pages-profile.html"><i
|
||||
<a class="dropdown-item" href="{{ route('profile.index') }}"><i
|
||||
class="mdi mdi-account-circle text-muted fs-16 align-middle me-1"></i> <span
|
||||
class="align-middle">Profile</span></a>
|
||||
<a class="dropdown-item" href="apps-chat.html"><i
|
||||
class="mdi mdi-message-text-outline text-muted fs-16 align-middle me-1"></i>
|
||||
<span class="align-middle">Messages</span></a>
|
||||
<a class="dropdown-item" href="apps-tasks-kanban.html"><i
|
||||
class="mdi mdi-calendar-check-outline text-muted fs-16 align-middle me-1"></i>
|
||||
<span class="align-middle">Taskboard</span></a>
|
||||
<a class="dropdown-item" href="pages-faqs.html"><i
|
||||
class="mdi mdi-lifebuoy text-muted fs-16 align-middle me-1"></i> <span
|
||||
class="align-middle">Help</span></a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="pages-profile.html"><i
|
||||
class="mdi mdi-wallet text-muted fs-16 align-middle me-1"></i> <span
|
||||
class="align-middle">Balance : <b>$5971.67</b></span></a>
|
||||
<a class="dropdown-item" href="pages-profile-settings.html"><span
|
||||
class="badge bg-soft-success text-success mt-1 float-end">New</span><i
|
||||
class="mdi mdi-cog-outline text-muted fs-16 align-middle me-1"></i> <span
|
||||
class="align-middle">Settings</span></a>
|
||||
<a class="dropdown-item" href="auth-lockscreen-basic.html"><i
|
||||
class="mdi mdi-lock text-muted fs-16 align-middle me-1"></i> <span
|
||||
class="align-middle">Lock screen</span></a>
|
||||
<form action="{{ route('auth.logout') }}" class="d-inline" method="POST">
|
||||
@csrf
|
||||
<button type="submit" class="dropdown-item">
|
||||
|
@ -211,9 +193,6 @@ class="align-middle">Lock screen</span></a>
|
|||
class="align-middle" data-key="t-logout">Logout</span>
|
||||
</button>
|
||||
</form>
|
||||
{{-- <a class="dropdown-item" href="auth-logout-basic.html"><i
|
||||
class="mdi mdi-logout text-muted fs-16 align-middle me-1"></i> <span
|
||||
class="align-middle" data-key="t-logout">Logout</span></a> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
use App\Http\Controllers\AssessmentHistoryController;
|
||||
use App\Http\Controllers\Auth\AuthenticatedSessionController;
|
||||
use App\Http\Controllers\Auth\PasswordResetLinkController;
|
||||
use App\Http\Controllers\Auth\ProfileController;
|
||||
use App\Http\Controllers\Auth\RegisteredUserController;
|
||||
use App\Http\Controllers\Auth\TwoStepVerifyController;
|
||||
use App\Http\Controllers\DashboardController;
|
||||
|
@ -60,6 +61,12 @@
|
|||
Route::middleware(['auth', 'verifiedAcount'])->group(function () {
|
||||
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])->name('auth.logout');
|
||||
|
||||
Route::prefix('profile')->controller(ProfileController::class)->name('profile.')->group(function () {
|
||||
Route::get('/', 'index')->name('index');
|
||||
Route::put('/', 'updateData')->name('update_data');
|
||||
Route::put('/password', 'updatePassword')->name('update_password');
|
||||
});
|
||||
|
||||
Route::prefix('location')->controller(LocationController::class)->name('location.')->group(function () {
|
||||
Route::get('/get-province', 'getProvinces')->name('get_provinces');
|
||||
Route::get('/get-regency/{id}', 'getRegencies')->name('get_regencies');
|
||||
|
|
Loading…
Reference in New Issue