Membuat Halaman Profil Sederhana di Admin Laravel 9 - Keza Felice
News Update
Loading...

Jumat, 06 Mei 2022

Membuat Halaman Profil Sederhana di Admin Laravel 9


Beberapa waktu lalu kita sudah berhasil membuat aplikasi Laravel mulai dari instalasi sampai masuk ke halaman dashboard. Saat ini kita akan lanjutkan dengan membuat halaman profil sederhana untuk user yang sedang login.

Beberapa hal yang akan kita lakukan:

  1. Membuat tampilan halaman profil user sederhana.
  2. Menambahkan menu link menuju ke halaman profil.
  3. Menambahkan route untuk menampilkan halaman profil.
  4. Membuat file controller untuk profil.
  5. Menambahkan kolom photo pada tabel users untuk menyimpan data foto.
  6. Menambahkan photo pada atribut fillable di model user.
  7. Menambahkan route untuk mengubah data pada tabel users yang diubah dari halaman profil.
  8. Membuat proses update profil.

Membuat Tampilan Halaman Profil User Sederhana


Buatlah file baru di dalam folder resources/views/layouts, beri nama profile.blade.php. Sebagai informasi, semua file untuk tampilan (view) menggunakan ekstensi .blade.php di belakangnya.

Isikkan di dalam file profile.blade.php dengan kode sebagai berikut:

@extends('layouts.app')

@section('content')

@endsection

@extends('layouts.app') artinya kita akan menggunakan file app.blade.php yang berada di dalam folder resources/views/layouts sebagai layout atau kerangka utama, dengan kata lain profile.blade.php yang berisi konten akan di-include-kan ke dalam app.blade.php yang berisi layout html utama.

Untuk mengisi konten halaman kita masukkan ke dalam area di antara @section('content') dan @endsection. Parameter content di @section('content') sendiri berdasarkan dari penamaan @yield('content') di app.blade.php. Jadi kalau namanya @yield('isi') maka dituliskan @section('isi').

Isikan setelah @section('content'), sebagai berikut:

<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Profile') }}</div>

                <div class="card-body">
                    
                    @if(session('status'))
                    <div class="alert alert-success alert-dismissible fade show" role="alert">
                        {{ session('status') }}
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                    </div>
                    @endif

                    <div class="row">
                        <div class="col-md-4">
                            @if($user->photo)
                                <img src="{{ asset('storage/photos/'.$user->photo) }}" class="img-thumbnail rounded mx-auto d-block">
                            @else
                                <img src="{{ asset('img/profile.png') }}" class="img-thumbnail rounded mx-auto d-block">
                            @endif
                            
                        </div>
                        <div class="col-md-8">
                            <form method="POST" action="{{ route('profile.update', $user->id) }}" enctype="multipart/form-data">
                                @method('PATCH')
                                @csrf

                                <div class="row mb-3">
                                    <label for="name" class="col-md-4 col-form-label text-md-end">{{ __('Name') }}</label>

                                    <div class="col-md-6">
                                        <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ $user->name }}" required autocomplete="name">

                                        @error('name')
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $message }}</strong>
                                            </span>
                                        @enderror
                                    </div>
                                </div>

                                <div class="row mb-3">
                                    <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

                                    <div class="col-md-6">
                                        <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email', $user->email) }}" required autocomplete="email">

                                        @error('email')
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $message }}</strong>
                                            </span>
                                        @enderror
                                    </div>
                                </div>

                                <div class="row mb-3">
                                    <label for="old_password" class="col-md-4 col-form-label text-md-end">{{ __('Old Password') }}</label>

                                    <div class="col-md-6">
                                        <input id="old_password" type="password" class="form-control @error('old_password') is-invalid @enderror" name="old_password" autocomplete="old-password">

                                        @error('old_password')
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $message }}</strong>
                                            </span>
                                        @enderror
                                    </div>
                                </div>

                                <div class="row mb-3">
                                    <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('New Password') }}</label>

                                    <div class="col-md-6">
                                        <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" autocomplete="new-password">

                                        @error('password')
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $message }}</strong>
                                            </span>
                                        @enderror
                                    </div>
                                </div>

                                <div class="row mb-3">
                                    <label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>

                                    <div class="col-md-6">
                                        <input id="password-confirm" type="password" class="form-control" name="password_confirmation" autocomplete="new-password">
                                    </div>
                                </div>

                                <div class="row mb-3">
                                    <label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Change Profile Photo') }}</label>

                                    <div class="col-md-6">
                                        <input id="photo" type="file" class="form-control" name="photo">
                                    </div>
                                </div>

                                <div class="row mb-0">
                                    <div class="col-md-6 offset-md-4">
                                        <button type="submit" class="btn btn-primary">
                                            {{ __('Update Profile') }}
                                        </button>
                                    </div>
                                </div>
                            </form>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Sehingga keseluruhan kodenya akan menjadi sebagai berikut:

Agar halaman profil ini bisa diakses maka diperlukan link sehingga ketika link tersebut diklik maka akan mengarahkan ke halaman profil. Jadi berikutnya kita akan membuat menu link halaman profil.

Menambahkan Menu Link Menuju Halaman Profil


Kita akan membuat menu link di bagian navbar tepatnya sebelum logout. Jadi, kita perlu menuju ke file app.blade.php di dalam folder layouts. Tambahkan kode berikut setelah baris 60 atau setelah <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">:

<a class="dropdown-item" href="{{ route('profile.index') }}">{{ __('Profile') }}</a>

Hasilnya akan tampil sebagai berikut:


Setiap teks yang ditampilkan ditulis sebagai berikut: {{ __('teks') }}. Hal ini berfungsi untuk keperluan translasi. Sementara profile.index pada link href {{ route('profile.index') }} adalah pemanggilan untuk nama route. Nama route ini akan kita tulis juga pada routes/web.php.

Menambahkan Route untuk Menampilkan Halaman Profil.


Buka file web.php di dalam folder routes. Tuliskan di dalamnya:

Route::get('/profile', [App\Http\Controllers\ProfileController::class, 'index'])->name('profile.index');

Pada saat halaman memanggil /profile (nama route: profile.index) maka akan diolah di dalam method index di ProfileController.

Maka selanjutnya kita perlu membuat file ProfileController.

Membuat ProfileController


Siapkan command prompt, masuk ke folder aplikasi web-app, ketik:

php artisan make:controller ProfileController

Perintah ini akan menghasilkan file controller bernama ProfileController di dalam folder app/Http/Controllers.

Perhatikan kode di bawah ini:

class ProfileController extends Controller
{

    //tuliskan kode di sini

}

Isikan pada area di antara tanda kurawal dengan kode berikut:

public function index()
{
    $user = User::findOrFail(Auth::id());

    return view('profile', compact('user'));
}

Jangan lupa untuk memanggil class User, tuliskan di bawah namespace App\Http\Controllers;:

use App\Models\User;

Setelah kita membuat ProfileController dan mengisikan method index sebenarnya kita sudah bisa menampilkan halaman profil, hanya saja kit perlu menambahkan kolom foto pada tabel users untuk menyimpan data foto yang akan di-input-kan. Jadi mari kita membuatnya.

Menambahkan Kolom Photo pada Tabel Users


Seperti biasa, siapkan command prompt, ketik:

php artisan make:migration add_photo_to_users_table --table=users

Perintah ini akan menghasilkan file baru di dalam migrations. Awalan nama file ini adalah tanggal pembuatan disusul dengan 6 digit angkat dan kemudian nama file, contoh: 2022_05_05_094506_add_photo_to_users_table.php.

Buka file migrations tersebut, isikan sebagai berikut masing-masing pada method up dan down:

/**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('photo')->nullable()->after('password');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('photo');
        });
    }

$table->string('photo')->nullable(); artinya kolom foto dibuat dengan tipe string dan boleh tidak diisi (kosong/nullable). after('password') artinya kolom foto tersebut akan dibuat berada di posisi setelah kolom password.

Terakhir, kita perlu menjalankan perintah migrate agar bisa dieksekusi ke dalam tabel users.

php artisan migrate:fresh

migrate:fresh artinya akan melakukan migrate ulang sehingga akan menambahkan kolom photo ke dalam tabel users.

Menambahkan Photo pada Atribut Fillable di Model Users


Setelah berhasil menambahkan kolom photo kita perlu memasukkan photo ke dalam atribut $fillable. Tujuannya agar saat melakukan proses input dan edit menggunakan Mass Assignment maka data dapat diolah ke dalam tabel.

Buka file model User di dalam folder app/Models. Pada $fillable tambahkan photo, sehingga kode akan terlihat sebagai berikut:

protected $fillable = [
    'name',
    'email',
    'password',
    'photo'
];

Menambahkan Route untuk proses Update User


Route untuk menampilkan halaman profil sudah kita tambahkan sebelumnya. Kita juga perlu menambahkan route untuk proses update saat halaman profil tersebut akan diubah datanya.

Buka web.php lalu tambahkan kode berikut:

Route::patch('/profile/{id}', [App\Http\Controllers\ProfileController::class, 'update'])->name('profile.update');

Membut Proses Update Profil


Buka kembali ProfileController, lalu tambahkan dengan kode berikut:

public function update(Request $request, $id)
{
    request()->validate([
        'name'       => 'required|string|min:2|max:100',
        'email'      => 'required|email|unique:users,email, ' . $id . ',id',
        'old_password' => 'nullable|string',
        'password' => 'nullable|required_with:old_password|string|confirmed|min:6'
    ]);

    $user = User::find($id);

    $user->name = $request->name;
    $user->email = $request->email;

    if ($request->filled('old_password')) {
        if (Hash::check($request->old_password, $user->password)) {
            $user->update([
                'password' => Hash::make($request->password)
            ]);
        } else {
            return back()
                ->withErrors(['old_password' => __('Please enter the correct password')])
                ->withInput();
        }
    }

    if (request()->hasFile('photo')) {
        if($user->photo && file_exists(storage_path('app/public/photos/' . $user->photo))){
            Storage::delete('app/public/photos/'.$user->photo);
        }

        $file = $request->file('photo');
        $fileName = $file->hashName() . '.' . $file->getClientOriginalExtension();
        $request->photo->move(storage_path('app/public/photos'), $fileName);
        $user->photo = $fileName;
    }


    $user->save();

    return back()->with('status', 'Profile updated!');
}

Tambahkan setelah namespace:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;

Terakhir kita perlu membuatkan symbolic link, yaitu link yang akan menghubungkan folder storage ke folder public sehingga kita dapat akses melalui public.

Caranya jalankan perintah berikut di command prompt:

php artisan storage:link

Inilah tampilan hasil akhir dari halaman profil yang sudah kita buat.


Jika ingin mengubah foto profil, klik "Choose File" untuk mengunggah file foto, kemudian klik tombol "Update Profil", hasilnya:


Demikian tutorial cara membuat halaman profil sederhana di Laravel 9. Semoga bermanfaat.

Kalian bisa melihat source code aplikasi ini di Github, linknya sebagai berikut: https://github.com/cafeteriaid/web-app.

Share with your friends

Give us your opinion

Hi! Aku Keza Felice, seorang Content Writer, Ghost Writer, Penulis Novel, dan penikmat musik. Terima kasih sudah berkenan mampir. Untuk mengenaliku lebih dekat lagi, silakan kunjungi Instagram @Keza236_queen

Notification
Selamat Datang di Blog Keza Queen.
Done