Compare commits

...

2 Commits

Author SHA1 Message Date
f38f8a286f [Login Admin]
Done
2025-09-01 09:45:58 +07:00
6588ee8c46 [Admin] 2025-09-01 08:59:34 +07:00
10 changed files with 256 additions and 107 deletions

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminAuthController extends Controller
{
public function showLogin()
{
return view('admin.auth.login');
}
public function login(Request $request)
{
$credentials = $request->validate([
'email' => ['required','email'],
'password' => ['required'],
]);
$remember = $request->boolean('remember');
if (Auth::guard('admin')->attempt($credentials, $remember)) {
$request->session()->regenerate();
return redirect()->intended(route('admin.dashboard'));
}
return back()->withErrors([
'email' => 'Email atau password salah.',
])->onlyInput('email');
}
public function logout(Request $request)
{
Auth::guard('admin')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('admin.login');
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Admin extends Authenticatable
{
use Notifiable;
protected $fillable = ['name','email','password'];
protected $hidden = ['password','remember_token'];
}

View File

@ -2,93 +2,38 @@
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session"
|
*/
'guards' => [
// Guard untuk user biasa
'web' => [
'driver' => 'session',
'provider' => 'users',
],
// Guard untuk admin
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
// Provider untuk user biasa
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
// Provider untuk admin
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that each reset token will be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
| The throttle setting is the number of seconds a user must wait before
| generating more password reset tokens. This prevents the user from
| quickly generating a very large amount of password reset tokens.
|
*/
'passwords' => [
'users' => [
@ -97,18 +42,13 @@ return [
'expire' => 60,
'throttle' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_reset_tokens',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,

View File

@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('admins');
}
};

View File

@ -2,16 +2,20 @@
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Models\Admin;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class AdminSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
Admin::updateOrCreate(
['email' => 'admin@example.com'],
[
'name' => 'Super Admin',
'password' => Hash::make('password123'), // ganti setelah login
]
);
}
}

View File

@ -7,16 +7,10 @@ use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
// \App\Models\User::factory(10)->create();
// \App\Models\User::factory()->create([
// 'name' => 'Test User',
// 'email' => 'test@example.com',
// ]);
$this->call([
AdminSeeder::class,
]);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,109 @@
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Login Admin</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: #ffffff;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.login-card {
background: #EFEFEF;
border-radius: 15px;
box-shadow: 0 0 25px rgb(0, 123, 255);
width: 100%;
max-width: 400px; /* batas lebar maksimum */
padding: 30px;
}
.login-logo {
display: block;
margin: 0 auto 15px;
max-width: 130px;
}
.btn-login {
background-color: #3bb9ff;
border: none;
border-radius: 8px;
}
.btn-login:hover {
background-color: #1a8edb;
}
.form-control {
border-radius: 10px;
}
/* Responsive padding */
@media (max-width: 576px) {
.login-card {
padding: 20px;
margin: 10px;
}
.login-logo {
max-width: 100px;
}
h4 {
font-size: 1.2rem;
}
p {
font-size: 0.9rem;
}
}
</style>
</head>
<body>
<div class="login-card">
<div class="text-center mb-3">
<!-- Logo -->
<img src="{{ asset('images/logo.png') }}" alt="Logo" class="login-logo">
</div>
<h4 class="text-center mb-2 fw-bold">SELAMAT DATANG</h4>
<p class="text-center text-muted mb-4">Selamat datang! Silakan masukkan detail Anda.</p>
@if ($errors->any())
<div class="alert alert-danger">
{{ $errors->first() }}
</div>
@endif
<form action="{{ route('admin.login.post') }}" method="POST">
@csrf
<div class="mb-3">
<label class="form-label">Nama</label>
<input type="email" name="email" value="{{ old('email') }}" class="form-control"
placeholder="Masukkan nama Anda" required autofocus>
</div>
<div class="mb-3">
<label class="form-label">Kata Sandi</label>
<input type="password" name="password" class="form-control"
placeholder="Masukkan kata sandi Anda" required>
</div>
<div class="d-flex justify-content-between align-items-center mb-3 flex-wrap">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember">
<label class="form-check-label" for="remember">Ingat saya</label>
</div>
<a href="#" class="text-decoration-none mt-2 mt-sm-0">Lupa kata sandi</a>
</div>
<button type="submit" class="btn btn-login text-white w-100">Login</button>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Admin Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="p-4">
<div class="container">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3>Admin Dashboard</h3>
<form action="{{ route('admin.logout') }}" method="POST">
@csrf
<button class="btn btn-outline-danger">Logout</button>
</form>
</div>
<div class="alert alert-success">Berhasil login sebagai <strong>{{ auth('admin')->user()->name }}</strong></div>
</div>
</body>
</html>

View File

@ -1,18 +1,19 @@
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AdminAuthController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('welcome');
Route::prefix('admin')->name('admin.')->group(function () {
Route::middleware('guest:admin')->group(function () {
Route::get('/login', [AdminAuthController::class, 'showLogin'])->name('login');
Route::post('/login', [AdminAuthController::class, 'login'])->name('login.post');
});
Route::middleware('auth:admin')->group(function () {
Route::get('/dashboard', function () {
return view('admin.dashboard');
})->name('dashboard');
Route::post('/logout', [AdminAuthController::class, 'logout'])->name('logout');
});
});