feat(profile): create function update profile picture
This commit is contained in:
parent
f02a867398
commit
27f3673c7f
|
@ -7,6 +7,7 @@
|
|||
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
|
||||
|
@ -35,12 +36,17 @@ public function updateData(request $request)
|
|||
'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()) {
|
||||
|
@ -48,12 +54,22 @@ public function updateData(request $request)
|
|||
return redirect()->back()->withInput();
|
||||
}
|
||||
|
||||
$user = User::find(Auth::user()->id);
|
||||
$user->username = $request->username;
|
||||
$user->name = $request->name;
|
||||
$user->email = $request->email;
|
||||
|
||||
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();
|
||||
|
@ -65,7 +81,6 @@ public function updateData(request $request)
|
|||
|
||||
public function updatePassword(request $request)
|
||||
{
|
||||
// dd($request->all());
|
||||
$customMessage = [
|
||||
'new_password.required' => 'Password wajib diisi',
|
||||
'new_password.confirmed' => 'Konfirmasi password tidak cocok',
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\ProfileUpdateRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the user's profile form.
|
||||
*/
|
||||
public function edit(Request $request): View
|
||||
{
|
||||
return view('profile.edit', [
|
||||
'user' => $request->user(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user's profile information.
|
||||
*/
|
||||
public function update(ProfileUpdateRequest $request): RedirectResponse
|
||||
{
|
||||
$request->user()->fill($request->validated());
|
||||
|
||||
if ($request->user()->isDirty('email')) {
|
||||
$request->user()->email_verified_at = null;
|
||||
}
|
||||
|
||||
$request->user()->save();
|
||||
|
||||
return Redirect::route('profile.edit')->with('status', 'profile-updated');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the user's account.
|
||||
*/
|
||||
public function destroy(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validateWithBag('userDeletion', [
|
||||
'password' => ['required', 'current_password'],
|
||||
]);
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
Auth::logout();
|
||||
|
||||
$user->delete();
|
||||
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return Redirect::to('/');
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,40 +1,14 @@
|
|||
document
|
||||
.querySelector("#profile-img-file-input")
|
||||
.addEventListener("change", function () {
|
||||
var o = document.querySelector(".user-profile-image"),
|
||||
e = document.querySelector(".profile-img-file-input").files[0],
|
||||
i = new FileReader();
|
||||
i.addEventListener(
|
||||
"load",
|
||||
function () {
|
||||
o.src = i.result;
|
||||
},
|
||||
!1
|
||||
),
|
||||
e && i.readAsDataURL(e);
|
||||
});
|
||||
var count = 2;
|
||||
function new_link() {
|
||||
count++;
|
||||
var o = document.createElement("div"),
|
||||
e =
|
||||
'<div class="row"><div class="col-lg-12"><div class="mb-3"><label for="jobTitle1" class="form-label">Job Title</label><input type="text" class="form-control" id="jobTitle1" placeholder="Job title"></div></div><div class="col-lg-6"><div class="mb-3"><label for="companyName" class="form-label">Company Name</label><input type="text" class="form-control" id="companyName" placeholder="Company name"></div></div><div class="col-lg-6"><div class="mb-3"><label for="choices-single-default3" class="form-label">Experience Years</label><div class="row"><div class="col-lg-5"><select class="form-control" data-trigger name="choices-single-default3"> <option value="">Select years</option><option value="Choice 1">2001</option><option value="Choice 2">2002</option><option value="Choice 3">2003</option><option value="Choice 4">2004</option><option value="Choice 5">2005</option><option value="Choice 6">2006</option><option value="Choice 7">2007</option><option value="Choice 8">2008</option><option value="Choice 9">2009</option><option value="Choice 10">2010</option><option value="Choice 11">2011</option><option value="Choice 12">2012</option><option value="Choice 13">2013</option><option value="Choice 14">2014</option><option value="Choice 15">2015</option><option value="Choice 16">2016</option><option value="Choice 17">2017</option><option value="Choice 18">2018</option><option value="Choice 19">2019</option><option value="Choice 20">2020</option><option value="Choice 21">2021</option><option value="Choice 22">2022</option></select></div><div class="col-auto align-self-center">to</div><div class="col-lg-5"><select class="form-control" data-trigger name="choices-single-default2"><option value="">Select years</option><option value="Choice 1">2001</option><option value="Choice 2">2002</option><option value="Choice 3">2003</option><option value="Choice 4">2004</option><option value="Choice 5">2005</option><option value="Choice 6">2006</option><option value="Choice 7">2007</option><option value="Choice 8">2008</option><option value="Choice 9">2009</option><option value="Choice 10">2010</option><option value="Choice 11">2011</option><option value="Choice 12">2012</option><option value="Choice 13">2013</option><option value="Choice 14">2014</option><option value="Choice 15">2015</option><option value="Choice 16">2016</option><option value="Choice 17">2017</option><option value="Choice 18">2018</option><option value="Choice 19">2019</option><option value="Choice 20">2020</option><option value="Choice 21">2021</option><option value="Choice 22">2022</option></select></div></div></div></div><div class="col-lg-12"><div class="mb-3"><label for="jobDescription" class="form-label">Job Description</label><textarea class="form-control" id="jobDescription" rows="3" placeholder="Enter description"></textarea></div></div><div class="hstack gap-2 justify-content-end"><a class="btn btn-success" href="javascript:deleteEl(' +
|
||||
(o.id = count) +
|
||||
')">Delete</a></div></div>';
|
||||
(o.innerHTML = document.getElementById("newForm").innerHTML + e),
|
||||
document.getElementById("newlink").appendChild(o);
|
||||
var t = document.querySelectorAll("[data-trigger]");
|
||||
for (i = 0; i < t.length; ++i) {
|
||||
var l = t[i];
|
||||
new Choices(l, {
|
||||
placeholderValue: "This is a placeholder set in the config",
|
||||
searchPlaceholderValue: "This is a search placeholder",
|
||||
searchEnabled: !1,
|
||||
});
|
||||
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]);
|
||||
}
|
||||
}
|
||||
function deleteEl(o) {
|
||||
d = document;
|
||||
o = d.getElementById(o);
|
||||
d.getElementById("newlink").removeChild(o);
|
||||
}
|
||||
|
|
|
@ -16,20 +16,12 @@
|
|||
<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="assets/images/users/avatar-1.jpg"
|
||||
<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">
|
||||
<div class="avatar-xs p-0 rounded-circle profile-photo-edit">
|
||||
<input id="profile-img-file-input" type="file" class="profile-img-file-input">
|
||||
<label for="profile-img-file-input" class="profile-photo-edit avatar-xs">
|
||||
<span class="avatar-title rounded-circle bg-light text-body">
|
||||
<i class="ri-camera-fill"></i>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
alt="user-profile-image" id="preview-img">
|
||||
</div>
|
||||
<h5 class="fs-16 mb-1">Anna Adame</h5>
|
||||
<p class="text-muted mb-0">Lead Designer / Developer</p>
|
||||
<h5 class="fs-16 mb-1">{{ $user->name }}</h5>
|
||||
<p class="text-muted mb-0">{{ $user->role }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -58,7 +50,7 @@ class="rounded-circle avatar-xl img-thumbnail user-profile-image"
|
|||
<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">
|
||||
id="personalDetailsForm" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="row">
|
||||
|
@ -98,6 +90,15 @@ class="rounded-circle avatar-xl img-thumbnail user-profile-image"
|
|||
</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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue