Tambah WelcomeController, Attendance model, dan migration
|
|
@ -2,19 +2,20 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\UserDosen;
|
||||
use App\Models\UserStaff;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$dosen = User::query()
|
||||
$dosen = UserDosen::query()
|
||||
->where('role', 'dosen')
|
||||
->orderBy('nama')
|
||||
->get();
|
||||
|
||||
$teknisi = User::query()
|
||||
$teknisi = UserStaff::query()
|
||||
->whereIn('role', ['teknisi', 'staff'])
|
||||
->orderBy('nama')
|
||||
->get();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\UserDosen;
|
||||
use App\Models\UserStaff;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$q = trim((string) $request->query('q', ''));
|
||||
$role = trim((string) $request->query('role', ''));
|
||||
$perPageInput = (string) $request->query('per_page', '10');
|
||||
|
||||
$allowedPerPage = ['10', '25', '50', '100', 'all'];
|
||||
if (!in_array($perPageInput, $allowedPerPage, true)) {
|
||||
$perPageInput = '10';
|
||||
}
|
||||
|
||||
$perPage = $perPageInput === 'all' ? 100000 : (int) $perPageInput;
|
||||
|
||||
// Query dari users_dosen (Dosen)
|
||||
$dosenQuery = UserDosen::query();
|
||||
|
||||
// Query dari users_staff (Staff & Teknisi)
|
||||
$staffQuery = UserStaff::query();
|
||||
|
||||
// Apply search filter
|
||||
if ($q !== '') {
|
||||
$dosenQuery->where(function ($sub) use ($q) {
|
||||
$sub->where('nama', 'ilike', "%{$q}%")
|
||||
->orWhere('nip', 'ilike', "%{$q}%")
|
||||
->orWhere('nidn', 'ilike', "%{$q}%");
|
||||
});
|
||||
|
||||
$staffQuery->where(function ($sub) use ($q) {
|
||||
$sub->where('nama', 'ilike', "%{$q}%")
|
||||
->orWhere('nip', 'ilike', "%{$q}%")
|
||||
->orWhere('nidn', 'ilike', "%{$q}%");
|
||||
});
|
||||
}
|
||||
|
||||
// Apply role filter
|
||||
if ($role !== '') {
|
||||
if ($role === 'dosen') {
|
||||
$staffQuery = null; // Only show dosen
|
||||
} else {
|
||||
$dosenQuery = null; // Only show staff/teknisi
|
||||
if (in_array($role, ['staff', 'teknisi'])) {
|
||||
$staffQuery->where('role', $role);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge results
|
||||
$dosen = $dosenQuery ? $dosenQuery->get() : collect();
|
||||
$staff = $staffQuery ? $staffQuery->get() : collect();
|
||||
|
||||
$allUsers = $dosen->merge($staff)->sortBy('nama');
|
||||
$totalCount = $allUsers->count();
|
||||
|
||||
// Manual pagination
|
||||
$page = (int) $request->query('page', 1);
|
||||
$offset = ($page - 1) * $perPage;
|
||||
$items = $allUsers->slice($offset, $perPage)->values();
|
||||
|
||||
// Create a Length Aware paginator instance
|
||||
$users = new \Illuminate\Pagination\LengthAwarePaginator(
|
||||
$items,
|
||||
$totalCount,
|
||||
$perPage,
|
||||
$page,
|
||||
[
|
||||
'path' => route('users.index'),
|
||||
'query' => $request->query(),
|
||||
]
|
||||
);
|
||||
|
||||
return view('user.index', [
|
||||
'users' => $users,
|
||||
'q' => $q,
|
||||
'role' => $role,
|
||||
'perPage' => $perPageInput,
|
||||
'roleOptions' => ['dosen', 'teknisi', 'staff'],
|
||||
'totalCount' => $totalCount,
|
||||
]);
|
||||
}
|
||||
|
||||
public function dosen(Request $request): View
|
||||
{
|
||||
$q = trim((string) $request->query('q', ''));
|
||||
$perPageInput = (string) $request->query('per_page', '10');
|
||||
|
||||
$allowedPerPage = ['10', '25', '50', '100', 'all'];
|
||||
if (!in_array($perPageInput, $allowedPerPage, true)) {
|
||||
$perPageInput = '10';
|
||||
}
|
||||
|
||||
$perPage = $perPageInput === 'all' ? 100000 : (int) $perPageInput;
|
||||
|
||||
$query = UserDosen::query()->where('role', 'dosen')->orderBy('nama');
|
||||
|
||||
if ($q !== '') {
|
||||
$query->where(function ($sub) use ($q) {
|
||||
$sub->where('nama', 'ilike', "%{$q}%")
|
||||
->orWhere('nip', 'ilike', "%{$q}%")
|
||||
->orWhere('nidn', 'ilike', "%{$q}%");
|
||||
});
|
||||
}
|
||||
|
||||
$dosen = $query->paginate($perPage)->withQueryString();
|
||||
$dosenCount = UserDosen::where('role', 'dosen')->count();
|
||||
|
||||
return view('Dosen.dosen', [
|
||||
'dosen' => $dosen,
|
||||
'dosenCount' => $dosenCount,
|
||||
'q' => $q,
|
||||
'perPage' => $perPageInput,
|
||||
]);
|
||||
}
|
||||
|
||||
public function staff(Request $request): View
|
||||
{
|
||||
$q = trim((string) $request->query('q', ''));
|
||||
$role = trim((string) $request->query('role', ''));
|
||||
$perPageInput = (string) $request->query('per_page', '10');
|
||||
|
||||
$allowedPerPage = ['10', '25', '50', '100', 'all'];
|
||||
if (!in_array($perPageInput, $allowedPerPage, true)) {
|
||||
$perPageInput = '10';
|
||||
}
|
||||
|
||||
$perPage = $perPageInput === 'all' ? 100000 : (int) $perPageInput;
|
||||
|
||||
$query = UserStaff::query()->orderBy('nama');
|
||||
|
||||
if ($q !== '') {
|
||||
$query->where(function ($sub) use ($q) {
|
||||
$sub->where('nama', 'ilike', "%{$q}%")
|
||||
->orWhere('nip', 'ilike', "%{$q}%")
|
||||
->orWhere('nidn', 'ilike', "%{$q}%");
|
||||
});
|
||||
}
|
||||
|
||||
if ($role !== '') {
|
||||
$query->where('role', $role);
|
||||
}
|
||||
|
||||
$staff = $query->paginate($perPage)->withQueryString();
|
||||
$staffCount = UserStaff::count();
|
||||
|
||||
return view('staff.staff', [
|
||||
'staff' => $staff,
|
||||
'staffCount' => $staffCount,
|
||||
'q' => $q,
|
||||
'role' => $role,
|
||||
'perPage' => $perPageInput,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
$roleOptions = ['dosen', 'teknisi', 'staff'];
|
||||
|
||||
// Determine which view to show based on the URL path
|
||||
if (request()->path() === 'dosen/create') {
|
||||
return view('Dosen.create', [
|
||||
'roleOptions' => $roleOptions,
|
||||
]);
|
||||
}
|
||||
|
||||
// Default to staff create view
|
||||
return view('staff.create', [
|
||||
'roleOptions' => $roleOptions,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
// Clean up input - trim whitespace and convert empty strings to null
|
||||
$request->merge([
|
||||
'nama' => trim((string) $request->input('nama')),
|
||||
'nip' => ($nip = trim((string) $request->input('nip'))) === '' ? null : $nip,
|
||||
'nidn' => ($nidn = trim((string) $request->input('nidn'))) === '' ? null : $nidn,
|
||||
'bagian' => trim((string) $request->input('bagian')),
|
||||
'foto' => trim((string) $request->input('foto')),
|
||||
]);
|
||||
|
||||
$role = $request->input('role');
|
||||
|
||||
if ($role === 'dosen') {
|
||||
// Validate for Dosen
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'nip' => ['nullable', 'string', 'max:255', 'unique:users_dosen,nip'],
|
||||
'nidn' => ['nullable', 'string', 'max:255', 'unique:users_dosen,nidn'],
|
||||
'prodi' => ['nullable', 'string', 'max:255'],
|
||||
'foto' => ['nullable', 'string', 'max:2048'],
|
||||
'role' => ['required', 'in:dosen'],
|
||||
]);
|
||||
|
||||
UserDosen::create($validated);
|
||||
|
||||
return redirect()->route('users.dosen')->with('success', 'Data dosen berhasil ditambahkan.');
|
||||
} else {
|
||||
// Validate for Staff/Teknisi
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'nip' => ['nullable', 'string', 'max:255', 'unique:users_staff,nip'],
|
||||
'nidn' => ['nullable', 'string', 'max:255', 'unique:users_staff,nidn'],
|
||||
'bagian' => ['nullable', 'string', 'max:255'],
|
||||
'foto' => ['nullable', 'string', 'max:2048'],
|
||||
'role' => ['required', 'in:staff,teknisi'],
|
||||
]);
|
||||
|
||||
UserStaff::create($validated);
|
||||
|
||||
return redirect()->route('users.staff')->with('success', 'Data staff/teknisi berhasil ditambahkan.');
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(UserDosen | UserStaff $user): View
|
||||
{
|
||||
$roleOptions = ['dosen', 'teknisi', 'staff'];
|
||||
|
||||
// Determine which view to show based on the URL path or user type
|
||||
if (request()->path() === "dosen/{$user->getKey()}/edit" || $user instanceof UserDosen) {
|
||||
return view('Dosen.edit', [
|
||||
'user' => $user,
|
||||
'roleOptions' => $roleOptions,
|
||||
]);
|
||||
}
|
||||
|
||||
return view('staff.edit', [
|
||||
'user' => $user,
|
||||
'roleOptions' => $roleOptions,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request, UserDosen | UserStaff $user): RedirectResponse
|
||||
{
|
||||
// Clean up input - trim whitespace and convert empty strings to null
|
||||
$request->merge([
|
||||
'nama' => trim((string) $request->input('nama')),
|
||||
'nip' => ($nip = trim((string) $request->input('nip'))) === '' ? null : $nip,
|
||||
'nidn' => ($nidn = trim((string) $request->input('nidn'))) === '' ? null : $nidn,
|
||||
'bagian' => trim((string) $request->input('bagian')),
|
||||
'foto' => trim((string) $request->input('foto')),
|
||||
]);
|
||||
|
||||
if ($user instanceof UserDosen) {
|
||||
// Update Dosen
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'nip' => ['nullable', 'string', 'max:255', 'unique:users_dosen,nip,' . $user->getKey() . ',id'],
|
||||
'nidn' => ['nullable', 'string', 'max:255', 'unique:users_dosen,nidn,' . $user->getKey() . ',id'],
|
||||
'prodi' => ['nullable', 'string', 'max:255'],
|
||||
'foto' => ['nullable', 'string', 'max:2048'],
|
||||
'role' => ['required', 'in:dosen'],
|
||||
]);
|
||||
|
||||
$user->update($validated);
|
||||
|
||||
return redirect()->route('users.dosen')->with('success', 'Data dosen berhasil diperbarui.');
|
||||
} else {
|
||||
// Update Staff/Teknisi
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'nip' => ['nullable', 'string', 'max:255', 'unique:users_staff,nip,' . $user->getKey() . ',id'],
|
||||
'nidn' => ['nullable', 'string', 'max:255', 'unique:users_staff,nidn,' . $user->getKey() . ',id'],
|
||||
'bagian' => ['nullable', 'string', 'max:255'],
|
||||
'foto' => ['nullable', 'string', 'max:2048'],
|
||||
'role' => ['required', 'in:staff,teknisi'],
|
||||
]);
|
||||
|
||||
$user->update($validated);
|
||||
|
||||
return redirect()->route('users.staff')->with('success', 'Data staff/teknisi berhasil diperbarui.');
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy(Request $request, string $id): RedirectResponse
|
||||
{
|
||||
// Try to find in UserDosen first, then UserStaff
|
||||
$userDosen = UserDosen::find($id);
|
||||
$userStaff = UserStaff::find($id);
|
||||
|
||||
if ($userDosen) {
|
||||
$userDosen->delete();
|
||||
return redirect()->route('users.dosen')->with('success', 'Data dosen berhasil dihapus.');
|
||||
} elseif ($userStaff) {
|
||||
$userStaff->delete();
|
||||
return redirect()->route('users.staff')->with('success', 'Data staff/teknisi berhasil dihapus.');
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', 'Data user tidak ditemukan.');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Attendance;
|
||||
use App\Models\UserDosen;
|
||||
use App\Models\UserStaff;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class WelcomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the welcome/management dashboard
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// Jika user sudah login, ambil data user dan attendance
|
||||
// Jika belum login, tampilkan halaman welcome dengan data default
|
||||
|
||||
$nama = null;
|
||||
$durasiMingguan = null;
|
||||
|
||||
// Cek apakah ada user yang sudah login
|
||||
if (Auth::check()) {
|
||||
$user = Auth::user();
|
||||
$nama = $user->nama ?? null;
|
||||
|
||||
// Ambil data durasi mingguan dari attendance table
|
||||
$durasiMingguan = Attendance::getDurationByDayThisWeek($user->id);
|
||||
} else {
|
||||
// Data default jika tidak ada user terautentikasi
|
||||
$nama = 'Dosen/Staff';
|
||||
$durasiMingguan = [
|
||||
'Senin' => 7.5,
|
||||
'Selasa' => 6.8,
|
||||
'Rabu' => 8.2,
|
||||
'Kamis' => 7.1,
|
||||
'Jumat' => 5.4,
|
||||
];
|
||||
}
|
||||
|
||||
return view('welcome', [
|
||||
'nama' => $nama,
|
||||
'durasiMingguan' => $durasiMingguan,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attendance data for a specific user
|
||||
* API endpoint untuk parsing data
|
||||
*/
|
||||
public function getAttendanceData(Request $request)
|
||||
{
|
||||
if (!Auth::check()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'User tidak terautentikasi',
|
||||
], 401);
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$durasiMingguan = Attendance::getDurationByDayThisWeek($user->id);
|
||||
$totalJam = array_sum($durasiMingguan);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'nama' => $user->nama,
|
||||
'durasiMingguan' => $durasiMingguan,
|
||||
'totalJam' => round($totalJam, 2),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record user check-in/check-out attendance
|
||||
*/
|
||||
public function recordAttendance(Request $request)
|
||||
{
|
||||
if (!Auth::check()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'User tidak terautentikasi',
|
||||
], 401);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'action' => 'required|in:check_in,check_out', // check_in atau check_out
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
$today = now()->toDateString();
|
||||
|
||||
// Cari atau buat record attendance untuk hari ini
|
||||
$attendance = Attendance::firstOrCreate(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
'tanggal' => $today,
|
||||
],
|
||||
[
|
||||
'user_type' => $user instanceof UserDosen ? 'dosen' : 'staff',
|
||||
]
|
||||
);
|
||||
|
||||
if ($validated['action'] === 'check_in') {
|
||||
$attendance->jam_masuk = now()->toTimeString();
|
||||
$attendance->keterangan = 'hadir';
|
||||
} else {
|
||||
$attendance->jam_keluar = now()->toTimeString();
|
||||
|
||||
// Hitung durasi jika sudah ada jam_masuk
|
||||
if ($attendance->jam_masuk) {
|
||||
$masuk = \Carbon\Carbon::createFromTimeString($attendance->jam_masuk);
|
||||
$keluar = \Carbon\Carbon::createFromTimeString($attendance->jam_keluar);
|
||||
$durasi = $masuk->diffInMinutes($keluar) / 60; // convert ke jam
|
||||
$attendance->durasi_jam = round($durasi, 2);
|
||||
}
|
||||
}
|
||||
|
||||
$attendance->save();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => $validated['action'] === 'check_in' ? 'Check-in berhasil' : 'Check-out berhasil',
|
||||
'attendance' => $attendance,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update status (online/tidak bisa diganggu)
|
||||
*/
|
||||
public function updateStatus(Request $request)
|
||||
{
|
||||
if (!Auth::check()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'User tidak terautentikasi',
|
||||
], 401);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'status' => 'required|in:online,dnd', // dnd = do not disturb
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
// Simpan status ke session atau database
|
||||
// Untuk sekarang, simpan di session
|
||||
session(['user_status' => $validated['status']]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Status diperbarui',
|
||||
'status' => $validated['status'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
|
||||
class Attendance extends Model
|
||||
{
|
||||
use HasUuids;
|
||||
|
||||
protected $table = 'attendances';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'user_type',
|
||||
'tanggal',
|
||||
'jam_masuk',
|
||||
'jam_keluar',
|
||||
'durasi_jam',
|
||||
'keterangan',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'tanggal' => 'date',
|
||||
'durasi_jam' => 'decimal:2',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the user (bisa UserDosen atau UserStaff)
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(UserDosen::class, 'user_id')
|
||||
->orWhere('user_type', 'dosen')
|
||||
->union(\DB::table('users_staff')->whereColumn('id', 'attendances.user_id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter minggu ini
|
||||
*/
|
||||
public function scopeThisWeek($query)
|
||||
{
|
||||
$startOfWeek = now()->startOfWeek();
|
||||
$endOfWeek = now()->endOfWeek();
|
||||
|
||||
return $query->whereBetween('tanggal', [$startOfWeek, $endOfWeek]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter hari kerja (Senin-Jumat)
|
||||
*/
|
||||
public function scopeWorkDays($query)
|
||||
{
|
||||
return $query->whereNotIn(\DB::raw('DAYOFWEEK(tanggal)'), [1, 7]); // 1=Sunday, 7=Saturday
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total durasi minggu ini
|
||||
*/
|
||||
public static function getTotalDurationThisWeek($userId)
|
||||
{
|
||||
return self::where('user_id', $userId)
|
||||
->thisWeek()
|
||||
->workDays()
|
||||
->sum('durasi_jam');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get durasi per hari minggu ini (Senin-Jumat)
|
||||
*/
|
||||
public static function getDurationByDayThisWeek($userId)
|
||||
{
|
||||
$days = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat'];
|
||||
$dayQuery = self::where('user_id', $userId)
|
||||
->thisWeek()
|
||||
->workDays()
|
||||
->get()
|
||||
->groupBy(function ($item) {
|
||||
$dayOfWeek = $item->tanggal->dayName;
|
||||
return match ($dayOfWeek) {
|
||||
'Monday' => 'Senin',
|
||||
'Tuesday' => 'Selasa',
|
||||
'Wednesday' => 'Rabu',
|
||||
'Thursday' => 'Kamis',
|
||||
'Friday' => 'Jumat',
|
||||
default => null,
|
||||
};
|
||||
});
|
||||
|
||||
$result = [];
|
||||
foreach ($days as $day) {
|
||||
$result[$day] = $dayQuery->get($day)?->sum('durasi_jam') ?? 0;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,14 +6,84 @@
|
|||
|
||||
class User extends Model
|
||||
{
|
||||
protected $table = 'users';
|
||||
protected $table = 'users_dosen';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'nama',
|
||||
'nip',
|
||||
'nidn',
|
||||
'foto',
|
||||
'role'
|
||||
'role',
|
||||
'password'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
protected $table = 'users_dosen';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'nama',
|
||||
'nip',
|
||||
'nidn',
|
||||
'foto',
|
||||
'role',
|
||||
'password'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
}
|
||||
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
protected $table = 'users_dosen';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'nama',
|
||||
'nip',
|
||||
'nidn',
|
||||
'foto',
|
||||
'role',
|
||||
'password'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserDosen extends Model
|
||||
{
|
||||
protected $table = 'users_dosen';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'nama',
|
||||
'nip',
|
||||
'nidn',
|
||||
'prodi',
|
||||
'foto',
|
||||
'role',
|
||||
'password'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
|
||||
/**
|
||||
* Boot the model.
|
||||
*/
|
||||
protected static function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
// Generate UUID untuk new records
|
||||
static::creating(function ($model) {
|
||||
if (empty($model->{$model->getKeyName()})) {
|
||||
$model->{$model->getKeyName()} = Str::uuid()->toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class UserStaff extends Model
|
||||
{
|
||||
protected $table = 'users_staff';
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'nama',
|
||||
'nip',
|
||||
'nidn',
|
||||
'bagian',
|
||||
'foto',
|
||||
'role',
|
||||
'password'
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
filepath = r"f:\Sempro TA\project\Laravel\TA\resources\views\Dosen\edit.blade.php"
|
||||
|
||||
# Read file
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
print(f"Total lines before: {len(lines)}")
|
||||
|
||||
# Keep only first 206 lines
|
||||
clean_lines = lines[:206]
|
||||
|
||||
# Write back
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.writelines(clean_lines)
|
||||
|
||||
print(f"Total lines after: {len(clean_lines)}")
|
||||
print("File truncated successfully!")
|
||||
|
|
@ -12,15 +12,41 @@
|
|||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn(['name', 'email', 'password', 'remember_token', 'email_verified_at']);
|
||||
// Only drop columns if they exist
|
||||
if (Schema::hasColumn('users', 'name')) {
|
||||
$table->dropColumn(['name']);
|
||||
}
|
||||
if (Schema::hasColumn('users', 'email')) {
|
||||
$table->dropColumn(['email']);
|
||||
}
|
||||
if (Schema::hasColumn('users', 'password')) {
|
||||
$table->dropColumn(['password']);
|
||||
}
|
||||
if (Schema::hasColumn('users', 'remember_token')) {
|
||||
$table->dropColumn(['remember_token']);
|
||||
}
|
||||
if (Schema::hasColumn('users', 'email_verified_at')) {
|
||||
$table->dropColumn(['email_verified_at']);
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
// Only add columns if they don't exist
|
||||
if (!Schema::hasColumn('users', 'nama')) {
|
||||
$table->string('nama')->after('id');
|
||||
}
|
||||
if (!Schema::hasColumn('users', 'nip')) {
|
||||
$table->string('nip')->unique()->nullable()->after('nama');
|
||||
}
|
||||
if (!Schema::hasColumn('users', 'nidn')) {
|
||||
$table->string('nidn')->unique()->nullable()->after('nip');
|
||||
}
|
||||
if (!Schema::hasColumn('users', 'foto')) {
|
||||
$table->string('foto')->nullable()->after('nidn');
|
||||
}
|
||||
if (!Schema::hasColumn('users', 'role')) {
|
||||
$table->string('role')->default('staff')->after('foto');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (!Schema::hasTable('users_staff')) {
|
||||
Schema::create('users_staff', function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
$table->string('nama');
|
||||
$table->string('nip')->unique()->nullable();
|
||||
$table->string('nidn')->unique()->nullable();
|
||||
$table->string('foto')->nullable();
|
||||
$table->enum('role', ['staff', 'teknisi'])->default('staff');
|
||||
$table->string('password')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users_staff');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Hanya buat tabel jika belum ada
|
||||
if (!Schema::hasTable('users_dosen')) {
|
||||
Schema::create('users_dosen', function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
$table->string('nama');
|
||||
$table->string('nip')->unique()->nullable();
|
||||
$table->string('nidn')->unique()->nullable();
|
||||
$table->string('prodi')->nullable();
|
||||
$table->string('foto')->nullable();
|
||||
$table->enum('role', ['dosen'])->default('dosen');
|
||||
$table->string('password')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users_dosen');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('attendances', function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
$table->uuid('user_id')->nullable();
|
||||
$table->string('user_type')->nullable(); // 'dosen' atau 'staff'
|
||||
$table->date('tanggal');
|
||||
$table->time('jam_masuk')->nullable();
|
||||
$table->time('jam_keluar')->nullable();
|
||||
$table->decimal('durasi_jam', 5, 2)->default(0); // durasi dalam jam (misal 7.5)
|
||||
$table->string('keterangan')->nullable(); // hadir, sakit, izin, dll
|
||||
$table->timestamps();
|
||||
|
||||
// Unique constraint agar 1 user hanya bisa 1 record per hari
|
||||
$table->unique(['user_id', 'tanggal']);
|
||||
|
||||
// Index untuk query cepat
|
||||
$table->index('user_id');
|
||||
$table->index('tanggal');
|
||||
$table->index(['user_type', 'tanggal']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('attendances');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,616 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tambah Dosen Baru - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 18px;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1rem; line-height: 1.1; color: var(--text); font-weight: 900; }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.85rem; }
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s ease;
|
||||
font-size: 0.9rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.22);
|
||||
}
|
||||
|
||||
.btn.primary:hover {
|
||||
box-shadow: 0 16px 32px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
padding: 28px 32px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 {
|
||||
font-size: 1.8rem;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.section-head p {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
padding: 36px 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 40px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.photo-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.photo-preview {
|
||||
width: 100%;
|
||||
aspect-ratio: 3/4;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 3.5rem;
|
||||
font-weight: 900;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: 0 16px 40px rgba(79, 70, 229, 0.25);
|
||||
border: 3px solid rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.photo-preview:hover {
|
||||
transform: scale(1.03);
|
||||
box-shadow: 0 20px 50px rgba(79, 70, 229, 0.32);
|
||||
}
|
||||
|
||||
.photo-preview img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.photo-initial {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.photo-label {
|
||||
border: 2px dashed rgba(79, 70, 229, 0.3);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(79, 70, 229, 0.02);
|
||||
}
|
||||
|
||||
.photo-label:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(79, 70, 229, 0.1);
|
||||
}
|
||||
|
||||
.photo-label-text {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 800;
|
||||
color: var(--primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.photo-label-hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.photo-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-row.full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-weight: 800;
|
||||
color: #475569;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 13px 14px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.25);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
transition: all 0.3s ease;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.input:focus, .select:focus {
|
||||
border-color: var(--primary);
|
||||
background: rgba(79, 70, 229, 0.02);
|
||||
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
|
||||
}
|
||||
|
||||
.input.error, .select.error {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.02);
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.field-error {
|
||||
font-size: 0.8rem;
|
||||
color: #dc2626;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.error-box {
|
||||
padding: 16px 20px;
|
||||
border-radius: 16px;
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
color: #7f1d1d;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.error-box strong {
|
||||
display: block;
|
||||
font-weight: 800;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.error-box ul {
|
||||
list-style: none;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.error-box li {
|
||||
font-weight: 700;
|
||||
margin-bottom: 6px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.error-box li:before {
|
||||
content: "•";
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.12);
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.btn.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 12px 24px rgba(16, 185, 129, 0.22);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn.success:hover {
|
||||
box-shadow: 0 16px 32px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.form-wrapper {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.section-head h2 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.photo-preview {
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-shell">
|
||||
<header class="topbar">
|
||||
<a class="brand" href="{{ route('users.index') }}">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>Tambah Dosen</h1>
|
||||
<p>Data dosen baru</p>
|
||||
</div>
|
||||
</a>
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="{{ route('users.dosen') }}">Kembali</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<h2>👨🏫 Form Tambah Dosen Baru</h2>
|
||||
<p>Lengkapi informasi dosen dengan data yang akurat dan benar.</p>
|
||||
</div>
|
||||
|
||||
@if ($errors->any())
|
||||
<div style="padding: 0 32px; padding-top: 20px;">
|
||||
<div class="error-box">
|
||||
<strong>❌ Validasi gagal, periksa kembali data Anda:</strong>
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('dosen.store') }}" class="form-wrapper" id="dosenForm">
|
||||
@csrf
|
||||
|
||||
<!-- Photo Section -->
|
||||
<div class="photo-section">
|
||||
<div class="photo-preview" id="photoPreview">
|
||||
<div class="photo-initial" id="photoInitial">👨🏫</div>
|
||||
<img id="photoImg" style="display: none;" alt="Preview" />
|
||||
</div>
|
||||
<label class="photo-label" for="photoInput">
|
||||
<div class="photo-label-text">📤 Upload Foto</div>
|
||||
<div class="photo-label-hint">Klik untuk pilih gambar</div>
|
||||
</label>
|
||||
<input id="photoInput" class="photo-input" type="file" accept="image/*">
|
||||
<input
|
||||
id="fotoUrl"
|
||||
class="input"
|
||||
type="text"
|
||||
name="foto"
|
||||
value="{{ old('foto') }}"
|
||||
placeholder="atau URL gambar"
|
||||
>
|
||||
<div class="hint">📝 Gunakan file atau URL gambar untuk foto profil</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Fields -->
|
||||
<div class="form-fields">
|
||||
<!-- Nama -->
|
||||
<div class="field-row full">
|
||||
<div class="field">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input
|
||||
id="nama"
|
||||
class="input @error('nama') error @enderror"
|
||||
type="text"
|
||||
name="nama"
|
||||
value="{{ old('nama') }}"
|
||||
required
|
||||
>
|
||||
@error('nama')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Masukkan nama lengkap dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- NIP & NIDN -->
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label for="nip">NIP</label>
|
||||
<input
|
||||
id="nip"
|
||||
class="input @error('nip') error @enderror"
|
||||
type="text"
|
||||
name="nip"
|
||||
value="{{ old('nip') }}"
|
||||
placeholder="Contoh: 19850315 200901 1 001"
|
||||
>
|
||||
@error('nip')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Nomor Induk Pegawai (opsional)</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="nidn">NIDN</label>
|
||||
<input
|
||||
id="nidn"
|
||||
class="input @error('nidn') error @enderror"
|
||||
type="text"
|
||||
name="nidn"
|
||||
value="{{ old('nidn') }}"
|
||||
placeholder="Contoh: 0017058003"
|
||||
>
|
||||
@error('nidn')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Nomor Induk Dosen Nasional (opsional)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prodi -->
|
||||
<div class="field-row full">
|
||||
<div class="field">
|
||||
<label for="prodi">Program Studi <span class="required">*</span></label>
|
||||
<select
|
||||
id="prodi"
|
||||
class="select @error('prodi') error @enderror"
|
||||
name="prodi"
|
||||
required
|
||||
>
|
||||
<option value="">-- Pilih Program Studi --</option>
|
||||
<option value="Manajemen Informatika" @selected(old('prodi') === 'Manajemen Informatika')>Manajemen Informatika</option>
|
||||
<option value="Teknik Informatika" @selected(old('prodi') === 'Teknik Informatika')>Teknik Informatika</option>
|
||||
<option value="Teknik Komputer" @selected(old('prodi') === 'Teknik Komputer')>Teknik Komputer</option>
|
||||
<option value="Teknologi Rekayasa Komputer" @selected(old('prodi') === 'Teknologi Rekayasa Komputer')>Teknologi Rekayasa Komputer</option>
|
||||
</select>
|
||||
@error('prodi')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Pilih program studi untuk dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Role (Hidden for Dosen) -->
|
||||
<input type="hidden" name="role" value="dosen">
|
||||
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<button class="btn success" type="submit">✅ Simpan Dosen</button>
|
||||
<a class="btn ghost" href="{{ route('users.dosen') }}">❌ Batal</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const photoInput = document.getElementById('photoInput');
|
||||
const fotoUrl = document.getElementById('fotoUrl');
|
||||
const photoPreview = document.getElementById('photoPreview');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const dosenForm = document.getElementById('dosenForm');
|
||||
let isSubmitting = false;
|
||||
|
||||
// Prevent double submit
|
||||
dosenForm.addEventListener('submit', function(e) {
|
||||
if (isSubmitting) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
isSubmitting = true;
|
||||
|
||||
// Disable submit button
|
||||
const submitBtn = dosenForm.querySelector('button[type="submit"]');
|
||||
if (submitBtn) {
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.style.opacity = '0.6';
|
||||
submitBtn.style.cursor = 'not-allowed';
|
||||
submitBtn.textContent = '⏳ Sedang menyimpan...';
|
||||
}
|
||||
});
|
||||
|
||||
// Handle file input
|
||||
photoInput.addEventListener('change', (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
photoImg.src = event.target.result;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
fotoUrl.value = event.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle URL input
|
||||
fotoUrl.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
// Update initial dari nama
|
||||
namaInput.addEventListener('input', () => {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama && !photoImg.src) {
|
||||
const words = nama.split(/\s+/);
|
||||
const initials = words.slice(0, 2).map(w => w.charAt(0).toUpperCase()).join('');
|
||||
photoInitial.textContent = initials || '👨🏫';
|
||||
}
|
||||
});
|
||||
|
||||
// Restore state saat halaman load
|
||||
window.addEventListener('load', () => {
|
||||
// Reset form state jika ada error
|
||||
isSubmitting = false;
|
||||
const submitBtn = dosenForm.querySelector('button[type="submit"]');
|
||||
if (submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.style.opacity = '1';
|
||||
submitBtn.style.cursor = 'pointer';
|
||||
submitBtn.textContent = '✅ Simpan Dosen';
|
||||
}
|
||||
|
||||
if (fotoUrl.value.trim()) {
|
||||
fotoUrl.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (namaInput.value.trim()) {
|
||||
namaInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,620 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CRUD Dosen - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 12px 14px;
|
||||
font-size: 0.9rem;
|
||||
color: #475569;
|
||||
background: #f8fafc;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.12);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 18px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.92rem; }
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 7px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
}
|
||||
|
||||
.pill.dosen { background: linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); }
|
||||
.pill.teknisi { background: linear-gradient(135deg, var(--green), #14b8a6); }
|
||||
.pill.staff { background: linear-gradient(135deg, var(--orange), var(--orange)); }
|
||||
|
||||
.row-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 9px 12px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-sm:hover { transform: translateY(-2px); }
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 8px 16px rgba(16, 185, 129, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 8px 16px rgba(59, 130, 246, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 8px 16px rgba(239, 68, 68, 0.18);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.pager { display: inline-flex; gap: 8px; }
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="{{ route('users.index') }}"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="{{ route('users.dosen') }}" class="active"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="{{ route('users.staff') }}"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="{{ url('/dashboard') }}">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>CRUD Dosen</h1>
|
||||
<p>Kelola data dosen JTI</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn-sm success" href="{{ route('dosen.create') }}">Tambah Dosen</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Dosen</h2>
|
||||
<p>Kelola data dosen dengan fitur pencarian dan filter.</p>
|
||||
</div>
|
||||
<div class="meta">Total: {{ $dosenCount }}</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="{{ route('users.dosen') }}">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for="q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="{{ $q }}" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
@foreach (['10','25','50','100','all'] as $size)
|
||||
<option value="{{ $size }}" @selected($perPage === $size)>
|
||||
{{ $size === 'all' ? 'Semua' : $size }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="{{ route('users.dosen') }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="notice">{{ session('success') }}</div>
|
||||
@endif
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 70px;">Foto</th>
|
||||
<th>Nama</th>
|
||||
<th style="width: 180px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 190px;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($dosen as $item)
|
||||
<tr>
|
||||
<td>
|
||||
@php($fotoUrl = $resolveFoto($item->foto))
|
||||
<div class="avatar" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900;">{{ $item->nama }}</div>
|
||||
<div class="meta">ID: {{ $item->id }}</div>
|
||||
</td>
|
||||
<td>{{ $item->nip ?? '-' }}</td>
|
||||
<td>{{ $item->nidn ?? '-' }}</td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<a class="btn-sm primary" href="{{ route('dosen.edit', $item) }}">Edit</a>
|
||||
|
||||
<form method="POST" action="{{ route('dosen.destroy', $item) }}" onsubmit="return confirm('Hapus dosen ini?')" style="display:inline;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn-sm danger" type="submit">Hapus</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="5" class="meta">Belum ada data dosen.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan {{ $dosen->firstItem() ?? 0 }}–{{ $dosen->lastItem() ?? 0 }} dari {{ $dosenCount }}
|
||||
</div>
|
||||
<div class="pager">
|
||||
@if ($dosen->onFirstPage())
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
@else
|
||||
<a class="btn-sm ghost" href="{{ $dosen->previousPageUrl() }}">Sebelumnya</a>
|
||||
@endif
|
||||
|
||||
@if ($dosen->hasMorePages())
|
||||
<a class="btn-sm ghost" href="{{ $dosen->nextPageUrl() }}">Berikutnya</a>
|
||||
@else
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Edit Dosen - JTI</title>
|
||||
<style>
|
||||
:root { --primary: #4f46e5; --success: #10b981; --orange: #d97706; --text: #1f2937; --muted: #6b7280; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: 'Segoe UI', sans-serif; background: linear-gradient(135deg, #e0e7ff 0%, #eef2ff 100%); min-height: 100vh; color: var(--text); }
|
||||
.container { max-width: 900px; margin: 20px auto; padding: 0 16px; }
|
||||
.header { display: flex; justify-content: space-between; align-items: center; padding: 16px; background: white; border-radius: 16px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
|
||||
.header h1 { font-size: 20px; font-weight: 900; }
|
||||
.btn { padding: 10px 16px; border-radius: 8px; border: none; cursor: pointer; font-weight: 700; text-decoration: none; display: inline-block; transition: all 0.2s; }
|
||||
.btn:hover { transform: translateY(-2px); }
|
||||
.btn-ghost { background: #e2e8f0; color: #334155; }
|
||||
.btn-success { background: var(--success); color: white; }
|
||||
.card { background: white; border-radius: 16px; padding: 32px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
|
||||
.form-layout { display: grid; grid-template-columns: 280px 1fr; gap: 40px; }
|
||||
.photo-box { text-align: center; }
|
||||
.photo-preview { width: 100%; aspect-ratio: 3/4; background: linear-gradient(135deg, var(--primary), #7c3aed); border-radius: 16px; display: flex; align-items: center; justify-content: center; color: white; font-size: 48px; font-weight: 900; margin-bottom: 16px; overflow: hidden; position: relative; }
|
||||
.photo-preview img { width: 100%; height: 100%; object-fit: cover; position: absolute; }
|
||||
.photo-initial { position: relative; z-index: 1; }
|
||||
.file-input { display: none; }
|
||||
.file-label { display: block; padding: 12px; border: 2px dashed var(--primary); border-radius: 12px; cursor: pointer; color: var(--primary); font-weight: 700; margin-bottom: 12px; transition: all 0.2s; }
|
||||
.file-label:hover { background: rgba(79, 70, 229, 0.05); border-color: #7c3aed; }
|
||||
.form-group { margin-bottom: 24px; }
|
||||
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
|
||||
.form-row.full { grid-column: 1 / -1; }
|
||||
label { display: block; margin-bottom: 8px; font-weight: 700; color: #475569; font-size: 14px; }
|
||||
.required { color: var(--orange); }
|
||||
input, select { width: 100%; padding: 12px; border: 1.5px solid #cbd5e1; border-radius: 10px; font-size: 14px; font-family: inherit; }
|
||||
input:focus, select:focus { outline: none; border-color: var(--primary); background: rgba(79, 70, 229, 0.02); box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); }
|
||||
input.error, select.error { border-color: #ef4444; background: rgba(239, 68, 68, 0.02); }
|
||||
.error-text { color: #dc2626; font-size: 12px; margin-top: 4px; }
|
||||
.hint-text { color: #6b7280; font-size: 12px; margin-top: 4px; }
|
||||
.error-alert { background: #fee2e2; border: 1px solid #fecaca; border-radius: 12px; padding: 16px; margin-bottom: 20px; }
|
||||
.error-alert strong { color: #7f1d1d; display: block; margin-bottom: 8px; font-weight: 800; }
|
||||
.error-alert ul { list-style: none; padding-left: 20px; color: #b91c1c; }
|
||||
.error-alert li { margin-bottom: 4px; }
|
||||
.form-actions { display: flex; gap: 12px; margin-top: 40px; border-top: 1px solid #e2e8f0; padding-top: 24px; }
|
||||
.form-actions button, .form-actions a { flex: 1; padding: 12px; border-radius: 8px; border: none; font-weight: 700; cursor: pointer; text-align: center; transition: all 0.2s; }
|
||||
.form-actions button:disabled { opacity: 0.6; cursor: not-allowed; }
|
||||
@media (max-width: 800px) {
|
||||
.form-layout { grid-template-columns: 1fr; }
|
||||
.form-row { grid-template-columns: 1fr; }
|
||||
.header { flex-direction: column; gap: 12px; align-items: flex-start; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return '👨🏫';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : '👨🏫';
|
||||
};
|
||||
@endphp
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>✏️ Edit Dosen</h1>
|
||||
<a href="{{ route('users.dosen') }}" class="btn btn-ghost">Kembali</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
@if ($errors->any())
|
||||
<div class="error-alert">
|
||||
<strong>❌ Validasi gagal:</strong>
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<form method="POST" action="{{ route('dosen.update', $user) }}" id="editForm" class="form-layout">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="photo-box">
|
||||
<div class="photo-preview" id="photoPreview">
|
||||
<span id="photoInitial">{{ $makeInitial($user->nama) }}</span>
|
||||
<img id="photoImg" style="display: none;" alt="Foto Dosen" />
|
||||
</div>
|
||||
<label for="photoFile" class="file-label">📤 Ubah Foto</label>
|
||||
<input id="photoFile" type="file" accept="image/*" class="file-input">
|
||||
<input id="fotoUrl" type="text" name="foto" value="{{ old('foto', $user->foto) }}" placeholder="atau URL foto">
|
||||
<div class="hint-text">URL gambar untuk profil</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="form-row full">
|
||||
<div class="form-group">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input id="nama" type="text" name="nama" value="{{ old('nama', $user->nama) }}" required class="@error('nama') error @enderror">
|
||||
@error('nama')<div class="error-text">{{ $message }}</div>@enderror
|
||||
<div class="hint-text">Nama lengkap dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="nip">NIP</label>
|
||||
<input id="nip" type="text" name="nip" value="{{ old('nip', $user->nip) }}" placeholder="19850315 200901 1 001" class="@error('nip') error @enderror">
|
||||
@error('nip')<div class="error-text">{{ $message }}</div>@enderror
|
||||
<div class="hint-text">Nomor Induk Pegawai</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="nidn">NIDN</label>
|
||||
<input id="nidn" type="text" name="nidn" value="{{ old('nidn', $user->nidn) }}" placeholder="0017058003" class="@error('nidn') error @enderror">
|
||||
@error('nidn')<div class="error-text">{{ $message }}</div>@enderror
|
||||
<div class="hint-text">Nomor Induk Dosen Nasional</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row full">
|
||||
<div class="form-group">
|
||||
<label for="prodi">Program Studi <span class="required">*</span></label>
|
||||
<select id="prodi" name="prodi" required class="@error('prodi') error @enderror">
|
||||
<option value="">-- Pilih Program Studi --</option>
|
||||
<option value="Manajemen Informatika" @selected(old('prodi', $user->prodi) === 'Manajemen Informatika')>Manajemen Informatika</option>
|
||||
<option value="Teknik Informatika" @selected(old('prodi', $user->prodi) === 'Teknik Informatika')>Teknik Informatika</option>
|
||||
<option value="Teknik Komputer" @selected(old('prodi', $user->prodi) === 'Teknik Komputer')>Teknik Komputer</option>
|
||||
<option value="Teknologi Rekayasa Komputer" @selected(old('prodi', $user->prodi) === 'Teknologi Rekayasa Komputer')>Teknologi Rekayasa Komputer</option>
|
||||
</select>
|
||||
@error('prodi')<div class="error-text">{{ $message }}</div>@enderror
|
||||
<div class="hint-text">Program studi dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="role" value="dosen">
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-success" id="submitBtn">💾 Simpan Perubahan</button>
|
||||
<a href="{{ route('users.dosen') }}" class="btn btn-ghost">❌ Batal</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const photoFile = document.getElementById('photoFile');
|
||||
const fotoUrl = document.getElementById('fotoUrl');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const editForm = document.getElementById('editForm');
|
||||
const submitBtn = document.getElementById('submitBtn');
|
||||
let isSubmitting = false;
|
||||
|
||||
editForm.addEventListener('submit', function(e) {
|
||||
if (isSubmitting) { e.preventDefault(); return false; }
|
||||
isSubmitting = true;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = '⏳ Menyimpan...';
|
||||
});
|
||||
|
||||
photoFile.addEventListener('change', (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
photoImg.src = event.target.result;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
fotoUrl.value = event.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
|
||||
fotoUrl.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
namaInput.addEventListener('input', () => {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama && !photoImg.src) {
|
||||
const words = nama.split(/\s+/);
|
||||
const initials = words.slice(0, 2).map(w => w.charAt(0).toUpperCase()).join('');
|
||||
photoInitial.textContent = initials || '👨🏫';
|
||||
photoInitial.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
isSubmitting = false;
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = '💾 Simpan Perubahan';
|
||||
if (fotoUrl.value.trim()) {
|
||||
fotoUrl.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (namaInput.value.trim()) {
|
||||
namaInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,635 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CRUD Staff/Teknisi - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 12px 14px;
|
||||
font-size: 0.9rem;
|
||||
color: #475569;
|
||||
background: #f8fafc;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.12);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 18px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.92rem; }
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 7px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
}
|
||||
|
||||
.pill.dosen { background: linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); }
|
||||
.pill.teknisi { background: linear-gradient(135deg, var(--green), #14b8a6); }
|
||||
.pill.staff { background: linear-gradient(135deg, var(--orange), var(--orange)); }
|
||||
|
||||
.row-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 9px 12px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-sm:hover { transform: translateY(-2px); }
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 8px 16px rgba(16, 185, 129, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 8px 16px rgba(59, 130, 246, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 8px 16px rgba(239, 68, 68, 0.18);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.pager { display: inline-flex; gap: 8px; }
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="{{ route('users.index') }}"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="{{ route('users.dosen') }}"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="{{ route('users.staff') }}" class="active"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="{{ url('/dashboard') }}">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>CRUD Staff/Teknisi</h1>
|
||||
<p>Kelola data staff dan teknisi JTI</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn-sm success" href="{{ route('staff.create') }}">Tambah Staff/Teknisi</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Staff/Teknisi</h2>
|
||||
<p>Kelola data staff dan teknisi dengan fitur pencarian dan filter.</p>
|
||||
</div>
|
||||
<div class="meta">Total: {{ $staffCount }}</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="{{ route('users.staff') }}">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for="q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="{{ $q }}" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="role">Role</label>
|
||||
<select id="role" class="select" name="role">
|
||||
<option value="">Semua</option>
|
||||
<option value="staff" @selected($role === 'staff')>Staff</option>
|
||||
<option value="teknisi" @selected($role === 'teknisi')>Teknisi</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
@foreach (['10','25','50','100','all'] as $size)
|
||||
<option value="{{ $size }}" @selected($perPage === $size)>
|
||||
{{ $size === 'all' ? 'Semua' : $size }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="{{ route('users.staff') }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="notice">{{ session('success') }}</div>
|
||||
@endif
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 70px;">Foto</th>
|
||||
<th>Nama</th>
|
||||
<th style="width: 180px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 120px;">Role</th>
|
||||
<th style="width: 190px;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($staff as $item)
|
||||
<tr>
|
||||
<td>
|
||||
@php($fotoUrl = $resolveFoto($item->foto))
|
||||
<div class="avatar" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900;">{{ $item->nama }}</div>
|
||||
<div class="meta">ID: {{ $item->id }}</div>
|
||||
</td>
|
||||
<td>{{ $item->nip ?? '-' }}</td>
|
||||
<td>{{ $item->nidn ?? '-' }}</td>
|
||||
<td>
|
||||
@php($r = (string) ($item->role ?? 'staff'))
|
||||
@php($r = in_array($r, ['dosen', 'teknisi', 'staff'], true) ? $r : 'staff')
|
||||
<span class="pill {{ $r }}">{{ ucfirst($r) }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<a class="btn-sm primary" href="{{ route('staff.edit', $item) }}">Edit</a>
|
||||
|
||||
<form method="POST" action="{{ route('staff.destroy', $item) }}" onsubmit="return confirm('Hapus staff/teknisi ini?')" style="display:inline;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn-sm danger" type="submit">Hapus</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="meta">Belum ada data staff/teknisi.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan {{ $staff->firstItem() ?? 0 }}–{{ $staff->lastItem() ?? 0 }} dari {{ $staffCount }}
|
||||
</div>
|
||||
<div class="pager">
|
||||
@if ($staff->onFirstPage())
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
@else
|
||||
<a class="btn-sm ghost" href="{{ $staff->previousPageUrl() }}">Sebelumnya</a>
|
||||
@endif
|
||||
|
||||
@if ($staff->hasMorePages())
|
||||
<a class="btn-sm ghost" href="{{ $staff->nextPageUrl() }}">Berikutnya</a>
|
||||
@else
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard JTI - Politeknik Negeri Jember</title>
|
||||
<title>JTI Monitoring - Politeknik Negeri Jember</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
|
|
@ -226,6 +226,84 @@
|
|||
gap: 20px;
|
||||
}
|
||||
|
||||
.prodi-groups {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.prodi-group {
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.prodi-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed rgba(148, 163, 184, 0.35);
|
||||
}
|
||||
|
||||
.prodi-title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.prodi-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 999px;
|
||||
padding: 6px 10px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary), var(--primary-2));
|
||||
}
|
||||
|
||||
.bagian-groups {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.bagian-group {
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.bagian-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed rgba(148, 163, 184, 0.35);
|
||||
}
|
||||
|
||||
.bagian-title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.bagian-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 999px;
|
||||
padding: 6px 10px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--green), #14b8a6);
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
|
@ -258,7 +336,7 @@
|
|||
color: #fff;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
background-image: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 26px rgba(79, 70, 229, 0.28);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
|
|
@ -266,7 +344,7 @@
|
|||
}
|
||||
|
||||
.avatar.teknisi {
|
||||
background: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
background-image: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
box-shadow: 0 12px 26px rgba(5, 150, 105, 0.25);
|
||||
}
|
||||
|
||||
|
|
@ -275,14 +353,14 @@
|
|||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
background-image: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.avatar.teknisi .avatar-placeholder {
|
||||
background: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
background-image: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
|
|
@ -447,8 +525,8 @@
|
|||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h3 id="sectionTitle">Manajemen Informatika</h3>
|
||||
<span id="sectionDesc">Daftar Dosen dan Staff aktif Manajemen Informatika.</span>
|
||||
<h3 id="sectionTitle">Program Studi Dosen</h3>
|
||||
<span id="sectionDesc">Daftar dosen aktif berdasarkan program studi.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -471,14 +549,45 @@
|
|||
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<section id="dosenPane" class="role-pane active">
|
||||
@php
|
||||
$dosenByProdi = $dosen
|
||||
->sortBy([['prodi', 'asc'], ['nama', 'asc']])
|
||||
->groupBy(function ($item) {
|
||||
$prodi = trim((string) ($item->prodi ?? ''));
|
||||
return $prodi !== '' ? $prodi : 'Prodi Belum Ditentukan';
|
||||
});
|
||||
@endphp
|
||||
|
||||
@if ($dosenByProdi->isEmpty())
|
||||
<div class="empty-state">Belum ada data dosen di database.</div>
|
||||
@else
|
||||
<div class="prodi-groups">
|
||||
@foreach ($dosenByProdi as $prodiName => $prodiItems)
|
||||
<section class="prodi-group">
|
||||
<header class="prodi-head">
|
||||
<h4 class="prodi-title">{{ $prodiName }}</h4>
|
||||
<span class="prodi-count">{{ $prodiItems->count() }} Dosen</span>
|
||||
</header>
|
||||
|
||||
<div class="cards">
|
||||
@forelse ($dosen as $item)
|
||||
@foreach ($prodiItems as $item)
|
||||
<article class="card">
|
||||
<div class="avatar" @if($item->foto) style="background-image: url('{{ $item->foto }}')" @endif>
|
||||
@if(!$item->foto)
|
||||
@php
|
||||
$fotoUrl = $resolveFoto($item->foto);
|
||||
@endphp
|
||||
<div class="avatar" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
@ -492,18 +601,43 @@
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
@empty
|
||||
<div class="empty-state">Belum ada data dosen di database.</div>
|
||||
@endforelse
|
||||
@endforeach
|
||||
</div>
|
||||
</section>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</section>
|
||||
|
||||
<section id="teknisiPane" class="role-pane">
|
||||
@php
|
||||
$teknisiByBagian = $teknisi
|
||||
->sortBy([['bagian', 'asc'], ['nama', 'asc']])
|
||||
->groupBy(function ($item) {
|
||||
$bagian = trim((string) ($item->bagian ?? ''));
|
||||
return $bagian !== '' ? $bagian : 'Bagian Belum Ditentukan';
|
||||
});
|
||||
@endphp
|
||||
|
||||
@if ($teknisiByBagian->isEmpty())
|
||||
<div class="empty-state">Belum ada data teknisi/staff di database.</div>
|
||||
@else
|
||||
<div class="bagian-groups">
|
||||
@foreach ($teknisiByBagian as $bagianName => $bagianItems)
|
||||
<section class="bagian-group">
|
||||
<header class="bagian-head">
|
||||
<h4 class="bagian-title">{{ $bagianName }}</h4>
|
||||
<span class="bagian-count">{{ $bagianItems->count() }} Orang</span>
|
||||
</header>
|
||||
|
||||
<div class="cards">
|
||||
@forelse ($teknisi as $item)
|
||||
@foreach ($bagianItems as $item)
|
||||
<article class="card">
|
||||
<div class="avatar teknisi" @if($item->foto) style="background-image: url('{{ $item->foto }}')" @endif>
|
||||
@if(!$item->foto)
|
||||
@php
|
||||
$fotoUrl = $resolveFoto($item->foto);
|
||||
@endphp
|
||||
<div class="avatar teknisi" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
@ -517,11 +651,13 @@
|
|||
</div>
|
||||
</div>
|
||||
</article>
|
||||
@empty
|
||||
<div class="empty-state">Belum ada data teknisi/staff di database.</div>
|
||||
@endforelse
|
||||
@endforeach
|
||||
</div>
|
||||
</section>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</section>
|
||||
|
||||
<div class="footer-note">
|
||||
</div>
|
||||
|
|
@ -535,10 +671,8 @@ function showRole(role) {
|
|||
const btnDosen = document.getElementById('btnDosen');
|
||||
const btnTeknisi = document.getElementById('btnTeknisi');
|
||||
const heroTitle = document.getElementById('heroTitle');
|
||||
const heroSubtitle = document.getElementById('heroSubtitle');
|
||||
const sectionTitle = document.getElementById('sectionTitle');
|
||||
const sectionDesc = document.getElementById('sectionDesc');
|
||||
const roleBadge = document.getElementById('roleBadge');
|
||||
|
||||
const isDosen = role === 'dosen';
|
||||
|
||||
|
|
@ -548,15 +682,12 @@ function showRole(role) {
|
|||
btnTeknisi.classList.toggle('active', !isDosen);
|
||||
|
||||
heroTitle.textContent = isDosen ? 'Dosen JTI' : 'Teknisi JTI';
|
||||
heroSubtitle.textContent = isDosen
|
||||
? 'Menampilkan data dosen yang diambil langsung dari database.'
|
||||
: 'Menampilkan data teknisi/staff yang diambil langsung dari database.';
|
||||
sectionTitle.textContent = isDosen ? 'Manajemen Informatika' : 'Teknisi dan Staff';
|
||||
sectionTitle.textContent = isDosen ? 'Program Studi Dosen' : 'Teknisi dan Staff';
|
||||
sectionDesc.textContent = isDosen
|
||||
? 'Daftar dosen aktif dari database.'
|
||||
: 'Daftar teknisi dan staff dari database.';
|
||||
roleBadge.textContent = isDosen ? 'Role: Dosen' : 'Role: Teknisi';
|
||||
? 'Daftar dosen aktif berdasarkan program studi.'
|
||||
: 'Daftar teknisi dan staff aktif berdasarkan bagian.';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,569 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tambah Staff/Teknisi - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #e0fdf4;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #059669;
|
||||
--primary-2: #14b8a6;
|
||||
--purple: #4f46e5;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(5, 150, 105, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(20, 184, 166, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #d1fae5 0%, #e0fdf4 45%, #f0fdfa 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 900;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header-desc {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
padding: 36px;
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 36px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.photo-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.photo-frame {
|
||||
width: 100%;
|
||||
aspect-ratio: 3/4;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 4rem;
|
||||
font-weight: 900;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
box-shadow: 0 16px 36px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.photo-frame:hover {
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 20px 48px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.photo-frame img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.photo-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.photo-label {
|
||||
border: 2px dashed rgba(5, 150, 105, 0.3);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
}
|
||||
|
||||
.photo-label:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
}
|
||||
|
||||
.photo-label-text {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.photo-label-hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section.full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-weight: 800;
|
||||
color: #475569;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.field label .required {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.input, .select {
|
||||
padding: 13px 14px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.25);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.input:focus, .select:focus {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.1);
|
||||
}
|
||||
|
||||
.input::placeholder {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
margin: 18px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 16px;
|
||||
background: rgba(217, 119, 6, 0.08);
|
||||
border: 1px solid rgba(217, 119, 6, 0.18);
|
||||
color: #7c2d12;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.error-message ul {
|
||||
margin-top: 8px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.field-error {
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
color: #991b1b;
|
||||
font-weight: 700;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.input.error, .select.error {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.02);
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 14px;
|
||||
padding: 16px;
|
||||
background: rgba(5, 150, 105, 0.05);
|
||||
border-radius: 14px;
|
||||
border: 1.5px solid rgba(5, 150, 105, 0.2);
|
||||
}
|
||||
|
||||
.role-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"] {
|
||||
cursor: pointer;
|
||||
accent-color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.04);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"]:checked ~ label {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option label {
|
||||
cursor: pointer;
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
gap: 8px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.btn.primary:hover {
|
||||
box-shadow: 0 16px 32px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.form-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-shell">
|
||||
<header class="header">
|
||||
<h1 class="header-title">🔧 Tambah Staff/Teknisi</h1>
|
||||
<p class="header-desc">Lengkapi data staff atau teknisi dengan informasi yang akurat.</p>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
@if ($errors->any())
|
||||
<div class="error-message">
|
||||
<strong>❌ Terjadi kesalahan validasi:</strong>
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('staff.store') }}" class="form-container">
|
||||
@csrf
|
||||
|
||||
<!-- Foto Section -->
|
||||
<div class="photo-section">
|
||||
<div class="photo-frame" id="photoPreview">
|
||||
<span id="photoInitial">🔧</span>
|
||||
<img id="photoImg" style="display:none;" />
|
||||
</div>
|
||||
<label class="photo-label" for="fotoInput">
|
||||
<div class="photo-label-text">📤 Upload Foto</div>
|
||||
<div class="photo-label-hint">Klik untuk memilih gambar</div>
|
||||
</label>
|
||||
<input
|
||||
id="fotoInput"
|
||||
class="input"
|
||||
type="text"
|
||||
name="foto"
|
||||
value="{{ old('foto') }}"
|
||||
placeholder="atau masukkan URL foto"
|
||||
>
|
||||
<div class="hint">Format: URL gambar (https://...)</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Fields -->
|
||||
<div class="form-fields">
|
||||
<!-- Row 1: Nama -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input
|
||||
id="nama"
|
||||
class="input @error('nama') error @enderror"
|
||||
type="text"
|
||||
name="nama"
|
||||
value="{{ old('nama') }}"
|
||||
placeholder="Masukkan nama lengkap"
|
||||
required
|
||||
>
|
||||
@error('nama')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 2: NIP dan NIDN -->
|
||||
<div class="field-section">
|
||||
<div class="field">
|
||||
<label for="nip">NIP</label>
|
||||
<input
|
||||
id="nip"
|
||||
class="input @error('nip') error @enderror"
|
||||
type="text"
|
||||
name="nip"
|
||||
value="{{ old('nip') }}"
|
||||
placeholder="Contoh: 12345678 900000 1 001"
|
||||
>
|
||||
@error('nip')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Nomor Induk Pegawai (opsional)</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="nidn">Identitas Lain / BioID</label>
|
||||
<input
|
||||
id="nidn"
|
||||
class="input @error('nidn') error @enderror"
|
||||
type="text"
|
||||
name="nidn"
|
||||
value="{{ old('nidn') }}"
|
||||
placeholder="Contoh: BiometricID atau nomor lain"
|
||||
>
|
||||
@error('nidn')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Identitas tambahan (opsional)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 3: Bagian -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="bagian">Bagian <span class="required">*</span></label>
|
||||
<select
|
||||
id="bagian"
|
||||
class="select @error('bagian') error @enderror"
|
||||
name="bagian"
|
||||
required
|
||||
>
|
||||
<option value="">-- Pilih Bagian --</option>
|
||||
<option value="Staff Administrasi" @selected(old('bagian') === 'Staff Administrasi')>Staff Administrasi</option>
|
||||
<option value="Arsitektur dan Jaringan Komputer" @selected(old('bagian') === 'Arsitektur dan Jaringan Komputer')>Arsitektur dan Jaringan Komputer</option>
|
||||
<option value="Komputasi dan Sistem Informasi" @selected(old('bagian') === 'Komputasi dan Sistem Informasi')>Komputasi dan Sistem Informasi</option>
|
||||
<option value="Rekayasa Sistem Informasi" @selected(old('bagian') === 'Rekayasa Sistem Informasi')>Rekayasa Sistem Informasi</option>
|
||||
<option value="Sistem Komputer dan Kontrol" @selected(old('bagian') === 'Sistem Komputer dan Kontrol')>Sistem Komputer dan Kontrol</option>
|
||||
<option value="Rekayasa Perangkat Lunak" @selected(old('bagian') === 'Rekayasa Perangkat Lunak')>Rekayasa Perangkat Lunak</option>
|
||||
<option value="Multimedia Cerdas" @selected(old('bagian') === 'Multimedia Cerdas')>Multimedia Cerdas</option>
|
||||
<option value="Staff Lainnya" @selected(old('bagian') === 'Staff Lainnya')>Staff Lainnya</option>
|
||||
</select>
|
||||
@error('bagian')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Pilih bagian/divisi staff</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Role Selection -->
|
||||
<div class="field-section full">
|
||||
<label style="font-weight: 800; color: #475569; font-size: 0.92rem; margin-bottom: 8px;">Pilih Role <span class="required">*</span></label>
|
||||
<div class="role-selector">
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleStaff" name="role" value="staff" @checked(old('role') === 'staff' || !old('role')) required>
|
||||
<label for="roleStaff">👤 Staff</label>
|
||||
</div>
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleTeknik" name="role" value="teknisi" @checked(old('role') === 'teknisi') required>
|
||||
<label for="roleTeknik">🔧 Teknisi</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<button class="btn primary" type="submit">✅ Simpan Staff/Teknisi</button>
|
||||
<a class="btn ghost" href="{{ route('users.staff') }}">❌ Batal</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Photo preview dari URL
|
||||
const fotoInput = document.getElementById('fotoInput');
|
||||
const photoPreview = document.getElementById('photoPreview');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const roleStaffInput = document.getElementById('roleStaff');
|
||||
const roleTeknikInput = document.getElementById('roleTeknik');
|
||||
const submitBtn = document.querySelector('button[type="submit"]');
|
||||
const form = document.querySelector('form');
|
||||
let isSubmitting = false;
|
||||
|
||||
function updatePhotoIcon() {
|
||||
if (roleTeknikInput.checked) {
|
||||
return '🔧';
|
||||
}
|
||||
return '👤';
|
||||
}
|
||||
|
||||
// Prevent double submission
|
||||
form.addEventListener('submit', (e) => {
|
||||
if (isSubmitting) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
isSubmitting = true;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = '⏳ Menyimpan...';
|
||||
});
|
||||
|
||||
fotoInput.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
updateInitials();
|
||||
}
|
||||
});
|
||||
|
||||
function updateInitials() {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama) {
|
||||
const initials = nama.split(/\s+/)
|
||||
.slice(0, 2)
|
||||
.map(w => w.charAt(0).toUpperCase())
|
||||
.join('');
|
||||
photoInitial.textContent = initials || updatePhotoIcon();
|
||||
} else {
|
||||
photoInitial.textContent = updatePhotoIcon();
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger dari input nama
|
||||
namaInput.addEventListener('input', updateInitials);
|
||||
|
||||
// Trigger dari role selection
|
||||
roleStaffInput.addEventListener('change', updateInitials);
|
||||
roleTeknikInput.addEventListener('change', updateInitials);
|
||||
|
||||
// Inisialisasi saat halaman load
|
||||
window.addEventListener('load', () => {
|
||||
isSubmitting = false;
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = '✅ Simpan Staff/Teknisi';
|
||||
if (fotoInput.value.trim()) {
|
||||
fotoInput.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (namaInput.value.trim()) {
|
||||
namaInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,590 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Edit Staff/Teknisi - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #e0fdf4;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #059669;
|
||||
--primary-2: #14b8a6;
|
||||
--purple: #4f46e5;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(5, 150, 105, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(20, 184, 166, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #d1fae5 0%, #e0fdf4 45%, #f0fdfa 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 900;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header-desc {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
padding: 36px;
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 36px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.photo-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.photo-frame {
|
||||
width: 100%;
|
||||
aspect-ratio: 3/4;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 4rem;
|
||||
font-weight: 900;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
box-shadow: 0 16px 36px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.photo-frame:hover {
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 20px 48px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.photo-frame img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.photo-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.photo-label {
|
||||
border: 2px dashed rgba(5, 150, 105, 0.3);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
}
|
||||
|
||||
.photo-label:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
}
|
||||
|
||||
.photo-label-text {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.photo-label-hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section.full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-weight: 800;
|
||||
color: #475569;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.field label .required {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.input, .select {
|
||||
padding: 13px 14px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.25);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.input:focus, .select:focus {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.1);
|
||||
}
|
||||
|
||||
.input::placeholder {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
margin: 18px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 16px;
|
||||
background: rgba(217, 119, 6, 0.08);
|
||||
border: 1px solid rgba(217, 119, 6, 0.18);
|
||||
color: #7c2d12;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.error-message ul {
|
||||
margin-top: 8px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.field-error {
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
color: #991b1b;
|
||||
font-weight: 700;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.input.error, .select.error {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.02);
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 14px;
|
||||
padding: 16px;
|
||||
background: rgba(5, 150, 105, 0.05);
|
||||
border-radius: 14px;
|
||||
border: 1.5px solid rgba(5, 150, 105, 0.2);
|
||||
}
|
||||
|
||||
.role-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"] {
|
||||
cursor: pointer;
|
||||
accent-color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.04);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"]:checked ~ label {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option label {
|
||||
cursor: pointer;
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
gap: 8px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.btn.primary:hover {
|
||||
box-shadow: 0 16px 32px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.form-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="page-shell">
|
||||
<header class="header">
|
||||
<h1 class="header-title">✏️ Edit Staff/Teknisi</h1>
|
||||
<p class="header-desc">Perbarui informasi staff/teknisi (ID: {{ $user->id }})</p>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
@if ($errors->any())
|
||||
<div class="error-message">
|
||||
<strong>❌ Terjadi kesalahan validasi:</strong>
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('staff.update', $user) }}" class="form-container">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<!-- Foto Section -->
|
||||
<div class="photo-section">
|
||||
<div class="photo-frame" id="photoPreview">
|
||||
<span id="photoInitial">{{ $makeInitial($user->nama) }}</span>
|
||||
<img id="photoImg" style="display:none;" />
|
||||
</div>
|
||||
<label class="photo-label" for="fotoInput">
|
||||
<div class="photo-label-text">📤 Upload Foto</div>
|
||||
<div class="photo-label-hint">Klik untuk memilih gambar</div>
|
||||
</label>
|
||||
<input
|
||||
id="fotoInput"
|
||||
class="input"
|
||||
type="text"
|
||||
name="foto"
|
||||
value="{{ old('foto', $user->foto) }}"
|
||||
placeholder="atau masukkan URL foto"
|
||||
>
|
||||
<div class="hint">Format: URL gambar (https://...)</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Fields -->
|
||||
<div class="form-fields">
|
||||
<!-- Row 1: Nama -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input
|
||||
id="nama"
|
||||
class="input @error('nama') error @enderror"
|
||||
type="text"
|
||||
name="nama"
|
||||
value="{{ old('nama', $user->nama) }}"
|
||||
placeholder="Masukkan nama lengkap"
|
||||
required
|
||||
>
|
||||
@error('nama')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 2: NIP dan NIDN -->
|
||||
<div class="field-section">
|
||||
<div class="field">
|
||||
<label for="nip">NIP</label>
|
||||
<input
|
||||
id="nip"
|
||||
class="input @error('nip') error @enderror"
|
||||
type="text"
|
||||
name="nip"
|
||||
value="{{ old('nip', $user->nip) }}"
|
||||
placeholder="Contoh: 12345678 900000 1 001"
|
||||
>
|
||||
@error('nip')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Nomor Induk Pegawai (opsional)</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="nidn">Identitas Lain / BioID</label>
|
||||
<input
|
||||
id="nidn"
|
||||
class="input @error('nidn') error @enderror"
|
||||
type="text"
|
||||
name="nidn"
|
||||
value="{{ old('nidn', $user->nidn) }}"
|
||||
placeholder="Contoh: BiometricID atau nomor lain"
|
||||
>
|
||||
@error('nidn')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Identitas tambahan (opsional)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 3: Bagian -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="bagian">Bagian <span class="required">*</span></label>
|
||||
<select
|
||||
id="bagian"
|
||||
class="select @error('bagian') error @enderror"
|
||||
name="bagian"
|
||||
required
|
||||
>
|
||||
<option value="">-- Pilih Bagian --</option>
|
||||
<option value="Staff Administrasi" @selected(old('bagian', $user->bagian) === 'Staff Administrasi')>Staff Administrasi</option>
|
||||
<option value="Arsitektur dan Jaringan Komputer" @selected(old('bagian', $user->bagian) === 'Arsitektur dan Jaringan Komputer')>Arsitektur dan Jaringan Komputer</option>
|
||||
<option value="Komputasi dan Sistem Informasi" @selected(old('bagian', $user->bagian) === 'Komputasi dan Sistem Informasi')>Komputasi dan Sistem Informasi</option>
|
||||
<option value="Rekayasa Sistem Informasi" @selected(old('bagian', $user->bagian) === 'Rekayasa Sistem Informasi')>Rekayasa Sistem Informasi</option>
|
||||
<option value="Sistem Komputer dan Kontrol" @selected(old('bagian', $user->bagian) === 'Sistem Komputer dan Kontrol')>Sistem Komputer dan Kontrol</option>
|
||||
<option value="Rekayasa Perangkat Lunak" @selected(old('bagian', $user->bagian) === 'Rekayasa Perangkat Lunak')>Rekayasa Perangkat Lunak</option>
|
||||
<option value="Multimedia Cerdas" @selected(old('bagian', $user->bagian) === 'Multimedia Cerdas')>Multimedia Cerdas</option>
|
||||
<option value="Staff Lainnya" @selected(old('bagian', $user->bagian) === 'Staff Lainnya')>Staff Lainnya</option>
|
||||
</select>
|
||||
@error('bagian')
|
||||
<div class="field-error">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="hint">Pilih bagian/divisi staff</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Role Selection -->
|
||||
<div class="field-section full">
|
||||
<label style="font-weight: 800; color: #475569; font-size: 0.92rem; margin-bottom: 8px;">Pilih Role <span class="required">*</span></label>
|
||||
<div class="role-selector">
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleStaff" name="role" value="staff" @checked(old('role', $user->role) === 'staff') required>
|
||||
<label for="roleStaff">👤 Staff</label>
|
||||
</div>
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleTeknik" name="role" value="teknisi" @checked(old('role', $user->role) === 'teknisi') required>
|
||||
<label for="roleTeknik">🔧 Teknisi</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<button class="btn primary" type="submit">💾 Simpan Perubahan</button>
|
||||
<a class="btn ghost" href="{{ route('users.staff') }}">❌ Batal</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Photo preview dari URL
|
||||
const fotoInput = document.getElementById('fotoInput');
|
||||
const photoPreview = document.getElementById('photoPreview');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const roleStaffInput = document.getElementById('roleStaff');
|
||||
const roleTeknikInput = document.getElementById('roleTeknik');
|
||||
const submitBtn = document.querySelector('button[type="submit"]');
|
||||
const form = document.querySelector('form');
|
||||
let isSubmitting = false;
|
||||
|
||||
function updatePhotoIcon() {
|
||||
if (roleTeknikInput.checked) {
|
||||
return '🔧';
|
||||
}
|
||||
return '👤';
|
||||
}
|
||||
|
||||
// Prevent double submission
|
||||
form.addEventListener('submit', (e) => {
|
||||
if (isSubmitting) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
isSubmitting = true;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = '⏳ Menyimpan...';
|
||||
});
|
||||
|
||||
fotoInput.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
updateInitials();
|
||||
}
|
||||
});
|
||||
|
||||
function updateInitials() {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama) {
|
||||
const initials = nama.split(/\s+/)
|
||||
.slice(0, 2)
|
||||
.map(w => w.charAt(0).toUpperCase())
|
||||
.join('');
|
||||
photoInitial.textContent = initials || updatePhotoIcon();
|
||||
} else {
|
||||
photoInitial.textContent = updatePhotoIcon();
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger dari input nama
|
||||
namaInput.addEventListener('input', updateInitials);
|
||||
|
||||
// Trigger dari role selection
|
||||
roleStaffInput.addEventListener('change', updateInitials);
|
||||
roleTeknikInput.addEventListener('change', updateInitials);
|
||||
|
||||
// Inisialisasi saat halaman load
|
||||
window.addEventListener('load', () => {
|
||||
isSubmitting = false;
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = '💾 Simpan Perubahan';
|
||||
if (fotoInput.value.trim()) {
|
||||
fotoInput.dispatchEvent(new Event('change'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,635 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CRUD Staff/Teknisi - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 12px 14px;
|
||||
font-size: 0.9rem;
|
||||
color: #475569;
|
||||
background: #f8fafc;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.12);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 18px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.92rem; }
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 7px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
}
|
||||
|
||||
.pill.dosen { background: linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); }
|
||||
.pill.teknisi { background: linear-gradient(135deg, var(--green), #14b8a6); }
|
||||
.pill.staff { background: linear-gradient(135deg, var(--orange), var(--orange)); }
|
||||
|
||||
.row-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 9px 12px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-sm:hover { transform: translateY(-2px); }
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 8px 16px rgba(16, 185, 129, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 8px 16px rgba(59, 130, 246, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 8px 16px rgba(239, 68, 68, 0.18);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.pager { display: inline-flex; gap: 8px; }
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="{{ route('users.index') }}"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="{{ route('users.dosen') }}"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="{{ route('users.staff') }}" class="active"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="{{ url('/dashboard') }}">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>CRUD Staff/Teknisi</h1>
|
||||
<p>Kelola data staff dan teknisi JTI</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn-sm success" href="{{ route('staff.create') }}">Tambah Staff/Teknisi</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Staff/Teknisi</h2>
|
||||
<p>Kelola data staff dan teknisi dengan fitur pencarian dan filter.</p>
|
||||
</div>
|
||||
<div class="meta">Total: {{ $staffCount }}</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="{{ route('users.staff') }}">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for="q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="{{ $q }}" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="role">Role</label>
|
||||
<select id="role" class="select" name="role">
|
||||
<option value="">Semua</option>
|
||||
<option value="staff" @selected($role === 'staff')>Staff</option>
|
||||
<option value="teknisi" @selected($role === 'teknisi')>Teknisi</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
@foreach (['10','25','50','100','all'] as $size)
|
||||
<option value="{{ $size }}" @selected($perPage === $size)>
|
||||
{{ $size === 'all' ? 'Semua' : $size }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="{{ route('users.staff') }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="notice">{{ session('success') }}</div>
|
||||
@endif
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 70px;">Foto</th>
|
||||
<th>Nama</th>
|
||||
<th style="width: 180px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 120px;">Role</th>
|
||||
<th style="width: 190px;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($staff as $item)
|
||||
<tr>
|
||||
<td>
|
||||
@php($fotoUrl = $resolveFoto($item->foto))
|
||||
<div class="avatar" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900;">{{ $item->nama }}</div>
|
||||
<div class="meta">ID: {{ $item->id }}</div>
|
||||
</td>
|
||||
<td>{{ $item->nip ?? '-' }}</td>
|
||||
<td>{{ $item->nidn ?? '-' }}</td>
|
||||
<td>
|
||||
@php($r = (string) ($item->role ?? 'staff'))
|
||||
@php($r = in_array($r, ['dosen', 'teknisi', 'staff'], true) ? $r : 'staff')
|
||||
<span class="pill {{ $r }}">{{ ucfirst($r) }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<a class="btn-sm primary" href="{{ route('staff.edit', $item) }}">Edit</a>
|
||||
|
||||
<form method="POST" action="{{ route('staff.destroy', $item) }}" onsubmit="return confirm('Hapus staff/teknisi ini?')" style="display:inline;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn-sm danger" type="submit">Hapus</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="meta">Belum ada data staff/teknisi.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan {{ $staff->firstItem() ?? 0 }}–{{ $staff->lastItem() ?? 0 }} dari {{ $staffCount }}
|
||||
</div>
|
||||
<div class="pager">
|
||||
@if ($staff->onFirstPage())
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
@else
|
||||
<a class="btn-sm ghost" href="{{ $staff->previousPageUrl() }}">Sebelumnya</a>
|
||||
@endif
|
||||
|
||||
@if ($staff->hasMorePages())
|
||||
<a class="btn-sm ghost" href="{{ $staff->nextPageUrl() }}">Berikutnya</a>
|
||||
@else
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,620 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CRUD Dosen - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 12px 14px;
|
||||
font-size: 0.9rem;
|
||||
color: #475569;
|
||||
background: #f8fafc;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.12);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 18px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.92rem; }
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 7px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
}
|
||||
|
||||
.pill.dosen { background: linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); }
|
||||
.pill.teknisi { background: linear-gradient(135deg, var(--green), #14b8a6); }
|
||||
.pill.staff { background: linear-gradient(135deg, var(--orange), var(--orange)); }
|
||||
|
||||
.row-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 9px 12px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-sm:hover { transform: translateY(-2px); }
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 8px 16px rgba(16, 185, 129, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 8px 16px rgba(59, 130, 246, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 8px 16px rgba(239, 68, 68, 0.18);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.pager { display: inline-flex; gap: 8px; }
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="{{ route('users.index') }}"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="{{ route('users.dosen') }}" class="active"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="{{ route('users.staff') }}"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="{{ url('/dashboard') }}">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>CRUD Dosen</h1>
|
||||
<p>Kelola data dosen JTI</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn-sm success" href="{{ route('users.create') }}">Tambah Dosen</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Dosen</h2>
|
||||
<p>Kelola data dosen dengan fitur pencarian dan filter.</p>
|
||||
</div>
|
||||
<div class="meta">Total: {{ $dosenCount }}</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="{{ route('users.dosen') }}">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for="q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="{{ $q }}" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
@foreach (['10','25','50','100','all'] as $size)
|
||||
<option value="{{ $size }}" @selected($perPage === $size)>
|
||||
{{ $size === 'all' ? 'Semua' : $size }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="{{ route('users.dosen') }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="notice">{{ session('success') }}</div>
|
||||
@endif
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 70px;">Foto</th>
|
||||
<th>Nama</th>
|
||||
<th style="width: 180px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 190px;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($dosen as $item)
|
||||
<tr>
|
||||
<td>
|
||||
@php($fotoUrl = $resolveFoto($item->foto))
|
||||
<div class="avatar" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900;">{{ $item->nama }}</div>
|
||||
<div class="meta">ID: {{ $item->id }}</div>
|
||||
</td>
|
||||
<td>{{ $item->nip ?? '-' }}</td>
|
||||
<td>{{ $item->nidn ?? '-' }}</td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<a class="btn-sm primary" href="{{ route('users.edit', $item) }}">Edit</a>
|
||||
|
||||
<form method="POST" action="{{ route('users.destroy', $item) }}" onsubmit="return confirm('Hapus dosen ini?')" style="display:inline;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn-sm danger" type="submit">Hapus</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="5" class="meta">Belum ada data dosen.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan {{ $dosen->firstItem() ?? 0 }}–{{ $dosen->lastItem() ?? 0 }} dari {{ $dosenCount }}
|
||||
</div>
|
||||
<div class="pager">
|
||||
@if ($dosen->onFirstPage())
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
@else
|
||||
<a class="btn-sm ghost" href="{{ $dosen->previousPageUrl() }}">Sebelumnya</a>
|
||||
@endif
|
||||
|
||||
@if ($dosen->hasMorePages())
|
||||
<a class="btn-sm ghost" href="{{ $dosen->nextPageUrl() }}">Berikutnya</a>
|
||||
@else
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,861 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kelola Users - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 16px 18px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 16px 18px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 900;
|
||||
color: #475569;
|
||||
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
||||
border-bottom: 2px solid rgba(148, 163, 184, 0.2);
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
transition: all 0.3s ease;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
background: rgba(79, 70, 229, 0.04);
|
||||
box-shadow: inset 0 0 12px rgba(79, 70, 229, 0.08);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background: rgba(248, 250, 252, 0.5);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even):hover {
|
||||
background: rgba(79, 70, 229, 0.06);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 14px 18px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 14px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 24px rgba(79, 70, 229, 0.28);
|
||||
border: 2.5px solid rgba(255, 255, 255, 0.35);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 1.25rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
tbody tr:hover .avatar {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 14px 32px rgba(79, 70, 229, 0.35);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.85rem; margin-top: 6px; letter-spacing: 0.3px; }
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 8px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.22);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.pill:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.pill.dosen {
|
||||
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
|
||||
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.22);
|
||||
}
|
||||
|
||||
.pill.dosen:hover {
|
||||
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.28);
|
||||
}
|
||||
|
||||
.pill.teknisi {
|
||||
background: linear-gradient(135deg, #10b981 0%, #14b8a6 100%);
|
||||
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.22);
|
||||
}
|
||||
|
||||
.pill.teknisi:hover {
|
||||
box-shadow: 0 6px 16px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.pill.staff {
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #f97316 100%);
|
||||
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.22);
|
||||
}
|
||||
|
||||
.pill.staff:hover {
|
||||
box-shadow: 0 6px 16px rgba(245, 158, 11, 0.28);
|
||||
}
|
||||
|
||||
.row-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
padding: 10px 14px;
|
||||
font-weight: 900;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 0.3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.btn-sm:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.btn-sm:active {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.3);
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.btn-sm.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
border-color: rgba(99, 102, 241, 0.5);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 6px 16px rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.success:hover {
|
||||
box-shadow: 0 8px 24px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.warning {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
|
||||
box-shadow: 0 6px 16px rgba(245, 158, 11, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.warning:hover {
|
||||
box-shadow: 0 8px 24px rgba(245, 158, 11, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 6px 16px rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.primary:hover {
|
||||
box-shadow: 0 8px 24px rgba(59, 130, 246, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 6px 16px rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.danger:hover {
|
||||
box-shadow: 0 8px 24px rgba(239, 68, 68, 0.28);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.12);
|
||||
}
|
||||
|
||||
.pager {
|
||||
display: inline-flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
|
||||
.welcome-section {
|
||||
padding: 32px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.08) 0%, rgba(124, 58, 237, 0.06) 100%);
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.15);
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 24px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.welcome-text h3 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 900;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.welcome-text p {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 14px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.welcome-stats {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(148, 163, 184, 0.12);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.15), rgba(124, 58, 237, 0.1));
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 900;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.75rem;
|
||||
color: var(--muted);
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 5rem;
|
||||
opacity: 0.15;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="{{ route('users.index') }}" class="active"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="{{ route('users.dosen') }}"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="{{ route('users.staff') }}"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="{{ url('/dashboard') }}">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>Kelola Users</h1>
|
||||
<p>Lihat semua data dosen, staff dan teknisi</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions"></div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Users</h2>
|
||||
<p>Gunakan filter untuk mencari dan batasi jumlah data.</p>
|
||||
</div>
|
||||
<div class="meta">Total: {{ $totalCount ?? 0 }}</div>
|
||||
</div>
|
||||
|
||||
<div class="welcome-section">
|
||||
<div class="welcome-content">
|
||||
<div class="welcome-text">
|
||||
<h3>🎉 Selamat Datang di Admin Panel</h3>
|
||||
<p>Kelola semua data dosen, staff, dan teknisi dengan mudah. Cari, filter, dan kelola informasi pengguna dalam satu tempat yang terintegrasi.</p>
|
||||
</div>
|
||||
<div class="welcome-icon">👥</div>
|
||||
</div>
|
||||
<div class="welcome-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">👨🏫</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number">{{ $totalCount }}</span>
|
||||
<span class="stat-label">Total Users</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">📊</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number">3</span>
|
||||
<span class="stat-label">Kategori</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">⚙️</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number">∞</span>
|
||||
<span class="stat-label">Fitur</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="{{ route('users.index') }}">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for=" q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="{{ $q }}" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="role">Role</label>
|
||||
<select id="role" class="select" name="role">
|
||||
<option value="">Semua</option>
|
||||
@foreach ($roleOptions as $opt)
|
||||
<option value="{{ $opt }}" @selected($role === $opt)>{{ ucfirst($opt) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
@foreach (['10','25','50','100','all'] as $size)
|
||||
<option value="{{ $size }}" @selected($perPage === $size)>
|
||||
{{ $size === 'all' ? 'Semua' : $size }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="{{ route('users.index') }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="notice">{{ session('success') }}</div>
|
||||
@endif
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 80px;">Foto</th>
|
||||
<th style="flex: 1; min-width: 280px;">Nama</th>
|
||||
<th style="width: 160px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 110px;">Role</th>
|
||||
<th style="width: 160px;">Waktu Input</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($users as $item)
|
||||
<tr>
|
||||
<td>
|
||||
@php($fotoUrl = $resolveFoto($item->foto))
|
||||
<div class="avatar" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900; font-size: 1.05rem; color: #1f2937; line-height: 1.4;">{{ $item->nama }}</div>
|
||||
<div class="meta" style="font-size: 0.8rem;">ID: {{ $item->id }}</div>
|
||||
</td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #475569;">{{ $item->nip ?? '-' }}</td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #475569;">{{ $item->nidn ?? '-' }}</td>
|
||||
<td>
|
||||
@php($r = (string) ($item->role ?? 'staff'))
|
||||
@php($r = in_array($r, ['dosen', 'teknisi', 'staff'], true) ? $r : 'staff')
|
||||
<span class="pill {{ $r }}">{{ ucfirst($r) }}</span>
|
||||
</td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #6b7280; font-size: 0.95rem;">
|
||||
{{ $item->created_at ? $item->created_at->format('d M Y H:i') : '-' }}
|
||||
<div class="meta" style="font-size: 0.75rem; margin-top: 4px;">{{ $item->created_at ? $item->created_at->diffForHumans() : '-' }}</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" style="text-align: center; padding: 48px 18px;">
|
||||
<div style="color: var(--muted); font-size: 1.1rem; font-weight: 700;">📭 Belum ada data</div>
|
||||
<div style="color: #9ca3af; font-size: 0.9rem; margin-top: 8px;">Coba ubah filter atau tambahkan data baru untuk memulai</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan {{ $users->firstItem() ?? 0 }}–{{ $users->lastItem() ?? 0 }} dari {{ $totalCount ?? 0 }}
|
||||
</div>
|
||||
<div class="pager">
|
||||
@if ($users->currentPage() == 1)
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
@else
|
||||
<a class="btn-sm ghost" href="{{ $users->previousPageUrl() }}">Sebelumnya</a>
|
||||
@endif
|
||||
|
||||
@if ($users->lastPage() > $users->currentPage())
|
||||
<a class="btn-sm ghost" href="{{ $users->nextPageUrl() }}">Berikutnya</a>
|
||||
@else
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,635 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CRUD Staff/Teknisi - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 12px 14px;
|
||||
font-size: 0.9rem;
|
||||
color: #475569;
|
||||
background: #f8fafc;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.12);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 18px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.92rem; }
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 7px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
}
|
||||
|
||||
.pill.dosen { background: linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); }
|
||||
.pill.teknisi { background: linear-gradient(135deg, var(--green), #14b8a6); }
|
||||
.pill.staff { background: linear-gradient(135deg, var(--orange), var(--orange)); }
|
||||
|
||||
.row-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 9px 12px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-sm:hover { transform: translateY(-2px); }
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 8px 16px rgba(16, 185, 129, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 8px 16px rgba(59, 130, 246, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 8px 16px rgba(239, 68, 68, 0.18);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.pager { display: inline-flex; gap: 8px; }
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="{{ route('users.index') }}"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="{{ route('users.dosen') }}"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="{{ route('users.staff') }}" class="active"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="{{ url('/dashboard') }}">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>CRUD Staff/Teknisi</h1>
|
||||
<p>Kelola data staff dan teknisi JTI</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn-sm success" href="{{ route('users.create') }}">Tambah Staff/Teknisi</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Staff/Teknisi</h2>
|
||||
<p>Kelola data staff dan teknisi dengan fitur pencarian dan filter.</p>
|
||||
</div>
|
||||
<div class="meta">Total: {{ $staffCount }}</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="{{ route('users.staff') }}">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for="q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="{{ $q }}" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="role">Role</label>
|
||||
<select id="role" class="select" name="role">
|
||||
<option value="">Semua</option>
|
||||
<option value="staff" @selected($role === 'staff')>Staff</option>
|
||||
<option value="teknisi" @selected($role === 'teknisi')>Teknisi</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
@foreach (['10','25','50','100','all'] as $size)
|
||||
<option value="{{ $size }}" @selected($perPage === $size)>
|
||||
{{ $size === 'all' ? 'Semua' : $size }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="{{ route('users.staff') }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@if (session('success'))
|
||||
<div class="notice">{{ session('success') }}</div>
|
||||
@endif
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 70px;">Foto</th>
|
||||
<th>Nama</th>
|
||||
<th style="width: 180px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 120px;">Role</th>
|
||||
<th style="width: 190px;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($staff as $item)
|
||||
<tr>
|
||||
<td>
|
||||
@php($fotoUrl = $resolveFoto($item->foto))
|
||||
<div class="avatar" @if($fotoUrl) style="background-image: url('{{ $fotoUrl }}')" @endif>
|
||||
@if(!$fotoUrl)
|
||||
<div class="avatar-placeholder">{{ $makeInitial($item->nama) }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900;">{{ $item->nama }}</div>
|
||||
<div class="meta">ID: {{ $item->id }}</div>
|
||||
</td>
|
||||
<td>{{ $item->nip ?? '-' }}</td>
|
||||
<td>{{ $item->nidn ?? '-' }}</td>
|
||||
<td>
|
||||
@php($r = (string) ($item->role ?? 'staff'))
|
||||
@php($r = in_array($r, ['dosen', 'teknisi', 'staff'], true) ? $r : 'staff')
|
||||
<span class="pill {{ $r }}">{{ ucfirst($r) }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<a class="btn-sm primary" href="{{ route('users.edit', $item) }}">Edit</a>
|
||||
|
||||
<form method="POST" action="{{ route('users.destroy', $item) }}" onsubmit="return confirm('Hapus staff/teknisi ini?')" style="display:inline;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button class="btn-sm danger" type="submit">Hapus</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="meta">Belum ada data staff/teknisi.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan {{ $staff->firstItem() ?? 0 }}–{{ $staff->lastItem() ?? 0 }} dari {{ $staffCount }}
|
||||
</div>
|
||||
<div class="pager">
|
||||
@if ($staff->onFirstPage())
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
@else
|
||||
<a class="btn-sm ghost" href="{{ $staff->previousPageUrl() }}">Sebelumnya</a>
|
||||
@endif
|
||||
|
||||
@if ($staff->hasMorePages())
|
||||
<a class="btn-sm ghost" href="{{ $staff->nextPageUrl() }}">Berikutnya</a>
|
||||
@else
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,7 +1,47 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\DashboardController;
|
||||
use App\Http\Controllers\UserController;
|
||||
use App\Http\Controllers\WelcomeController;
|
||||
use App\Models\UserDosen;
|
||||
use App\Models\UserStaff;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/', [DashboardController::class, 'index']);
|
||||
Route::get('/dashboard', [DashboardController::class, 'index']);
|
||||
// Model Binding
|
||||
Route::model('user', UserDosen::class);
|
||||
Route::model('staff', UserStaff::class);
|
||||
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('home');
|
||||
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
|
||||
|
||||
// Welcome/Management Portal
|
||||
Route::get('/welcome', [WelcomeController::class, 'index'])->name('welcome');
|
||||
|
||||
// API Routes untuk Attendance
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::get('/api/attendance/data', [WelcomeController::class, 'getAttendanceData'])->name('attendance.get');
|
||||
Route::post('/api/attendance/record', [WelcomeController::class, 'recordAttendance'])->name('attendance.record');
|
||||
Route::post('/api/status/update', [WelcomeController::class, 'updateStatus'])->name('status.update');
|
||||
});
|
||||
|
||||
// User listing pages
|
||||
Route::get('/users', [UserController::class, 'index'])->name('users.index');
|
||||
Route::get('/users/dosen/index', [UserController::class, 'dosen'])->name('users.dosen');
|
||||
Route::get('/users/staff/index', [UserController::class, 'staff'])->name('users.staff');
|
||||
|
||||
// Dosen CRUD
|
||||
Route::get('/dosen/create', [UserController::class, 'create'])->name('dosen.create');
|
||||
Route::post('/dosen/store', [UserController::class, 'store'])->name('dosen.store');
|
||||
Route::get('/dosen/{user}/edit', [UserController::class, 'edit'])->name('dosen.edit');
|
||||
Route::put('/dosen/{user}', [UserController::class, 'update'])->name('dosen.update');
|
||||
Route::delete('/dosen/{user}', [UserController::class, 'destroy'])->name('dosen.destroy');
|
||||
|
||||
// Staff CRUD
|
||||
Route::get('/staff/create', [UserController::class, 'create'])->name('staff.create');
|
||||
Route::post('/staff/store', [UserController::class, 'store'])->name('staff.store');
|
||||
Route::get('/staff/{staff}/edit', [UserController::class, 'edit'])->name('staff.edit');
|
||||
Route::put('/staff/{staff}', [UserController::class, 'update'])->name('staff.update');
|
||||
Route::delete('/staff/{staff}', [UserController::class, 'destroy'])->name('staff.destroy');
|
||||
|
||||
// Generic user resource routes
|
||||
Route::resource('users', UserController::class)->except(['show', 'index']);
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
*
|
||||
!.gitignore
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="12" viewBox="0 0 8 12" fill="none" <?php echo e($attributes); ?>>
|
||||
<g clip-path="url(#clip0_14550_6168)">
|
||||
<path d="M6.75 11.0001L4 8.25012L1.25 11.0001" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.75 1.50012L4 4.25012L1.25 1.50012" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_14550_6168">
|
||||
<rect width="8" height="11" fill="white" style="fill:white;fill-opacity:1;" transform="translate(0 0.500122)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/chevrons-down-up.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 810 B |
|
|
@ -0,0 +1,8 @@
|
|||
<section
|
||||
<?php echo e($attributes->merge(['class' => "w-full max-w-7xl mx-auto p-4 sm:p-14 border-x border-dashed border-neutral-300 dark:border-white/[9%]"])); ?>
|
||||
|
||||
>
|
||||
<?php echo e($slot); ?>
|
||||
|
||||
</section>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/section-container.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php $__env->startSection('title', __('Not Found')); ?>
|
||||
<?php $__env->startSection('code', '404'); ?>
|
||||
<?php $__env->startSection('message', __('Not Found')); ?>
|
||||
|
||||
<?php echo $__env->make('errors::minimal', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions/views/404.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php if($paginator->hasPages()): ?>
|
||||
<nav role="navigation" aria-label="<?php echo e(__('Pagination Navigation')); ?>" class="flex gap-2 items-center justify-between">
|
||||
|
||||
<?php if($paginator->onFirstPage()): ?>
|
||||
<span class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-600 bg-white border border-gray-300 cursor-not-allowed leading-5 rounded-md dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600">
|
||||
<?php echo __('pagination.previous'); ?>
|
||||
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<a href="<?php echo e($paginator->previousPageUrl()); ?>" rel="prev" class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-800 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-700 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-800 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-900 dark:hover:text-gray-200">
|
||||
<?php echo __('pagination.previous'); ?>
|
||||
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($paginator->hasMorePages()): ?>
|
||||
<a href="<?php echo e($paginator->nextPageUrl()); ?>" rel="next" class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-800 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-700 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-800 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-900 dark:hover:text-gray-200">
|
||||
<?php echo __('pagination.next'); ?>
|
||||
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-600 bg-white border border-gray-300 cursor-not-allowed leading-5 rounded-md dark:text-gray-300 dark:bg-gray-700 dark:border-gray-600">
|
||||
<?php echo __('pagination.next'); ?>
|
||||
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Pagination\resources\views\simple-tailwind.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title><?php echo $__env->yieldContent('title'); ?></title>
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #fff;
|
||||
color: #636b6f;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-weight: 100;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.position-ref {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex-center position-ref full-height">
|
||||
<div class="content">
|
||||
<div class="title">
|
||||
<?php echo $__env->yieldContent('message'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\views\layout.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# <?php echo e($exception->class()); ?> - <?php echo $exception->title(); ?>
|
||||
|
||||
|
||||
<?php echo $exception->message(); ?>
|
||||
|
||||
|
||||
PHP <?php echo e(PHP_VERSION); ?>
|
||||
|
||||
Laravel <?php echo e(app()->version()); ?>
|
||||
|
||||
<?php echo e($exception->request()->httpHost()); ?>
|
||||
|
||||
|
||||
## Stack Trace
|
||||
|
||||
<?php $__currentLoopData = $exception->frames(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $frame): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($index); ?> - <?php echo e($frame->file()); ?>:<?php echo e($frame->line()); ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
<?php if($exception->previousExceptions()->isNotEmpty()): ?>
|
||||
## Previous <?php echo e(\Illuminate\Support\Str::plural('exception', $exception->previousExceptions()->count())); ?>
|
||||
|
||||
<?php $__currentLoopData = $exception->previousExceptions(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $previous): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
### <?php echo e($index + 1); ?>. <?php echo e($previous->class()); ?>
|
||||
|
||||
|
||||
<?php echo $previous->message(); ?>
|
||||
|
||||
|
||||
<?php $__currentLoopData = $previous->frames(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $frame): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($index); ?> - <?php echo e($frame->file()); ?>:<?php echo e($frame->line()); ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
## Request
|
||||
|
||||
<?php echo e($exception->request()->method()); ?> <?php echo e(\Illuminate\Support\Str::start($exception->request()->path(), '/')); ?>
|
||||
|
||||
|
||||
## Headers
|
||||
|
||||
<?php $__empty_1 = true; $__currentLoopData = $exception->requestHeaders(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
* **<?php echo e($key); ?>**: <?php echo $value; ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
No header data available.
|
||||
<?php endif; ?>
|
||||
|
||||
## Route Context
|
||||
|
||||
<?php $__empty_1 = true; $__currentLoopData = $exception->applicationRouteContext(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $name => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<?php echo e($name); ?>: <?php echo $value; ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
No routing data available.
|
||||
<?php endif; ?>
|
||||
|
||||
## Route Parameters
|
||||
|
||||
<?php if($routeParametersContext = $exception->applicationRouteParametersContext()): ?>
|
||||
<?php echo $routeParametersContext; ?>
|
||||
|
||||
<?php else: ?>
|
||||
No route parameter data available.
|
||||
<?php endif; ?>
|
||||
|
||||
## Database Queries
|
||||
|
||||
<?php $__empty_1 = true; $__currentLoopData = $exception->applicationQueries(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as ['connectionName' => $connectionName, 'sql' => $sql, 'time' => $time]): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
* <?php echo e($connectionName); ?> - <?php echo $sql; ?> (<?php echo e($time); ?> ms)
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
No database queries detected.
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\markdown.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['code', 'highlightedLine']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['code', 'highlightedLine']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div
|
||||
class="text-sm rounded-b-lg bg-neutral-50 border-t border-neutral-100 dark:bg-neutral-900 dark:border-white/10"
|
||||
<?php echo e($attributes); ?>
|
||||
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal12cb286571f553eebcbe98210b217f94 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal12cb286571f553eebcbe98210b217f94 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.syntax-highlight','data' => ['code' => $code,'language' => 'php','editor' => true,'startingLine' => max(1, $highlightedLine - 5),'highlightedLine' => min(5, $highlightedLine - 1),'class' => 'overflow-x-auto']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::syntax-highlight'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['code' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($code),'language' => 'php','editor' => true,'starting-line' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute(max(1, $highlightedLine - 5)),'highlighted-line' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute(min(5, $highlightedLine - 1)),'class' => 'overflow-x-auto']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $attributes = $__attributesOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__attributesOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $component = $__componentOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__componentOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\frame-code.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Management Portal - Dosen & Staff/Teknisi</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f5f7f4;
|
||||
--panel: #ffffff;
|
||||
--ink: #17211f;
|
||||
--muted: #5f6d69;
|
||||
--line: #d8dfdc;
|
||||
--brand: #0f766e;
|
||||
--brand-soft: #e7f3f1;
|
||||
--accent: #f97316;
|
||||
--ok: #16a34a;
|
||||
--warn: #c2410c;
|
||||
--shadow: 0 18px 42px rgba(23, 33, 31, 0.08);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: "Trebuchet MS", "Segoe UI", sans-serif;
|
||||
color: var(--ink);
|
||||
background:
|
||||
radial-gradient(65rem 45rem at 120% -10%, #d7f0ec 0%, transparent 45%),
|
||||
radial-gradient(55rem 40rem at -20% 120%, #ffe8d4 0%, transparent 38%),
|
||||
var(--bg);
|
||||
}
|
||||
|
||||
.layout {
|
||||
min-height: 100vh;
|
||||
display: grid;
|
||||
grid-template-columns: 270px 1fr;
|
||||
gap: 18px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background: linear-gradient(180deg, #0f172a, #111827);
|
||||
color: #e5e7eb;
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
box-shadow: var(--shadow);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.brand {
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 18px;
|
||||
border-bottom: 1px solid rgba(229, 231, 235, 0.2);
|
||||
}
|
||||
|
||||
.brand h1 {
|
||||
font-size: 1.1rem;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.brand p {
|
||||
margin-top: 4px;
|
||||
color: #9ca3af;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
text-decoration: none;
|
||||
color: #d1d5db;
|
||||
border: 1px solid rgba(209, 213, 219, 0.15);
|
||||
border-radius: 12px;
|
||||
padding: 12px 14px;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.menu a:hover,
|
||||
.menu a.active {
|
||||
color: #ffffff;
|
||||
background: rgba(15, 118, 110, 0.35);
|
||||
border-color: rgba(94, 234, 212, 0.45);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
.sidebar-note {
|
||||
margin-top: auto;
|
||||
border-top: 1px solid rgba(229, 231, 235, 0.18);
|
||||
padding-top: 14px;
|
||||
font-size: 0.84rem;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
box-shadow: var(--shadow);
|
||||
padding: 16px 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.welcome h2 {
|
||||
font-size: clamp(1.15rem, 2.5vw, 1.8rem);
|
||||
}
|
||||
|
||||
.welcome p {
|
||||
margin-top: 4px;
|
||||
color: var(--muted);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
position: relative;
|
||||
min-width: 240px;
|
||||
}
|
||||
|
||||
.status-trigger {
|
||||
width: 100%;
|
||||
border: 1px solid var(--line);
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.status-current {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 999px;
|
||||
background: var(--ok);
|
||||
box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.18);
|
||||
}
|
||||
|
||||
.status-minus {
|
||||
display: inline-flex;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 999px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
background: var(--warn);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.status-menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 8px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
border: 1px solid var(--line);
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow);
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.status-menu.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.status-option {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: #fff;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #edf0ef;
|
||||
padding: 10px 12px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.status-option:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.status-option:hover {
|
||||
background: #f8faf9;
|
||||
}
|
||||
|
||||
.main-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
box-shadow: var(--shadow);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.card p {
|
||||
color: var(--muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.chart-wrap {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.chart-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.chip {
|
||||
background: var(--brand-soft);
|
||||
color: var(--brand);
|
||||
border: 1px solid #b5ddd8;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.chart {
|
||||
display: grid;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: grid;
|
||||
grid-template-columns: 70px 1fr 55px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.day {
|
||||
font-weight: 700;
|
||||
color: #33413e;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.bar-bg {
|
||||
height: 12px;
|
||||
background: #e9efed;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bar {
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, var(--brand), #14b8a6);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.hours {
|
||||
text-align: right;
|
||||
font-weight: 700;
|
||||
color: #33413e;
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
.settings-list {
|
||||
margin-top: 14px;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1px solid #e7ecea;
|
||||
border-radius: 12px;
|
||||
padding: 10px 12px;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.setting-item span {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 1px solid #d2dad7;
|
||||
border-radius: 9px;
|
||||
background: #fff;
|
||||
padding: 6px 9px;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
color: #33413e;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: #a9bbb6;
|
||||
background: #f6faf9;
|
||||
}
|
||||
|
||||
@media (max-width: 980px) {
|
||||
.layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.main-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 620px) {
|
||||
.topbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.row {
|
||||
grid-template-columns: 56px 1fr 45px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$namaString = $nama ?? 'Dosen/Staff';
|
||||
$durasiMingguan = $durasiMingguan ?? [
|
||||
'Senin' => 7.5,
|
||||
'Selasa' => 6.8,
|
||||
'Rabu' => 8.2,
|
||||
'Kamis' => 7.1,
|
||||
'Jumat' => 5.4,
|
||||
];
|
||||
$maksJam = max($durasiMingguan);
|
||||
?>
|
||||
|
||||
<div class="layout">
|
||||
<aside class="sidebar">
|
||||
<div class="brand">
|
||||
<h1>JTI MANAGEMENT</h1>
|
||||
<p>Portal Dosen & Staff/Teknisi</p>
|
||||
</div>
|
||||
|
||||
<nav class="menu" aria-label="Menu utama">
|
||||
<a href="#" class="active">
|
||||
<span>Home</span>
|
||||
<span>01</span>
|
||||
</a>
|
||||
<a href="#">
|
||||
<span>Setting</span>
|
||||
<span>02</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-note">
|
||||
Monitoring kehadiran kampus aktif Senin - Jumat dan reset otomatis tiap minggu.
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<section class="content">
|
||||
<header class="topbar">
|
||||
<div class="welcome">
|
||||
<h2>Selamat datang, <?php echo e($namaString); ?></h2>
|
||||
<p>Semoga aktivitas akademik dan operasional hari ini berjalan lancar.</p>
|
||||
</div>
|
||||
|
||||
<div class="status-wrap">
|
||||
<button id="statusTrigger" class="status-trigger" type="button" aria-expanded="false" aria-controls="statusMenu">
|
||||
<span id="statusCurrent" class="status-current">
|
||||
<span class="status-dot" aria-hidden="true"></span>
|
||||
Online
|
||||
</span>
|
||||
<span aria-hidden="true">v</span>
|
||||
</button>
|
||||
|
||||
<div id="statusMenu" class="status-menu" role="listbox" aria-label="Pilih status">
|
||||
<button type="button" class="status-option" data-type="online" role="option">
|
||||
<span class="status-dot" aria-hidden="true"></span>
|
||||
Online
|
||||
</button>
|
||||
<button type="button" class="status-option" data-type="dnd" role="option">
|
||||
<span class="status-minus" aria-hidden="true">-</span>
|
||||
Tidak Bisa Diganggu
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="main-grid">
|
||||
<article class="card">
|
||||
<h3>Grafik Durasi Kehadiran Dosen di Kampus</h3>
|
||||
<p>Rekap otomatis dari Senin sampai Jumat, reset pada awal minggu berikutnya.</p>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-head">
|
||||
<strong>Durasi mingguan (jam)</strong>
|
||||
<span class="chip">Reset Mingguan Otomatis</span>
|
||||
</div>
|
||||
|
||||
<div class="chart">
|
||||
<?php $__currentLoopData = $durasiMingguan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $hari => $jam): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php
|
||||
$persen = $maksJam > 0 ? ($jam / $maksJam) * 100 : 0;
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="day"><?php echo e($hari); ?></div>
|
||||
<div class="bar-bg" aria-hidden="true">
|
||||
<div class="bar" style="width: <?php echo e(number_format($persen, 2, '.', '')); ?>%"></div>
|
||||
</div>
|
||||
<div class="hours"><?php echo e(rtrim(rtrim(number_format($jam, 1, '.', ''), '0'), '.')); ?>j</div>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<aside class="card">
|
||||
<h3>Setting</h3>
|
||||
<p>Pengaturan singkat untuk akun dosen dan staff/teknisi.</p>
|
||||
|
||||
<div class="settings-list">
|
||||
<div class="setting-item">
|
||||
<span>Nama Tampilan</span>
|
||||
<button class="btn" type="button">Ubah</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<span>Notifikasi Kehadiran</span>
|
||||
<button class="btn" type="button">Aktif</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<span>Sinkron Mingguan</span>
|
||||
<button class="btn" type="button">Jadwalkan</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
const trigger = document.getElementById('statusTrigger');
|
||||
const menu = document.getElementById('statusMenu');
|
||||
const current = document.getElementById('statusCurrent');
|
||||
|
||||
if (!trigger || !menu || !current) return;
|
||||
|
||||
const closeMenu = function () {
|
||||
menu.classList.remove('open');
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
};
|
||||
|
||||
trigger.addEventListener('click', function () {
|
||||
const isOpen = menu.classList.contains('open');
|
||||
menu.classList.toggle('open', !isOpen);
|
||||
trigger.setAttribute('aria-expanded', String(!isOpen));
|
||||
});
|
||||
|
||||
menu.querySelectorAll('.status-option').forEach(function (option) {
|
||||
option.addEventListener('click', function () {
|
||||
const type = option.getAttribute('data-type');
|
||||
|
||||
if (type === 'online') {
|
||||
current.innerHTML = '<span class="status-dot" aria-hidden="true"></span>Online';
|
||||
} else {
|
||||
current.innerHTML = '<span class="status-minus" aria-hidden="true">-</span>Tidak Bisa Diganggu';
|
||||
}
|
||||
|
||||
closeMenu();
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (event) {
|
||||
if (!menu.contains(event.target) && !trigger.contains(event.target)) {
|
||||
closeMenu();
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views/welcome.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php if($paginator->hasPages()): ?>
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
|
||||
<?php if($paginator->onFirstPage()): ?>
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="<?php echo app('translator')->get('pagination.previous'); ?>">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?php echo e($paginator->previousPageUrl()); ?>" rel="prev" aria-label="<?php echo app('translator')->get('pagination.previous'); ?>">‹</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php $__currentLoopData = $elements; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $element): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
<?php if(is_string($element)): ?>
|
||||
<li class="page-item disabled" aria-disabled="true"><span class="page-link"><?php echo e($element); ?></span></li>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php if(is_array($element)): ?>
|
||||
<?php $__currentLoopData = $element; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $page => $url): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if($page == $paginator->currentPage()): ?>
|
||||
<li class="page-item active" aria-current="page"><span class="page-link"><?php echo e($page); ?></span></li>
|
||||
<?php else: ?>
|
||||
<li class="page-item"><a class="page-link" href="<?php echo e($url); ?>"><?php echo e($page); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
|
||||
<?php if($paginator->hasMorePages()): ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?php echo e($paginator->nextPageUrl()); ?>" rel="next" aria-label="<?php echo app('translator')->get('pagination.next'); ?>">›</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="<?php echo app('translator')->get('pagination.next'); ?>">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Pagination\resources\views\bootstrap-4.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<section
|
||||
<?php echo e($attributes->merge(['class' => "w-full max-w-7xl mx-auto p-4 sm:p-14 border-x border-dashed border-neutral-300 dark:border-white/[9%]"])); ?>
|
||||
|
||||
>
|
||||
<?php echo e($slot); ?>
|
||||
|
||||
</section>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\section-container.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="6" height="10" viewBox="0 0 6 10" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M0.875 9.25L5.125 5L0.875 0.75" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/chevron-right.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 441 B |
|
|
@ -0,0 +1,48 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['headers']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['headers']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<h2 class="text-lg font-semibold text-neutral-900 dark:text-white">Headers</h2>
|
||||
<div class="flex flex-col">
|
||||
<?php $__currentLoopData = $headers; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<div class="flex max-w-full items-baseline gap-2 h-10 text-sm font-mono">
|
||||
<div class="uppercase text-neutral-500 dark:text-neutral-400 shrink-0"><?php echo e($key); ?></div>
|
||||
<div class="min-w-6 grow h-3 border-b-2 border-dotted border-neutral-300 dark:border-white/20"></div>
|
||||
<div class="truncate text-neutral-900 dark:text-white">
|
||||
<span data-tippy-content="<?php echo e($value); ?>">
|
||||
<?php echo e($value); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\request-header.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['body']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['body']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<h2 class="text-lg font-semibold">Body</h2>
|
||||
<?php if($body): ?>
|
||||
<div class="bg-white dark:bg-white/[2%] border border-neutral-200 dark:border-neutral-800 rounded-md overflow-x-auto p-5 text-sm font-mono shadow-xs">
|
||||
<?php if (isset($component)) { $__componentOriginal12cb286571f553eebcbe98210b217f94 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal12cb286571f553eebcbe98210b217f94 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.syntax-highlight','data' => ['code' => $body,'language' => 'json']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::syntax-highlight'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['code' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($body),'language' => 'json']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $attributes = $__attributesOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__attributesOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $component = $__componentOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__componentOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php if (isset($component)) { $__componentOriginal612ffe32146e3bd2ac6ba6076cca9520 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.empty-state','data' => ['message' => 'No request body']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::empty-state'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['message' => 'No request body']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520)): ?>
|
||||
<?php $attributes = $__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520; ?>
|
||||
<?php unset($__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal612ffe32146e3bd2ac6ba6076cca9520)): ?>
|
||||
<?php $component = $__componentOriginal612ffe32146e3bd2ac6ba6076cca9520; ?>
|
||||
<?php unset($__componentOriginal612ffe32146e3bd2ac6ba6076cca9520); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/request-body.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="6" height="10" viewBox="0 0 6 10" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M5.125 0.75L0.875 5L5.125 9.25" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\chevron-left.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 427 B |
|
|
@ -0,0 +1,114 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['exception']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['exception']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="flex flex-col gap-2.5 bg-neutral-50 dark:bg-white/1 border border-neutral-200 dark:border-neutral-800 rounded-xl p-2.5 shadow-xs">
|
||||
<div class="flex items-center gap-2.5 p-2">
|
||||
<div class="bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/5 rounded-md w-6 h-6 flex items-center justify-center p-1">
|
||||
<?php if (isset($component)) { $__componentOriginalebc8ec9a834a8051f56913d6745a7050 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalebc8ec9a834a8051f56913d6745a7050 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.alert','data' => ['class' => 'w-2.5 h-2.5 text-blue-500 dark:text-emerald-500']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.alert'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5 text-blue-500 dark:text-emerald-500']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $attributes = $__attributesOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $component = $__componentOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__componentOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<h3 class="text-base font-semibold text-neutral-900 dark:text-white">Exception trace</h3>
|
||||
<?php if($exception->previousExceptions()->isNotEmpty()): ?>
|
||||
<a href="#previous-exceptions" class="ml-auto text-sm text-neutral-500 dark:text-neutral-400 hover:text-blue-500 dark:hover:text-emerald-500 transition-colors">
|
||||
<?php echo e($exception->previousExceptions()->count()); ?> previous <?php echo e(\Illuminate\Support\Str::plural('exception', $exception->previousExceptions()->count())); ?>
|
||||
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<?php $__currentLoopData = $exception->frameGroups(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $group): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if($group['is_vendor']): ?>
|
||||
<?php if (isset($component)) { $__componentOriginal449787012edfba29f0e80f325065fad5 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal449787012edfba29f0e80f325065fad5 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.vendor-frames','data' => ['frames' => $group['frames']]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::vendor-frames'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frames' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($group['frames'])]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal449787012edfba29f0e80f325065fad5)): ?>
|
||||
<?php $attributes = $__attributesOriginal449787012edfba29f0e80f325065fad5; ?>
|
||||
<?php unset($__attributesOriginal449787012edfba29f0e80f325065fad5); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal449787012edfba29f0e80f325065fad5)): ?>
|
||||
<?php $component = $__componentOriginal449787012edfba29f0e80f325065fad5; ?>
|
||||
<?php unset($__componentOriginal449787012edfba29f0e80f325065fad5); ?>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<?php $__currentLoopData = $group['frames']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $frame): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.frame','data' => ['frame' => $frame]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::frame'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frame' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($frame)]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407)): ?>
|
||||
<?php $attributes = $__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407; ?>
|
||||
<?php unset($__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407)): ?>
|
||||
<?php $component = $__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407; ?>
|
||||
<?php unset($__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407); ?>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\trace.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,694 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>JTI Monitoring - Politeknik Negeri Jember</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 {
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.1;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.brand-text p {
|
||||
margin-top: 2px;
|
||||
color: var(--muted);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.role-switch {
|
||||
display: inline-flex;
|
||||
gap: 8px;
|
||||
padding: 6px;
|
||||
border-radius: 999px;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.role-switch button {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 18px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
|
||||
color: #475569;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.role-switch button:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.role-switch button.active {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 20px rgba(79, 70, 229, 0.22);
|
||||
}
|
||||
|
||||
.hero {
|
||||
margin-top: 18px;
|
||||
border-radius: 28px;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.96) 0%, rgba(124, 58, 237, 0.9) 100%);
|
||||
color: white;
|
||||
box-shadow: var(--shadow);
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
.hero::before,
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: auto;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.14);
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
.hero::before {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
top: -110px;
|
||||
right: -70px;
|
||||
}
|
||||
|
||||
.hero::after {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
bottom: -80px;
|
||||
left: -40px;
|
||||
}
|
||||
|
||||
.hero-inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 42px 32px 38px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero-kicker {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 7px 14px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.hero h2 {
|
||||
margin-top: 18px;
|
||||
font-size: clamp(2rem, 4vw, 3.5rem);
|
||||
line-height: 1.05;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
margin-top: 12px;
|
||||
font-size: 1.05rem;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 18px;
|
||||
border-radius: 28px;
|
||||
background: var(--panel);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h3 {
|
||||
font-size: 1.45rem;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.section-head span {
|
||||
color: var(--muted);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.role-pane {
|
||||
display: none;
|
||||
padding: 26px;
|
||||
animation: fadeIn 0.35s ease;
|
||||
}
|
||||
|
||||
.role-pane.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.prodi-groups {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.prodi-group {
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.prodi-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed rgba(148, 163, 184, 0.35);
|
||||
}
|
||||
|
||||
.prodi-title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.prodi-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 999px;
|
||||
padding: 6px 10px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary), var(--primary-2));
|
||||
}
|
||||
|
||||
.bagian-groups {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.bagian-group {
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.bagian-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed rgba(148, 163, 184, 0.35);
|
||||
}
|
||||
|
||||
.bagian-title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.bagian-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 999px;
|
||||
padding: 6px 10px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--green), #14b8a6);
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 24px;
|
||||
padding: 22px;
|
||||
background: var(--panel-strong);
|
||||
border: 1px solid rgba(148, 163, 184, 0.16);
|
||||
box-shadow: 0 14px 34px rgba(15, 23, 42, 0.08);
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0 auto auto 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, var(--primary), var(--primary-2));
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
border-radius: 50%;
|
||||
flex: 0 0 auto;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
background-image: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 26px rgba(79, 70, 229, 0.28);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar.teknisi {
|
||||
background-image: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
box-shadow: 0 12px 26px rgba(5, 150, 105, 0.25);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.avatar.teknisi .avatar-placeholder {
|
||||
background-image: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.35;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.card-meta {
|
||||
margin-top: 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card-meta.dosen {
|
||||
background: linear-gradient(135deg, var(--primary), var(--primary-2));
|
||||
}
|
||||
|
||||
.card-meta.teknisi {
|
||||
background: linear-gradient(135deg, var(--green), #14b8a6);
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
margin-top: 16px;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.detail {
|
||||
display: grid;
|
||||
grid-template-columns: 84px 1fr;
|
||||
gap: 12px;
|
||||
align-items: start;
|
||||
padding: 11px 14px;
|
||||
border-radius: 14px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: #64748b;
|
||||
font-weight: 700;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
margin-top: 18px;
|
||||
padding: 24px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px dashed rgba(100, 116, 139, 0.3);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.footer-note {
|
||||
padding: 0 26px 26px;
|
||||
color: var(--muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.topbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.role-switch {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cards {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.page-shell {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.hero-inner,
|
||||
.role-pane,
|
||||
.section-head,
|
||||
.footer-note {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.detail {
|
||||
grid-template-columns: 1fr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 0.84rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-shell">
|
||||
<header class="topbar">
|
||||
<a class="brand" href="/">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>Politeknik Negeri Jember</h1>
|
||||
<p>Dashboard data dosen dan teknisi</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="role-switch" aria-label="Pilih role tampilan">
|
||||
<button id="btnDosen" class="active" type="button" onclick="showRole('dosen')">Dosen</button>
|
||||
<button id="btnTeknisi" type="button" onclick="showRole('teknisi')">Teknisi</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-inner">
|
||||
<div class="hero-kicker">Jurusan Teknologi Informasi</div>
|
||||
<h2 id="heroTitle">Dosen JTI</h2>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h3 id="sectionTitle">Program Studi Dosen</h3>
|
||||
<span id="sectionDesc">Daftar dosen aktif berdasarkan program studi.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$makeInitial = static function (string $nama): string {
|
||||
$parts = preg_split('/\s+/', trim($nama)) ?: [];
|
||||
$initials = '';
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
|
||||
if (strlen($initials) >= 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
?>
|
||||
|
||||
<section id="dosenPane" class="role-pane active">
|
||||
<?php
|
||||
$dosenByProdi = $dosen
|
||||
->sortBy([['prodi', 'asc'], ['nama', 'asc']])
|
||||
->groupBy(function ($item) {
|
||||
$prodi = trim((string) ($item->prodi ?? ''));
|
||||
return $prodi !== '' ? $prodi : 'Prodi Belum Ditentukan';
|
||||
});
|
||||
?>
|
||||
|
||||
<?php if($dosenByProdi->isEmpty()): ?>
|
||||
<div class="empty-state">Belum ada data dosen di database.</div>
|
||||
<?php else: ?>
|
||||
<div class="prodi-groups">
|
||||
<?php $__currentLoopData = $dosenByProdi; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $prodiName => $prodiItems): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<section class="prodi-group">
|
||||
<header class="prodi-head">
|
||||
<h4 class="prodi-title"><?php echo e($prodiName); ?></h4>
|
||||
<span class="prodi-count"><?php echo e($prodiItems->count()); ?> Dosen</span>
|
||||
</header>
|
||||
|
||||
<div class="cards">
|
||||
<?php $__currentLoopData = $prodiItems; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<article class="card">
|
||||
<?php
|
||||
$fotoUrl = $resolveFoto($item->foto);
|
||||
?>
|
||||
<div class="avatar" <?php if($fotoUrl): ?> style="background-image: url('<?php echo e($fotoUrl); ?>')" <?php endif; ?>>
|
||||
<?php if(!$fotoUrl): ?>
|
||||
<div class="avatar-placeholder"><?php echo e($makeInitial($item->nama)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-title"><?php echo e($item->nama); ?></div>
|
||||
<div class="card-meta dosen">Dosen</div>
|
||||
<div class="detail-list">
|
||||
<div class="detail"><div class="detail-label">NIP</div><div class="detail-value"><?php echo e($item->nip ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">NIDN</div><div class="detail-value"><?php echo e($item->nidn ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">Lokasi</div><div class="detail-value">Gedung JTI Lt. 1</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<section id="teknisiPane" class="role-pane">
|
||||
<?php
|
||||
$teknisiByBagian = $teknisi
|
||||
->sortBy([['bagian', 'asc'], ['nama', 'asc']])
|
||||
->groupBy(function ($item) {
|
||||
$bagian = trim((string) ($item->bagian ?? ''));
|
||||
return $bagian !== '' ? $bagian : 'Bagian Belum Ditentukan';
|
||||
});
|
||||
?>
|
||||
|
||||
<?php if($teknisiByBagian->isEmpty()): ?>
|
||||
<div class="empty-state">Belum ada data teknisi/staff di database.</div>
|
||||
<?php else: ?>
|
||||
<div class="bagian-groups">
|
||||
<?php $__currentLoopData = $teknisiByBagian; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $bagianName => $bagianItems): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<section class="bagian-group">
|
||||
<header class="bagian-head">
|
||||
<h4 class="bagian-title"><?php echo e($bagianName); ?></h4>
|
||||
<span class="bagian-count"><?php echo e($bagianItems->count()); ?> Orang</span>
|
||||
</header>
|
||||
|
||||
<div class="cards">
|
||||
<?php $__currentLoopData = $bagianItems; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<article class="card">
|
||||
<?php
|
||||
$fotoUrl = $resolveFoto($item->foto);
|
||||
?>
|
||||
<div class="avatar teknisi" <?php if($fotoUrl): ?> style="background-image: url('<?php echo e($fotoUrl); ?>')" <?php endif; ?>>
|
||||
<?php if(!$fotoUrl): ?>
|
||||
<div class="avatar-placeholder"><?php echo e($makeInitial($item->nama)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-title"><?php echo e($item->nama); ?></div>
|
||||
<div class="card-meta teknisi"><?php echo e(ucfirst($item->role ?? 'staff')); ?></div>
|
||||
<div class="detail-list">
|
||||
<div class="detail"><div class="detail-label">NIP</div><div class="detail-value"><?php echo e($item->nip ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">NIDN</div><div class="detail-value"><?php echo e($item->nidn ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">Lokasi</div><div class="detail-value">Gedung JTI Lt. 1</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<div class="footer-note">
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showRole(role) {
|
||||
const dosenPane = document.getElementById('dosenPane');
|
||||
const teknisiPane = document.getElementById('teknisiPane');
|
||||
const btnDosen = document.getElementById('btnDosen');
|
||||
const btnTeknisi = document.getElementById('btnTeknisi');
|
||||
const heroTitle = document.getElementById('heroTitle');
|
||||
const sectionTitle = document.getElementById('sectionTitle');
|
||||
const sectionDesc = document.getElementById('sectionDesc');
|
||||
|
||||
const isDosen = role === 'dosen';
|
||||
|
||||
dosenPane.classList.toggle('active', isDosen);
|
||||
teknisiPane.classList.toggle('active', !isDosen);
|
||||
btnDosen.classList.toggle('active', isDosen);
|
||||
btnTeknisi.classList.toggle('active', !isDosen);
|
||||
|
||||
heroTitle.textContent = isDosen ? 'Dosen JTI' : 'Teknisi JTI';
|
||||
sectionTitle.textContent = isDosen ? 'Program Studi Dosen' : 'Teknisi dan Staff';
|
||||
sectionDesc.textContent = isDosen
|
||||
? 'Daftar dosen aktif berdasarkan program studi.'
|
||||
: 'Daftar teknisi dan staff aktif berdasarkan bagian.';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views\dashboard.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php use \Illuminate\Foundation\Exceptions\Renderer\Renderer; ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
|
||||
|
||||
<title><?php echo e(config('app.name', 'Laravel')); ?></title>
|
||||
|
||||
<link
|
||||
rel="icon" type="image/svg+xml"
|
||||
href="data:image/svg+xml,%3Csvg viewBox='0 -.11376601 49.74245785 51.31690859' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m49.626 11.564a.809.809 0 0 1 .028.209v10.972a.8.8 0 0 1 -.402.694l-9.209 5.302v10.509c0 .286-.152.55-.4.694l-19.223 11.066c-.044.025-.092.041-.14.058-.018.006-.035.017-.054.022a.805.805 0 0 1 -.41 0c-.022-.006-.042-.018-.063-.026-.044-.016-.09-.03-.132-.054l-19.219-11.066a.801.801 0 0 1 -.402-.694v-32.916c0-.072.01-.142.028-.21.006-.023.02-.044.028-.067.015-.042.029-.085.051-.124.015-.026.037-.047.055-.071.023-.032.044-.065.071-.093.023-.023.053-.04.079-.06.029-.024.055-.05.088-.069h.001l9.61-5.533a.802.802 0 0 1 .8 0l9.61 5.533h.002c.032.02.059.045.088.068.026.02.055.038.078.06.028.029.048.062.072.094.017.024.04.045.054.071.023.04.036.082.052.124.008.023.022.044.028.068a.809.809 0 0 1 .028.209v20.559l8.008-4.611v-10.51c0-.07.01-.141.028-.208.007-.024.02-.045.028-.068.016-.042.03-.085.052-.124.015-.026.037-.047.054-.071.024-.032.044-.065.072-.093.023-.023.052-.04.078-.06.03-.024.056-.05.088-.069h.001l9.611-5.533a.801.801 0 0 1 .8 0l9.61 5.533c.034.02.06.045.09.068.025.02.054.038.077.06.028.029.048.062.072.094.018.024.04.045.054.071.023.039.036.082.052.124.009.023.022.044.028.068zm-1.574 10.718v-9.124l-3.363 1.936-4.646 2.675v9.124l8.01-4.611zm-9.61 16.505v-9.13l-4.57 2.61-13.05 7.448v9.216zm-36.84-31.068v31.068l17.618 10.143v-9.214l-9.204-5.209-.003-.002-.004-.002c-.031-.018-.057-.044-.086-.066-.025-.02-.054-.036-.076-.058l-.002-.003c-.026-.025-.044-.056-.066-.084-.02-.027-.044-.05-.06-.078l-.001-.003c-.018-.03-.029-.066-.042-.1-.013-.03-.03-.058-.038-.09v-.001c-.01-.038-.012-.078-.016-.117-.004-.03-.012-.06-.012-.09v-21.483l-4.645-2.676-3.363-1.934zm8.81-5.994-8.007 4.609 8.005 4.609 8.006-4.61-8.006-4.608zm4.164 28.764 4.645-2.674v-20.096l-3.363 1.936-4.646 2.675v20.096zm24.667-23.325-8.006 4.609 8.006 4.609 8.005-4.61zm-.801 10.605-4.646-2.675-3.363-1.936v9.124l4.645 2.674 3.364 1.937zm-18.422 20.561 11.743-6.704 5.87-3.35-8-4.606-9.211 5.303-8.395 4.833z' fill='%23ff2d20'/%3E%3C/svg%3E"
|
||||
/>
|
||||
|
||||
<?php echo Renderer::css(); ?>
|
||||
|
||||
</head>
|
||||
<body class="font-sans antialiased overflow-x-hidden bg-neutral-50 dark:bg-neutral-900 dark:text-white scheme-light-dark">
|
||||
<div class="min-h-dvh">
|
||||
<?php echo e($slot); ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php echo Renderer::js(); ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/layout.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['message']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['message']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="bg-white/[2%] border border-neutral-200 dark:border-neutral-800 rounded-md w-full p-5 uppercase text-sm text-center font-mono shadow-xs text-neutral-600 dark:text-neutral-400">
|
||||
<span class="text-neutral-400 dark:text-neutral-600">// </span><?php echo e($message); ?>
|
||||
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/empty-state.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?php if($paginator->hasPages()): ?>
|
||||
<nav class="d-flex justify-items-center justify-content-between">
|
||||
<div class="d-flex justify-content-between flex-fill d-sm-none">
|
||||
<ul class="pagination">
|
||||
|
||||
<?php if($paginator->onFirstPage()): ?>
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link"><?php echo app('translator')->get('pagination.previous'); ?></span>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?php echo e($paginator->previousPageUrl()); ?>" rel="prev"><?php echo app('translator')->get('pagination.previous'); ?></a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php if($paginator->hasMorePages()): ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?php echo e($paginator->nextPageUrl()); ?>" rel="next"><?php echo app('translator')->get('pagination.next'); ?></a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link"><?php echo app('translator')->get('pagination.next'); ?></span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="d-none flex-sm-fill d-sm-flex align-items-sm-center justify-content-sm-between">
|
||||
<div class="small text-muted">
|
||||
<?php echo __('Showing'); ?>
|
||||
|
||||
<span class="fw-semibold"><?php echo e($paginator->firstItem()); ?></span>
|
||||
<?php echo __('to'); ?>
|
||||
|
||||
<span class="fw-semibold"><?php echo e($paginator->lastItem()); ?></span>
|
||||
<?php echo __('of'); ?>
|
||||
|
||||
<span class="fw-semibold"><?php echo e($paginator->total()); ?></span>
|
||||
<?php echo __('results'); ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul class="pagination">
|
||||
|
||||
<?php if($paginator->onFirstPage()): ?>
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="<?php echo app('translator')->get('pagination.previous'); ?>">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?php echo e($paginator->previousPageUrl()); ?>" rel="prev" aria-label="<?php echo app('translator')->get('pagination.previous'); ?>">‹</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php $__currentLoopData = $elements; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $element): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
<?php if(is_string($element)): ?>
|
||||
<li class="page-item disabled" aria-disabled="true"><span class="page-link"><?php echo e($element); ?></span></li>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php if(is_array($element)): ?>
|
||||
<?php $__currentLoopData = $element; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $page => $url): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if($page == $paginator->currentPage()): ?>
|
||||
<li class="page-item active" aria-current="page"><span class="page-link"><?php echo e($page); ?></span></li>
|
||||
<?php else: ?>
|
||||
<li class="page-item"><a class="page-link" href="<?php echo e($url); ?>"><?php echo e($page); ?></a></li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
|
||||
<?php if($paginator->hasMorePages()): ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="<?php echo e($paginator->nextPageUrl()); ?>" rel="next" aria-label="<?php echo app('translator')->get('pagination.next'); ?>">›</a>
|
||||
</li>
|
||||
<?php else: ?>
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="<?php echo app('translator')->get('pagination.next'); ?>">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Pagination\resources\views\bootstrap-5.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" <?php echo e($attributes); ?>>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/check.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 384 B |
|
|
@ -0,0 +1,418 @@
|
|||
<?php if (isset($component)) { $__componentOriginalbbd4eeea836234825f7514ed20d2d52d = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalbbd4eeea836234825f7514ed20d2d52d = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.layout','data' => []] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::layout'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes([]); ?>
|
||||
<?php if (isset($component)) { $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.section-container','data' => ['class' => 'px-6 py-0 sm:py-0']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::section-container'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'px-6 py-0 sm:py-0']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginal6769184c81828596613858780a973bc6 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal6769184c81828596613858780a973bc6 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.topbar','data' => ['title' => $exception->title(),'markdown' => $exceptionAsMarkdown]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::topbar'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['title' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->title()),'markdown' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exceptionAsMarkdown)]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal6769184c81828596613858780a973bc6)): ?>
|
||||
<?php $attributes = $__attributesOriginal6769184c81828596613858780a973bc6; ?>
|
||||
<?php unset($__attributesOriginal6769184c81828596613858780a973bc6); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal6769184c81828596613858780a973bc6)): ?>
|
||||
<?php $component = $__componentOriginal6769184c81828596613858780a973bc6; ?>
|
||||
<?php unset($__componentOriginal6769184c81828596613858780a973bc6); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $attributes = $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $component = $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal40a3de7997c05e5562c4104d90e9b634 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal40a3de7997c05e5562c4104d90e9b634 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.separator','data' => []] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::separator'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes([]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $attributes = $__attributesOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $component = $__componentOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__componentOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.section-container','data' => ['class' => 'flex flex-col gap-8 py-0 sm:py-0']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::section-container'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'flex flex-col gap-8 py-0 sm:py-0']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginal1e817eb3c41fe3ea9eb0c15213c4b557 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal1e817eb3c41fe3ea9eb0c15213c4b557 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.header','data' => ['exception' => $exception]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::header'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['exception' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception)]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal1e817eb3c41fe3ea9eb0c15213c4b557)): ?>
|
||||
<?php $attributes = $__attributesOriginal1e817eb3c41fe3ea9eb0c15213c4b557; ?>
|
||||
<?php unset($__attributesOriginal1e817eb3c41fe3ea9eb0c15213c4b557); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal1e817eb3c41fe3ea9eb0c15213c4b557)): ?>
|
||||
<?php $component = $__componentOriginal1e817eb3c41fe3ea9eb0c15213c4b557; ?>
|
||||
<?php unset($__componentOriginal1e817eb3c41fe3ea9eb0c15213c4b557); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $attributes = $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $component = $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal40a3de7997c05e5562c4104d90e9b634 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal40a3de7997c05e5562c4104d90e9b634 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.separator','data' => ['class' => '-mt-5 -z-10']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::separator'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => '-mt-5 -z-10']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $attributes = $__attributesOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $component = $__componentOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__componentOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.section-container','data' => ['class' => 'flex flex-col gap-8 pt-14']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::section-container'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'flex flex-col gap-8 pt-14']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginal92c1a431b4816bac5d5a20d0fc1238ab = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal92c1a431b4816bac5d5a20d0fc1238ab = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.trace','data' => ['exception' => $exception]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::trace'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['exception' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception)]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal92c1a431b4816bac5d5a20d0fc1238ab)): ?>
|
||||
<?php $attributes = $__attributesOriginal92c1a431b4816bac5d5a20d0fc1238ab; ?>
|
||||
<?php unset($__attributesOriginal92c1a431b4816bac5d5a20d0fc1238ab); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal92c1a431b4816bac5d5a20d0fc1238ab)): ?>
|
||||
<?php $component = $__componentOriginal92c1a431b4816bac5d5a20d0fc1238ab; ?>
|
||||
<?php unset($__componentOriginal92c1a431b4816bac5d5a20d0fc1238ab); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($exception->previousExceptions()->isNotEmpty()): ?>
|
||||
<?php if (isset($component)) { $__componentOriginal57933e9e29ce1ea934dd1d7d96c0d62e = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal57933e9e29ce1ea934dd1d7d96c0d62e = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.previous-exceptions','data' => ['exception' => $exception]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::previous-exceptions'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['exception' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception)]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal57933e9e29ce1ea934dd1d7d96c0d62e)): ?>
|
||||
<?php $attributes = $__attributesOriginal57933e9e29ce1ea934dd1d7d96c0d62e; ?>
|
||||
<?php unset($__attributesOriginal57933e9e29ce1ea934dd1d7d96c0d62e); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal57933e9e29ce1ea934dd1d7d96c0d62e)): ?>
|
||||
<?php $component = $__componentOriginal57933e9e29ce1ea934dd1d7d96c0d62e; ?>
|
||||
<?php unset($__componentOriginal57933e9e29ce1ea934dd1d7d96c0d62e); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginalb73d2d8821ad40718c243f895ec0c546 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalb73d2d8821ad40718c243f895ec0c546 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.query','data' => ['queries' => $exception->applicationQueries()]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::query'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['queries' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->applicationQueries())]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalb73d2d8821ad40718c243f895ec0c546)): ?>
|
||||
<?php $attributes = $__attributesOriginalb73d2d8821ad40718c243f895ec0c546; ?>
|
||||
<?php unset($__attributesOriginalb73d2d8821ad40718c243f895ec0c546); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalb73d2d8821ad40718c243f895ec0c546)): ?>
|
||||
<?php $component = $__componentOriginalb73d2d8821ad40718c243f895ec0c546; ?>
|
||||
<?php unset($__componentOriginalb73d2d8821ad40718c243f895ec0c546); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $attributes = $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $component = $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal40a3de7997c05e5562c4104d90e9b634 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal40a3de7997c05e5562c4104d90e9b634 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.separator','data' => []] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::separator'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes([]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $attributes = $__attributesOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $component = $__componentOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__componentOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.section-container','data' => ['class' => 'flex flex-col gap-12']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::section-container'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'flex flex-col gap-12']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalcc330c991c1b19cde28fea414de1b6cb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalcc330c991c1b19cde28fea414de1b6cb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.request-header','data' => ['headers' => $exception->requestHeaders()]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::request-header'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['headers' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->requestHeaders())]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalcc330c991c1b19cde28fea414de1b6cb)): ?>
|
||||
<?php $attributes = $__attributesOriginalcc330c991c1b19cde28fea414de1b6cb; ?>
|
||||
<?php unset($__attributesOriginalcc330c991c1b19cde28fea414de1b6cb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalcc330c991c1b19cde28fea414de1b6cb)): ?>
|
||||
<?php $component = $__componentOriginalcc330c991c1b19cde28fea414de1b6cb; ?>
|
||||
<?php unset($__componentOriginalcc330c991c1b19cde28fea414de1b6cb); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal3ce7d5064193f9b8bde76eb6792e715a = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal3ce7d5064193f9b8bde76eb6792e715a = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.request-body','data' => ['body' => $exception->requestBody()]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::request-body'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['body' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->requestBody())]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal3ce7d5064193f9b8bde76eb6792e715a)): ?>
|
||||
<?php $attributes = $__attributesOriginal3ce7d5064193f9b8bde76eb6792e715a; ?>
|
||||
<?php unset($__attributesOriginal3ce7d5064193f9b8bde76eb6792e715a); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal3ce7d5064193f9b8bde76eb6792e715a)): ?>
|
||||
<?php $component = $__componentOriginal3ce7d5064193f9b8bde76eb6792e715a; ?>
|
||||
<?php unset($__componentOriginal3ce7d5064193f9b8bde76eb6792e715a); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal40aab92597234e6686a03fbf91514afb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal40aab92597234e6686a03fbf91514afb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.routing','data' => ['routing' => $exception->applicationRouteContext()]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::routing'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['routing' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->applicationRouteContext())]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal40aab92597234e6686a03fbf91514afb)): ?>
|
||||
<?php $attributes = $__attributesOriginal40aab92597234e6686a03fbf91514afb; ?>
|
||||
<?php unset($__attributesOriginal40aab92597234e6686a03fbf91514afb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal40aab92597234e6686a03fbf91514afb)): ?>
|
||||
<?php $component = $__componentOriginal40aab92597234e6686a03fbf91514afb; ?>
|
||||
<?php unset($__componentOriginal40aab92597234e6686a03fbf91514afb); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal982e77712eb0069b2ae32176000f422d = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal982e77712eb0069b2ae32176000f422d = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.routing-parameter','data' => ['routeParameters' => $exception->applicationRouteParametersContext()]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::routing-parameter'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['routeParameters' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->applicationRouteParametersContext())]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal982e77712eb0069b2ae32176000f422d)): ?>
|
||||
<?php $attributes = $__attributesOriginal982e77712eb0069b2ae32176000f422d; ?>
|
||||
<?php unset($__attributesOriginal982e77712eb0069b2ae32176000f422d); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal982e77712eb0069b2ae32176000f422d)): ?>
|
||||
<?php $component = $__componentOriginal982e77712eb0069b2ae32176000f422d; ?>
|
||||
<?php unset($__componentOriginal982e77712eb0069b2ae32176000f422d); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $attributes = $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $component = $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal40a3de7997c05e5562c4104d90e9b634 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal40a3de7997c05e5562c4104d90e9b634 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.separator','data' => []] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::separator'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes([]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $attributes = $__attributesOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__attributesOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal40a3de7997c05e5562c4104d90e9b634)): ?>
|
||||
<?php $component = $__componentOriginal40a3de7997c05e5562c4104d90e9b634; ?>
|
||||
<?php unset($__componentOriginal40a3de7997c05e5562c4104d90e9b634); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(! app()->runningUnitTests() && ! app()->runningInConsole()): ?>
|
||||
<?php if (isset($component)) { $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.section-container','data' => ['class' => 'pb-0 sm:pb-0']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::section-container'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'pb-0 sm:pb-0']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginal00da9961ee0aae6b56664f2b481f9f2e = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal00da9961ee0aae6b56664f2b481f9f2e = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.laravel-ascii-spotlight','data' => []] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::laravel-ascii-spotlight'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes([]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal00da9961ee0aae6b56664f2b481f9f2e)): ?>
|
||||
<?php $attributes = $__attributesOriginal00da9961ee0aae6b56664f2b481f9f2e; ?>
|
||||
<?php unset($__attributesOriginal00da9961ee0aae6b56664f2b481f9f2e); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal00da9961ee0aae6b56664f2b481f9f2e)): ?>
|
||||
<?php $component = $__componentOriginal00da9961ee0aae6b56664f2b481f9f2e; ?>
|
||||
<?php unset($__componentOriginal00da9961ee0aae6b56664f2b481f9f2e); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $attributes = $__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__attributesOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b)): ?>
|
||||
<?php $component = $__componentOriginal1e2fb8a385bff5b6574eeb687cee100b; ?>
|
||||
<?php unset($__componentOriginal1e2fb8a385bff5b6574eeb687cee100b); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalbbd4eeea836234825f7514ed20d2d52d)): ?>
|
||||
<?php $attributes = $__attributesOriginalbbd4eeea836234825f7514ed20d2d52d; ?>
|
||||
<?php unset($__attributesOriginalbbd4eeea836234825f7514ed20d2d52d); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalbbd4eeea836234825f7514ed20d2d52d)): ?>
|
||||
<?php $component = $__componentOriginalbbd4eeea836234825f7514ed20d2d52d; ?>
|
||||
<?php unset($__componentOriginalbbd4eeea836234825f7514ed20d2d52d); ?>
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php $__env->startSection('title', __('Unauthorized')); ?>
|
||||
<?php $__env->startSection('code', '401'); ?>
|
||||
<?php $__env->startSection('message', __('Unauthorized')); ?>
|
||||
|
||||
<?php echo $__env->make('errors::minimal', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\views\401.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['exception']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['exception']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div id="previous-exceptions" class="flex flex-col gap-2.5 bg-neutral-50 dark:bg-white/1 border border-neutral-200 dark:border-neutral-800 rounded-xl p-2.5 shadow-xs">
|
||||
<div class="flex items-center gap-2.5 p-2">
|
||||
<div class="bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-white/5 rounded-md w-6 h-6 flex items-center justify-center p-1">
|
||||
<?php if (isset($component)) { $__componentOriginalebc8ec9a834a8051f56913d6745a7050 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalebc8ec9a834a8051f56913d6745a7050 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.alert','data' => ['class' => 'w-2.5 h-2.5 text-blue-500 dark:text-emerald-500']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.alert'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5 text-blue-500 dark:text-emerald-500']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $attributes = $__attributesOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $component = $__componentOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__componentOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<h3 class="text-base font-semibold text-neutral-900 dark:text-white">Previous <?php echo e(\Illuminate\Support\Str::plural('exception', $exception->previousExceptions()->count())); ?></h3>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<?php $__currentLoopData = $exception->previousExceptions(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $previous): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<div class="flex gap-2.5 px-2">
|
||||
|
||||
<?php if($exception->previousExceptions()->count() > 1): ?>
|
||||
<div class="flex flex-col items-center w-6 flex-shrink-0 self-stretch">
|
||||
<?php if($index > 0): ?>
|
||||
<div class="h-[23.5px] w-px border-l border-dashed border-emerald-900"></div>
|
||||
<?php else: ?>
|
||||
<div class="h-[23.5px]"></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="size-[9px] flex-shrink-0 rounded-full bg-emerald-800"></div>
|
||||
|
||||
<?php if($index < $exception->previousExceptions()->count() - 1): ?>
|
||||
<div class="flex-1 w-px border-l border-dashed border-emerald-900"></div>
|
||||
<?php else: ?>
|
||||
<div class="flex-1"></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div
|
||||
x-data="{ expanded: false }"
|
||||
class="group/exception flex-1 min-w-0 rounded-lg my-1.5"
|
||||
:class="{
|
||||
'border border-neutral-200 bg-white/50 dark:bg-white/2 dark:border-white/5': expanded,
|
||||
<?php if($exception->previousExceptions()->count() === 1): ?>
|
||||
'border border-neutral-200 dark:border-transparent dark:bg-white/2': !expanded,
|
||||
<?php else: ?>
|
||||
'hover:border hover:border-neutral-200 dark:hover:border-none': !expanded,
|
||||
<?php endif; ?>
|
||||
}"
|
||||
>
|
||||
|
||||
<div
|
||||
class="flex gap-2.5 p-3 cursor-pointer rounded-lg"
|
||||
:class="{ 'hover:bg-white/50 dark:hover:bg-white/2': !expanded }"
|
||||
@click="expanded = !expanded"
|
||||
>
|
||||
<div
|
||||
class="flex-1 min-w-0"
|
||||
:class="expanded ? 'flex flex-col' : 'flex items-baseline gap-2'"
|
||||
>
|
||||
<h4 class="font-mono text-sm font-medium text-neutral-900 dark:text-white flex-shrink-0 max-w-full truncate"><?php echo e($previous->class()); ?></h4>
|
||||
<p
|
||||
class="text-sm text-neutral-500 dark:text-neutral-400"
|
||||
:class="expanded ? 'mt-1 break-words' : 'truncate'"
|
||||
><?php echo e($previous->message()); ?></p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="flex h-6 w-6 flex-shrink-0 cursor-pointer items-center justify-center rounded-md border border-neutral-200 dark:border-white/8 group-hover/exception:text-blue-500 group-hover/exception:dark:text-emerald-500"
|
||||
:class="{
|
||||
'text-blue-500 dark:text-emerald-500 dark:bg-white/5': expanded,
|
||||
'text-neutral-500 dark:text-neutral-500 dark:bg-white/3': !expanded,
|
||||
}"
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.chevrons-down-up','data' => ['xShow' => 'expanded']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.chevrons-down-up'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['x-show' => 'expanded']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28)): ?>
|
||||
<?php $attributes = $__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28; ?>
|
||||
<?php unset($__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28)): ?>
|
||||
<?php $component = $__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28; ?>
|
||||
<?php unset($__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal7348bb70f498d75e0a91acc6a707f136 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal7348bb70f498d75e0a91acc6a707f136 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.chevrons-up-down','data' => ['xShow' => '!expanded','xCloak' => true]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.chevrons-up-down'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['x-show' => '!expanded','x-cloak' => true]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal7348bb70f498d75e0a91acc6a707f136)): ?>
|
||||
<?php $attributes = $__attributesOriginal7348bb70f498d75e0a91acc6a707f136; ?>
|
||||
<?php unset($__attributesOriginal7348bb70f498d75e0a91acc6a707f136); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal7348bb70f498d75e0a91acc6a707f136)): ?>
|
||||
<?php $component = $__componentOriginal7348bb70f498d75e0a91acc6a707f136; ?>
|
||||
<?php unset($__componentOriginal7348bb70f498d75e0a91acc6a707f136); ?>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div x-show="expanded" x-cloak class="flex flex-col gap-1.5 p-3">
|
||||
<?php $__currentLoopData = $previous->frameGroups(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $group): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if($group['is_vendor']): ?>
|
||||
<?php if (isset($component)) { $__componentOriginal449787012edfba29f0e80f325065fad5 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal449787012edfba29f0e80f325065fad5 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.vendor-frames','data' => ['frames' => $group['frames']]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::vendor-frames'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frames' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($group['frames'])]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal449787012edfba29f0e80f325065fad5)): ?>
|
||||
<?php $attributes = $__attributesOriginal449787012edfba29f0e80f325065fad5; ?>
|
||||
<?php unset($__attributesOriginal449787012edfba29f0e80f325065fad5); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal449787012edfba29f0e80f325065fad5)): ?>
|
||||
<?php $component = $__componentOriginal449787012edfba29f0e80f325065fad5; ?>
|
||||
<?php unset($__componentOriginal449787012edfba29f0e80f325065fad5); ?>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<?php $__currentLoopData = $group['frames']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $frame): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.frame','data' => ['frame' => $frame]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::frame'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frame' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($frame)]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407)): ?>
|
||||
<?php $attributes = $__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407; ?>
|
||||
<?php unset($__attributesOriginalc7c58c6d16fe849872fb25ad6e9b8407); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407)): ?>
|
||||
<?php $component = $__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407; ?>
|
||||
<?php unset($__componentOriginalc7c58c6d16fe849872fb25ad6e9b8407); ?>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\previous-exceptions.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,626 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tambah Staff/Teknisi - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #e0fdf4;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #059669;
|
||||
--primary-2: #14b8a6;
|
||||
--purple: #4f46e5;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(5, 150, 105, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(20, 184, 166, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #d1fae5 0%, #e0fdf4 45%, #f0fdfa 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 900;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header-desc {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
padding: 36px;
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 36px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.photo-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.photo-frame {
|
||||
width: 100%;
|
||||
aspect-ratio: 3/4;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 4rem;
|
||||
font-weight: 900;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
box-shadow: 0 16px 36px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.photo-frame:hover {
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 20px 48px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.photo-frame img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.photo-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.photo-label {
|
||||
border: 2px dashed rgba(5, 150, 105, 0.3);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
}
|
||||
|
||||
.photo-label:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
}
|
||||
|
||||
.photo-label-text {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.photo-label-hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section.full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-weight: 800;
|
||||
color: #475569;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.field label .required {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.input, .select {
|
||||
padding: 13px 14px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.25);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.input:focus, .select:focus {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.1);
|
||||
}
|
||||
|
||||
.input::placeholder {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
margin: 18px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 16px;
|
||||
background: rgba(217, 119, 6, 0.08);
|
||||
border: 1px solid rgba(217, 119, 6, 0.18);
|
||||
color: #7c2d12;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.error-message ul {
|
||||
margin-top: 8px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.field-error {
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
color: #991b1b;
|
||||
font-weight: 700;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.input.error, .select.error {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.02);
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 14px;
|
||||
padding: 16px;
|
||||
background: rgba(5, 150, 105, 0.05);
|
||||
border-radius: 14px;
|
||||
border: 1.5px solid rgba(5, 150, 105, 0.2);
|
||||
}
|
||||
|
||||
.role-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"] {
|
||||
cursor: pointer;
|
||||
accent-color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.04);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"]:checked ~ label {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option label {
|
||||
cursor: pointer;
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
gap: 8px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.btn.primary:hover {
|
||||
box-shadow: 0 16px 32px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.form-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-shell">
|
||||
<header class="header">
|
||||
<h1 class="header-title">🔧 Tambah Staff/Teknisi</h1>
|
||||
<p class="header-desc">Lengkapi data staff atau teknisi dengan informasi yang akurat.</p>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<?php if($errors->any()): ?>
|
||||
<div class="error-message">
|
||||
<strong>❌ Terjadi kesalahan validasi:</strong>
|
||||
<ul>
|
||||
<?php $__currentLoopData = $errors->all(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $error): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<li><?php echo e($error); ?></li>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST" action="<?php echo e(route('staff.store')); ?>" class="form-container">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<!-- Foto Section -->
|
||||
<div class="photo-section">
|
||||
<div class="photo-frame" id="photoPreview">
|
||||
<span id="photoInitial">🔧</span>
|
||||
<img id="photoImg" style="display:none;" />
|
||||
</div>
|
||||
<label class="photo-label" for="fotoInput">
|
||||
<div class="photo-label-text">📤 Upload Foto</div>
|
||||
<div class="photo-label-hint">Klik untuk memilih gambar</div>
|
||||
</label>
|
||||
<input
|
||||
id="fotoInput"
|
||||
class="input"
|
||||
type="text"
|
||||
name="foto"
|
||||
value="<?php echo e(old('foto')); ?>"
|
||||
placeholder="atau masukkan URL foto"
|
||||
>
|
||||
<div class="hint">Format: URL gambar (https://...)</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Fields -->
|
||||
<div class="form-fields">
|
||||
<!-- Row 1: Nama -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input
|
||||
id="nama"
|
||||
class="input <?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nama"
|
||||
value="<?php echo e(old('nama')); ?>"
|
||||
placeholder="Masukkan nama lengkap"
|
||||
required
|
||||
>
|
||||
<?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 2: NIP dan NIDN -->
|
||||
<div class="field-section">
|
||||
<div class="field">
|
||||
<label for="nip">NIP</label>
|
||||
<input
|
||||
id="nip"
|
||||
class="input <?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nip"
|
||||
value="<?php echo e(old('nip')); ?>"
|
||||
placeholder="Contoh: 12345678 900000 1 001"
|
||||
>
|
||||
<?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Nomor Induk Pegawai (opsional)</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="nidn">Identitas Lain / BioID</label>
|
||||
<input
|
||||
id="nidn"
|
||||
class="input <?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nidn"
|
||||
value="<?php echo e(old('nidn')); ?>"
|
||||
placeholder="Contoh: BiometricID atau nomor lain"
|
||||
>
|
||||
<?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Identitas tambahan (opsional)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 3: Bagian -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="bagian">Bagian <span class="required">*</span></label>
|
||||
<select
|
||||
id="bagian"
|
||||
class="select <?php $__errorArgs = ['bagian'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
name="bagian"
|
||||
required
|
||||
>
|
||||
<option value="">-- Pilih Bagian --</option>
|
||||
<option value="Staff Administrasi" <?php if(old('bagian') === 'Staff Administrasi'): echo 'selected'; endif; ?>>Staff Administrasi</option>
|
||||
<option value="Arsitektur dan Jaringan Komputer" <?php if(old('bagian') === 'Arsitektur dan Jaringan Komputer'): echo 'selected'; endif; ?>>Arsitektur dan Jaringan Komputer</option>
|
||||
<option value="Komputasi dan Sistem Informasi" <?php if(old('bagian') === 'Komputasi dan Sistem Informasi'): echo 'selected'; endif; ?>>Komputasi dan Sistem Informasi</option>
|
||||
<option value="Rekayasa Sistem Informasi" <?php if(old('bagian') === 'Rekayasa Sistem Informasi'): echo 'selected'; endif; ?>>Rekayasa Sistem Informasi</option>
|
||||
<option value="Sistem Komputer dan Kontrol" <?php if(old('bagian') === 'Sistem Komputer dan Kontrol'): echo 'selected'; endif; ?>>Sistem Komputer dan Kontrol</option>
|
||||
<option value="Rekayasa Perangkat Lunak" <?php if(old('bagian') === 'Rekayasa Perangkat Lunak'): echo 'selected'; endif; ?>>Rekayasa Perangkat Lunak</option>
|
||||
<option value="Multimedia Cerdas" <?php if(old('bagian') === 'Multimedia Cerdas'): echo 'selected'; endif; ?>>Multimedia Cerdas</option>
|
||||
<option value="Staff Lainnya" <?php if(old('bagian') === 'Staff Lainnya'): echo 'selected'; endif; ?>>Staff Lainnya</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['bagian'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Pilih bagian/divisi staff</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Role Selection -->
|
||||
<div class="field-section full">
|
||||
<label style="font-weight: 800; color: #475569; font-size: 0.92rem; margin-bottom: 8px;">Pilih Role <span class="required">*</span></label>
|
||||
<div class="role-selector">
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleStaff" name="role" value="staff" <?php if(old('role') === 'staff' || !old('role')): echo 'checked'; endif; ?> required>
|
||||
<label for="roleStaff">👤 Staff</label>
|
||||
</div>
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleTeknik" name="role" value="teknisi" <?php if(old('role') === 'teknisi'): echo 'checked'; endif; ?> required>
|
||||
<label for="roleTeknik">🔧 Teknisi</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<button class="btn primary" type="submit">✅ Simpan Staff/Teknisi</button>
|
||||
<a class="btn ghost" href="<?php echo e(route('users.staff')); ?>">❌ Batal</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Photo preview dari URL
|
||||
const fotoInput = document.getElementById('fotoInput');
|
||||
const photoPreview = document.getElementById('photoPreview');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const roleStaffInput = document.getElementById('roleStaff');
|
||||
const roleTeknikInput = document.getElementById('roleTeknik');
|
||||
const submitBtn = document.querySelector('button[type="submit"]');
|
||||
const form = document.querySelector('form');
|
||||
let isSubmitting = false;
|
||||
|
||||
function updatePhotoIcon() {
|
||||
if (roleTeknikInput.checked) {
|
||||
return '🔧';
|
||||
}
|
||||
return '👤';
|
||||
}
|
||||
|
||||
// Prevent double submission
|
||||
form.addEventListener('submit', (e) => {
|
||||
if (isSubmitting) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
isSubmitting = true;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = '⏳ Menyimpan...';
|
||||
});
|
||||
|
||||
fotoInput.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
updateInitials();
|
||||
}
|
||||
});
|
||||
|
||||
function updateInitials() {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama) {
|
||||
const initials = nama.split(/\s+/)
|
||||
.slice(0, 2)
|
||||
.map(w => w.charAt(0).toUpperCase())
|
||||
.join('');
|
||||
photoInitial.textContent = initials || updatePhotoIcon();
|
||||
} else {
|
||||
photoInitial.textContent = updatePhotoIcon();
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger dari input nama
|
||||
namaInput.addEventListener('input', updateInitials);
|
||||
|
||||
// Trigger dari role selection
|
||||
roleStaffInput.addEventListener('change', updateInitials);
|
||||
roleTeknikInput.addEventListener('change', updateInitials);
|
||||
|
||||
// Inisialisasi saat halaman load
|
||||
window.addEventListener('load', () => {
|
||||
isSubmitting = false;
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = '✅ Simpan Staff/Teknisi';
|
||||
if (fotoInput.value.trim()) {
|
||||
fotoInput.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (namaInput.value.trim()) {
|
||||
namaInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views/staff/create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# <?php echo e($exception->class()); ?> - <?php echo $exception->title(); ?>
|
||||
|
||||
|
||||
<?php echo $exception->message(); ?>
|
||||
|
||||
|
||||
PHP <?php echo e(PHP_VERSION); ?>
|
||||
|
||||
Laravel <?php echo e(app()->version()); ?>
|
||||
|
||||
<?php echo e($exception->request()->httpHost()); ?>
|
||||
|
||||
|
||||
## Stack Trace
|
||||
|
||||
<?php $__currentLoopData = $exception->frames(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $frame): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($index); ?> - <?php echo e($frame->file()); ?>:<?php echo e($frame->line()); ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
<?php if($exception->previousExceptions()->isNotEmpty()): ?>
|
||||
## Previous <?php echo e(\Illuminate\Support\Str::plural('exception', $exception->previousExceptions()->count())); ?>
|
||||
|
||||
<?php $__currentLoopData = $exception->previousExceptions(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $previous): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
|
||||
### <?php echo e($index + 1); ?>. <?php echo e($previous->class()); ?>
|
||||
|
||||
|
||||
<?php echo $previous->message(); ?>
|
||||
|
||||
|
||||
<?php $__currentLoopData = $previous->frames(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $frame): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($index); ?> - <?php echo e($frame->file()); ?>:<?php echo e($frame->line()); ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
## Request
|
||||
|
||||
<?php echo e($exception->request()->method()); ?> <?php echo e(\Illuminate\Support\Str::start($exception->request()->path(), '/')); ?>
|
||||
|
||||
|
||||
## Headers
|
||||
|
||||
<?php $__empty_1 = true; $__currentLoopData = $exception->requestHeaders(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
* **<?php echo e($key); ?>**: <?php echo $value; ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
No header data available.
|
||||
<?php endif; ?>
|
||||
|
||||
## Route Context
|
||||
|
||||
<?php $__empty_1 = true; $__currentLoopData = $exception->applicationRouteContext(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $name => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<?php echo e($name); ?>: <?php echo $value; ?>
|
||||
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
No routing data available.
|
||||
<?php endif; ?>
|
||||
|
||||
## Route Parameters
|
||||
|
||||
<?php if($routeParametersContext = $exception->applicationRouteParametersContext()): ?>
|
||||
<?php echo $routeParametersContext; ?>
|
||||
|
||||
<?php else: ?>
|
||||
No route parameter data available.
|
||||
<?php endif; ?>
|
||||
|
||||
## Database Queries
|
||||
|
||||
<?php $__empty_1 = true; $__currentLoopData = $exception->applicationQueries(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as ['connectionName' => $connectionName, 'sql' => $sql, 'time' => $time]): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
* <?php echo e($connectionName); ?> - <?php echo $sql; ?> (<?php echo e($time); ?> ms)
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
No database queries detected.
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/markdown.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<div <?php echo e($attributes->merge(['class' => "h-0 w-full relative"])); ?>>
|
||||
<div class="absolute top-[-1px] left-0 right-0 bottom-0 border-t border-dashed border-neutral-300 dark:border-white/[9%]"></div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/separator.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['title', 'markdown']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['title', 'markdown']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<script>
|
||||
const markdown = <?php echo e(Illuminate\Support\Js::from($markdown)); ?>
|
||||
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex items-center justify-between"
|
||||
x-data="{
|
||||
copied: false,
|
||||
async copyToClipboard() {
|
||||
try {
|
||||
await window.copyToClipboard(markdown);
|
||||
this.copied = true;
|
||||
setTimeout(() => { this.copied = false }, 3000);
|
||||
} catch (err) {
|
||||
console.error('Failed to copy the markdown: ', err);
|
||||
}
|
||||
}
|
||||
}"
|
||||
>
|
||||
<div class="flex items-center gap-2 h-[56px]">
|
||||
<div class="w-[18px] h-[18px] flex items-center justify-center bg-rose-500 rounded-md">
|
||||
<svg width="2" height="10" class="text-white" viewBox="0 0 2 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.00006 6.3188C1.41416 6.3188 1.75006 5.98295 1.75006 5.56885V1.43115C1.75006 1.01705 1.41416 0.681152 1.00006 0.681152C0.585961 0.681152 0.250061 1.01705 0.250061 1.43115V5.56885C0.250061 5.98295 0.585961 6.3188 1.00006 6.3188Z" fill="currentColor" />
|
||||
<path d="M1.00006 9.41699C1.55235 9.41699 2.00007 8.96929 2.00007 8.41699C2.00007 7.86469 1.55235 7.41699 1.00006 7.41699C0.447781 7.41699 6.10352e-05 7.86469 6.10352e-05 8.41699C6.10352e-05 8.96929 0.447781 9.41699 1.00006 9.41699Z" fill="currentColor "/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="font-medium text-sm text-neutral-900 dark:text-white">
|
||||
<?php echo e($title); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
x-cloak
|
||||
class="<?php echo \Illuminate\Support\Arr::toCssClasses([
|
||||
"text-sm rounded-md border px-3 h-8 flex items-center gap-2 transition-colors duration-200 ease-in-out cursor-pointer shadow-xs",
|
||||
"text-neutral-600 dark:text-neutral-400 bg-white/5 border-neutral-200 hover:bg-neutral-100 dark:bg-white/5 dark:border-white/10 dark:hover:bg-white/10",
|
||||
]); ?>"
|
||||
@click="copyToClipboard()"
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal8894ff2e6e6bd543865d608162806b35 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal8894ff2e6e6bd543865d608162806b35 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.copy','data' => ['class' => 'w-3 h-3','xShow' => '!copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.copy'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3','x-show' => '!copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $attributes = $__attributesOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__attributesOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $component = $__componentOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__componentOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal394a4f59b8774713925fcf456ba90b57 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal394a4f59b8774713925fcf456ba90b57 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.check','data' => ['class' => 'w-3 h-3 text-emerald-500','xShow' => 'copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.check'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3 text-emerald-500','x-show' => 'copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $attributes = $__attributesOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__attributesOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $component = $__componentOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__componentOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
<span x-text="copied ? 'Copied to clipboard' : 'Copy as Markdown'"></span>
|
||||
</button>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\topbar.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M4.75 1L0.75 5L4.75 9" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.25 1L5.25 5L9.25 9" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/chevrons-left.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 541 B |
|
|
@ -0,0 +1,623 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CRUD Dosen - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 12px 14px;
|
||||
font-size: 0.9rem;
|
||||
color: #475569;
|
||||
background: #f8fafc;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.12);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border-radius: 50%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 18px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.92rem; }
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 7px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
}
|
||||
|
||||
.pill.dosen { background: linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); }
|
||||
.pill.teknisi { background: linear-gradient(135deg, var(--green), #14b8a6); }
|
||||
.pill.staff { background: linear-gradient(135deg, var(--orange), var(--orange)); }
|
||||
|
||||
.row-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 9px 12px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn-sm:hover { transform: translateY(-2px); }
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 8px 16px rgba(16, 185, 129, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 8px 16px rgba(59, 130, 246, 0.18);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 8px 16px rgba(239, 68, 68, 0.18);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.pager { display: inline-flex; gap: 8px; }
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
?>
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="<?php echo e(route('users.index')); ?>"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="<?php echo e(route('users.dosen')); ?>" class="active"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="<?php echo e(route('users.staff')); ?>"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="<?php echo e(url('/dashboard')); ?>">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>CRUD Dosen</h1>
|
||||
<p>Kelola data dosen JTI</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn-sm success" href="<?php echo e(route('dosen.create')); ?>">Tambah Dosen</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Dosen</h2>
|
||||
<p>Kelola data dosen dengan fitur pencarian dan filter.</p>
|
||||
</div>
|
||||
<div class="meta">Total: <?php echo e($dosenCount); ?></div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="<?php echo e(route('users.dosen')); ?>">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for="q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="<?php echo e($q); ?>" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
<?php $__currentLoopData = ['10','25','50','100','all']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $size): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($size); ?>" <?php if($perPage === $size): echo 'selected'; endif; ?>>
|
||||
<?php echo e($size === 'all' ? 'Semua' : $size); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="<?php echo e(route('users.dosen')); ?>">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="notice"><?php echo e(session('success')); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 70px;">Foto</th>
|
||||
<th>Nama</th>
|
||||
<th style="width: 180px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 190px;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__empty_1 = true; $__currentLoopData = $dosen; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php ($fotoUrl = $resolveFoto($item->foto)); ?>
|
||||
<div class="avatar" <?php if($fotoUrl): ?> style="background-image: url('<?php echo e($fotoUrl); ?>')" <?php endif; ?>>
|
||||
<?php if(!$fotoUrl): ?>
|
||||
<div class="avatar-placeholder"><?php echo e($makeInitial($item->nama)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900;"><?php echo e($item->nama); ?></div>
|
||||
<div class="meta">ID: <?php echo e($item->id); ?></div>
|
||||
</td>
|
||||
<td><?php echo e($item->nip ?? '-'); ?></td>
|
||||
<td><?php echo e($item->nidn ?? '-'); ?></td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
<a class="btn-sm primary" href="<?php echo e(route('dosen.edit', $item)); ?>">Edit</a>
|
||||
|
||||
<form method="POST" action="<?php echo e(route('dosen.destroy', $item)); ?>" onsubmit="return confirm('Hapus dosen ini?')" style="display:inline;">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button class="btn-sm danger" type="submit">Hapus</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<tr>
|
||||
<td colspan="5" class="meta">Belum ada data dosen.</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan <?php echo e($dosen->firstItem() ?? 0); ?>–<?php echo e($dosen->lastItem() ?? 0); ?> dari <?php echo e($dosenCount); ?>
|
||||
|
||||
</div>
|
||||
<div class="pager">
|
||||
<?php if($dosen->onFirstPage()): ?>
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
<?php else: ?>
|
||||
<a class="btn-sm ghost" href="<?php echo e($dosen->previousPageUrl()); ?>">Sebelumnya</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($dosen->hasMorePages()): ?>
|
||||
<a class="btn-sm ghost" href="<?php echo e($dosen->nextPageUrl()); ?>">Berikutnya</a>
|
||||
<?php else: ?>
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views/Dosen/dosen.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,263 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Edit Dosen - JTI</title>
|
||||
<style>
|
||||
:root { --primary: #4f46e5; --success: #10b981; --orange: #d97706; --text: #1f2937; --muted: #6b7280; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: 'Segoe UI', sans-serif; background: linear-gradient(135deg, #e0e7ff 0%, #eef2ff 100%); min-height: 100vh; color: var(--text); }
|
||||
.container { max-width: 900px; margin: 20px auto; padding: 0 16px; }
|
||||
.header { display: flex; justify-content: space-between; align-items: center; padding: 16px; background: white; border-radius: 16px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
|
||||
.header h1 { font-size: 20px; font-weight: 900; }
|
||||
.btn { padding: 10px 16px; border-radius: 8px; border: none; cursor: pointer; font-weight: 700; text-decoration: none; display: inline-block; transition: all 0.2s; }
|
||||
.btn:hover { transform: translateY(-2px); }
|
||||
.btn-ghost { background: #e2e8f0; color: #334155; }
|
||||
.btn-success { background: var(--success); color: white; }
|
||||
.card { background: white; border-radius: 16px; padding: 32px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
|
||||
.form-layout { display: grid; grid-template-columns: 280px 1fr; gap: 40px; }
|
||||
.photo-box { text-align: center; }
|
||||
.photo-preview { width: 100%; aspect-ratio: 3/4; background: linear-gradient(135deg, var(--primary), #7c3aed); border-radius: 16px; display: flex; align-items: center; justify-content: center; color: white; font-size: 48px; font-weight: 900; margin-bottom: 16px; overflow: hidden; position: relative; }
|
||||
.photo-preview img { width: 100%; height: 100%; object-fit: cover; position: absolute; }
|
||||
.photo-initial { position: relative; z-index: 1; }
|
||||
.file-input { display: none; }
|
||||
.file-label { display: block; padding: 12px; border: 2px dashed var(--primary); border-radius: 12px; cursor: pointer; color: var(--primary); font-weight: 700; margin-bottom: 12px; transition: all 0.2s; }
|
||||
.file-label:hover { background: rgba(79, 70, 229, 0.05); border-color: #7c3aed; }
|
||||
.form-group { margin-bottom: 24px; }
|
||||
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
|
||||
.form-row.full { grid-column: 1 / -1; }
|
||||
label { display: block; margin-bottom: 8px; font-weight: 700; color: #475569; font-size: 14px; }
|
||||
.required { color: var(--orange); }
|
||||
input, select { width: 100%; padding: 12px; border: 1.5px solid #cbd5e1; border-radius: 10px; font-size: 14px; font-family: inherit; }
|
||||
input:focus, select:focus { outline: none; border-color: var(--primary); background: rgba(79, 70, 229, 0.02); box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); }
|
||||
input.error, select.error { border-color: #ef4444; background: rgba(239, 68, 68, 0.02); }
|
||||
.error-text { color: #dc2626; font-size: 12px; margin-top: 4px; }
|
||||
.hint-text { color: #6b7280; font-size: 12px; margin-top: 4px; }
|
||||
.error-alert { background: #fee2e2; border: 1px solid #fecaca; border-radius: 12px; padding: 16px; margin-bottom: 20px; }
|
||||
.error-alert strong { color: #7f1d1d; display: block; margin-bottom: 8px; font-weight: 800; }
|
||||
.error-alert ul { list-style: none; padding-left: 20px; color: #b91c1c; }
|
||||
.error-alert li { margin-bottom: 4px; }
|
||||
.form-actions { display: flex; gap: 12px; margin-top: 40px; border-top: 1px solid #e2e8f0; padding-top: 24px; }
|
||||
.form-actions button, .form-actions a { flex: 1; padding: 12px; border-radius: 8px; border: none; font-weight: 700; cursor: pointer; text-align: center; transition: all 0.2s; }
|
||||
.form-actions button:disabled { opacity: 0.6; cursor: not-allowed; }
|
||||
@media (max-width: 800px) {
|
||||
.form-layout { grid-template-columns: 1fr; }
|
||||
.form-row { grid-template-columns: 1fr; }
|
||||
.header { flex-direction: column; gap: 12px; align-items: flex-start; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return '👨🏫';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : '👨🏫';
|
||||
};
|
||||
?>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>✏️ Edit Dosen</h1>
|
||||
<a href="<?php echo e(route('users.dosen')); ?>" class="btn btn-ghost">Kembali</a>
|
||||
</div>
|
||||
<div class="card">
|
||||
<?php if($errors->any()): ?>
|
||||
<div class="error-alert">
|
||||
<strong>❌ Validasi gagal:</strong>
|
||||
<ul>
|
||||
<?php $__currentLoopData = $errors->all(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $error): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<li><?php echo e($error); ?></li>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<form method="POST" action="<?php echo e(route('dosen.update', $user)); ?>" id="editForm" class="form-layout">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('PUT'); ?>
|
||||
<div class="photo-box">
|
||||
<div class="photo-preview" id="photoPreview">
|
||||
<span id="photoInitial"><?php echo e($makeInitial($user->nama)); ?></span>
|
||||
<img id="photoImg" style="display: none;" alt="Foto Dosen" />
|
||||
</div>
|
||||
<label for="photoFile" class="file-label">📤 Ubah Foto</label>
|
||||
<input id="photoFile" type="file" accept="image/*" class="file-input">
|
||||
<input id="fotoUrl" type="text" name="foto" value="<?php echo e(old('foto', $user->foto)); ?>" placeholder="atau URL foto">
|
||||
<div class="hint-text">URL gambar untuk profil</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="form-row full">
|
||||
<div class="form-group">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input id="nama" type="text" name="nama" value="<?php echo e(old('nama', $user->nama)); ?>" required class="<?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>">
|
||||
<?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?><div class="error-text"><?php echo e($message); ?></div><?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint-text">Nama lengkap dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="nip">NIP</label>
|
||||
<input id="nip" type="text" name="nip" value="<?php echo e(old('nip', $user->nip)); ?>" placeholder="19850315 200901 1 001" class="<?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>">
|
||||
<?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?><div class="error-text"><?php echo e($message); ?></div><?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint-text">Nomor Induk Pegawai</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="nidn">NIDN</label>
|
||||
<input id="nidn" type="text" name="nidn" value="<?php echo e(old('nidn', $user->nidn)); ?>" placeholder="0017058003" class="<?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>">
|
||||
<?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?><div class="error-text"><?php echo e($message); ?></div><?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint-text">Nomor Induk Dosen Nasional</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row full">
|
||||
<div class="form-group">
|
||||
<label for="prodi">Program Studi <span class="required">*</span></label>
|
||||
<select id="prodi" name="prodi" required class="<?php $__errorArgs = ['prodi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>">
|
||||
<option value="">-- Pilih Program Studi --</option>
|
||||
<option value="Manajemen Informatika" <?php if(old('prodi', $user->prodi) === 'Manajemen Informatika'): echo 'selected'; endif; ?>>Manajemen Informatika</option>
|
||||
<option value="Teknik Informatika" <?php if(old('prodi', $user->prodi) === 'Teknik Informatika'): echo 'selected'; endif; ?>>Teknik Informatika</option>
|
||||
<option value="Teknik Komputer" <?php if(old('prodi', $user->prodi) === 'Teknik Komputer'): echo 'selected'; endif; ?>>Teknik Komputer</option>
|
||||
<option value="Teknologi Rekayasa Komputer" <?php if(old('prodi', $user->prodi) === 'Teknologi Rekayasa Komputer'): echo 'selected'; endif; ?>>Teknologi Rekayasa Komputer</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['prodi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?><div class="error-text"><?php echo e($message); ?></div><?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint-text">Program studi dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="role" value="dosen">
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-success" id="submitBtn">💾 Simpan Perubahan</button>
|
||||
<a href="<?php echo e(route('users.dosen')); ?>" class="btn btn-ghost">❌ Batal</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const photoFile = document.getElementById('photoFile');
|
||||
const fotoUrl = document.getElementById('fotoUrl');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const editForm = document.getElementById('editForm');
|
||||
const submitBtn = document.getElementById('submitBtn');
|
||||
let isSubmitting = false;
|
||||
|
||||
editForm.addEventListener('submit', function(e) {
|
||||
if (isSubmitting) { e.preventDefault(); return false; }
|
||||
isSubmitting = true;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = '⏳ Menyimpan...';
|
||||
});
|
||||
|
||||
photoFile.addEventListener('change', (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
photoImg.src = event.target.result;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
fotoUrl.value = event.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
|
||||
fotoUrl.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
namaInput.addEventListener('input', () => {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama && !photoImg.src) {
|
||||
const words = nama.split(/\s+/);
|
||||
const initials = words.slice(0, 2).map(w => w.charAt(0).toUpperCase()).join('');
|
||||
photoInitial.textContent = initials || '👨🏫';
|
||||
photoInitial.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
isSubmitting = false;
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = '💾 Simpan Perubahan';
|
||||
if (fotoUrl.value.trim()) {
|
||||
fotoUrl.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (namaInput.value.trim()) {
|
||||
namaInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html><?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views\Dosen\edit.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<g clip-path="url(#clip0_14732_6105)">
|
||||
<path d="M9.87466 7.8287L5.92654 0.549947C5.82917 0.369362 5.68068 0.221523 5.49966 0.124947C5.25374 -0.00665839 4.9658 -0.0358401 4.69847 0.0437494C4.43115 0.123339 4.20606 0.305262 4.07216 0.549947L0.124664 7.8287C0.0383472 7.98887 -0.00481098 8.16875 -0.000569449 8.35066C0.00367208 8.53256 0.0551674 8.71024 0.148856 8.86622C0.242546 9.0222 0.375205 9.15112 0.533798 9.24031C0.692391 9.32951 0.871462 9.37591 1.05341 9.37495H8.94591C9.12031 9.37495 9.29203 9.33202 9.44591 9.24995C9.56783 9.18524 9.67572 9.09703 9.76338 8.99041C9.85104 8.8838 9.91672 8.76088 9.95663 8.62876C9.99655 8.49663 10.0099 8.35791 9.99595 8.22059C9.98199 8.08328 9.94036 7.95009 9.87466 7.8287ZM4.99966 8.12495C4.87605 8.12495 4.75521 8.08829 4.65243 8.01962C4.54965 7.95094 4.46954 7.85333 4.42224 7.73912C4.37493 7.62492 4.36256 7.49925 4.38667 7.37802C4.41079 7.25678 4.47031 7.14541 4.55772 7.05801C4.64513 6.9706 4.75649 6.91107 4.87773 6.88696C4.99897 6.86284 5.12464 6.87522 5.23884 6.92252C5.35304 6.96983 5.45066 7.04993 5.51933 7.15272C5.58801 7.2555 5.62466 7.37633 5.62466 7.49995C5.62466 7.66571 5.55882 7.82468 5.44161 7.94189C5.3244 8.0591 5.16542 8.12495 4.99966 8.12495ZM5.62466 5.93745C5.62466 6.02033 5.59174 6.09981 5.53313 6.15842C5.47453 6.21702 5.39504 6.24995 5.31216 6.24995H4.68716C4.60428 6.24995 4.5248 6.21702 4.46619 6.15842C4.40759 6.09981 4.37466 6.02033 4.37466 5.93745V3.43745C4.37466 3.35457 4.40759 3.27508 4.46619 3.21648C4.5248 3.15787 4.60428 3.12495 4.68716 3.12495H5.31216C5.39504 3.12495 5.47453 3.15787 5.53313 3.21648C5.59174 3.27508 5.62466 3.35457 5.62466 3.43745V5.93745Z" fill="currentColor" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_14732_6105">
|
||||
<rect width="10" height="10" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\alert.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -0,0 +1,865 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kelola Users - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 16px 18px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 16px 18px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 900;
|
||||
color: #475569;
|
||||
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
||||
border-bottom: 2px solid rgba(148, 163, 184, 0.2);
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
transition: all 0.3s ease;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
background: rgba(79, 70, 229, 0.04);
|
||||
box-shadow: inset 0 0 12px rgba(79, 70, 229, 0.08);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background: rgba(248, 250, 252, 0.5);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even):hover {
|
||||
background: rgba(79, 70, 229, 0.06);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 14px 18px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 14px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 24px rgba(79, 70, 229, 0.28);
|
||||
border: 2.5px solid rgba(255, 255, 255, 0.35);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 1.25rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
tbody tr:hover .avatar {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 14px 32px rgba(79, 70, 229, 0.35);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.85rem; margin-top: 6px; letter-spacing: 0.3px; }
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 8px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.22);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.pill:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.pill.dosen {
|
||||
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
|
||||
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.22);
|
||||
}
|
||||
|
||||
.pill.dosen:hover {
|
||||
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.28);
|
||||
}
|
||||
|
||||
.pill.teknisi {
|
||||
background: linear-gradient(135deg, #10b981 0%, #14b8a6 100%);
|
||||
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.22);
|
||||
}
|
||||
|
||||
.pill.teknisi:hover {
|
||||
box-shadow: 0 6px 16px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.pill.staff {
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #f97316 100%);
|
||||
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.22);
|
||||
}
|
||||
|
||||
.pill.staff:hover {
|
||||
box-shadow: 0 6px 16px rgba(245, 158, 11, 0.28);
|
||||
}
|
||||
|
||||
.row-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
padding: 10px 14px;
|
||||
font-weight: 900;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 0.3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.btn-sm:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.btn-sm:active {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.3);
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.btn-sm.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
border-color: rgba(99, 102, 241, 0.5);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 6px 16px rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.success:hover {
|
||||
box-shadow: 0 8px 24px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.warning {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
|
||||
box-shadow: 0 6px 16px rgba(245, 158, 11, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.warning:hover {
|
||||
box-shadow: 0 8px 24px rgba(245, 158, 11, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 6px 16px rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.primary:hover {
|
||||
box-shadow: 0 8px 24px rgba(59, 130, 246, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 6px 16px rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.danger:hover {
|
||||
box-shadow: 0 8px 24px rgba(239, 68, 68, 0.28);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.12);
|
||||
}
|
||||
|
||||
.pager {
|
||||
display: inline-flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
|
||||
.welcome-section {
|
||||
padding: 32px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.08) 0%, rgba(124, 58, 237, 0.06) 100%);
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.15);
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 24px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.welcome-text h3 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 900;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.welcome-text p {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 14px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.welcome-stats {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(148, 163, 184, 0.12);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.15), rgba(124, 58, 237, 0.1));
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 900;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.75rem;
|
||||
color: var(--muted);
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 5rem;
|
||||
opacity: 0.15;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
?>
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="<?php echo e(route('users.index')); ?>" class="active"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="<?php echo e(route('users.dosen')); ?>"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="<?php echo e(route('users.staff')); ?>"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="<?php echo e(url('/dashboard')); ?>">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>Kelola Users</h1>
|
||||
<p>Lihat semua data dosen, staff dan teknisi</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions"></div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Users</h2>
|
||||
<p>Gunakan filter untuk mencari dan batasi jumlah data.</p>
|
||||
</div>
|
||||
<div class="meta">Total: <?php echo e($totalCount ?? 0); ?></div>
|
||||
</div>
|
||||
|
||||
<div class="welcome-section">
|
||||
<div class="welcome-content">
|
||||
<div class="welcome-text">
|
||||
<h3>🎉 Selamat Datang di Admin Panel</h3>
|
||||
<p>Kelola semua data dosen, staff, dan teknisi dengan mudah. Cari, filter, dan kelola informasi pengguna dalam satu tempat yang terintegrasi.</p>
|
||||
</div>
|
||||
<div class="welcome-icon">👥</div>
|
||||
</div>
|
||||
<div class="welcome-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">👨🏫</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number"><?php echo e($totalCount); ?></span>
|
||||
<span class="stat-label">Total Users</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">📊</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number">3</span>
|
||||
<span class="stat-label">Kategori</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">⚙️</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number">∞</span>
|
||||
<span class="stat-label">Fitur</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="<?php echo e(route('users.index')); ?>">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for=" q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="<?php echo e($q); ?>" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="role">Role</label>
|
||||
<select id="role" class="select" name="role">
|
||||
<option value="">Semua</option>
|
||||
<?php $__currentLoopData = $roleOptions; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $opt): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($opt); ?>" <?php if($role === $opt): echo 'selected'; endif; ?>><?php echo e(ucfirst($opt)); ?></option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
<?php $__currentLoopData = ['10','25','50','100','all']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $size): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($size); ?>" <?php if($perPage === $size): echo 'selected'; endif; ?>>
|
||||
<?php echo e($size === 'all' ? 'Semua' : $size); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="<?php echo e(route('users.index')); ?>">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="notice"><?php echo e(session('success')); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 80px;">Foto</th>
|
||||
<th style="flex: 1; min-width: 280px;">Nama</th>
|
||||
<th style="width: 160px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 110px;">Role</th>
|
||||
<th style="width: 160px;">Waktu Input</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__empty_1 = true; $__currentLoopData = $users; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php ($fotoUrl = $resolveFoto($item->foto)); ?>
|
||||
<div class="avatar" <?php if($fotoUrl): ?> style="background-image: url('<?php echo e($fotoUrl); ?>')" <?php endif; ?>>
|
||||
<?php if(!$fotoUrl): ?>
|
||||
<div class="avatar-placeholder"><?php echo e($makeInitial($item->nama)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900; font-size: 1.05rem; color: #1f2937; line-height: 1.4;"><?php echo e($item->nama); ?></div>
|
||||
<div class="meta" style="font-size: 0.8rem;">ID: <?php echo e($item->id); ?></div>
|
||||
</td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #475569;"><?php echo e($item->nip ?? '-'); ?></td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #475569;"><?php echo e($item->nidn ?? '-'); ?></td>
|
||||
<td>
|
||||
<?php ($r = (string) ($item->role ?? 'staff')); ?>
|
||||
<?php ($r = in_array($r, ['dosen', 'teknisi', 'staff'], true) ? $r : 'staff'); ?>
|
||||
<span class="pill <?php echo e($r); ?>"><?php echo e(ucfirst($r)); ?></span>
|
||||
</td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #6b7280; font-size: 0.95rem;">
|
||||
<?php echo e($item->created_at ? $item->created_at->format('d M Y H:i') : '-'); ?>
|
||||
|
||||
<div class="meta" style="font-size: 0.75rem; margin-top: 4px;"><?php echo e($item->created_at ? $item->created_at->diffForHumans() : '-'); ?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<tr>
|
||||
<td colspan="6" style="text-align: center; padding: 48px 18px;">
|
||||
<div style="color: var(--muted); font-size: 1.1rem; font-weight: 700;">📭 Belum ada data</div>
|
||||
<div style="color: #9ca3af; font-size: 0.9rem; margin-top: 8px;">Coba ubah filter atau tambahkan data baru untuk memulai</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan <?php echo e($users->firstItem() ?? 0); ?>–<?php echo e($users->lastItem() ?? 0); ?> dari <?php echo e($totalCount ?? 0); ?>
|
||||
|
||||
</div>
|
||||
<div class="pager">
|
||||
<?php if($users->currentPage() == 1): ?>
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
<?php else: ?>
|
||||
<a class="btn-sm ghost" href="<?php echo e($users->previousPageUrl()); ?>">Sebelumnya</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($users->lastPage() > $users->currentPage()): ?>
|
||||
<a class="btn-sm ghost" href="<?php echo e($users->nextPageUrl()); ?>">Berikutnya</a>
|
||||
<?php else: ?>
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views\user\index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M2.75 2.75H5.614L5.316 2.114C5.069 1.587 4.54 1.25 3.958 1.25H2.25C1.422 1.25 0.75 1.922 0.75 2.75V4.75C0.75 3.645 1.645 2.75 2.75 2.75Z" />
|
||||
<path d="M0.75 4.75V2.75C0.75 1.922 1.422 1.25 2.25 1.25H3.958C4.54 1.25 5.069 1.587 5.316 2.114L5.614 2.75" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.75 2.75H9.25C10.355 2.75 11.25 3.645 11.25 4.75V8.25C11.25 9.355 10.355 10.25 9.25 10.25H2.75C1.645 10.25 0.75 9.355 0.75 8.25V4.75C0.75 3.645 1.645 2.75 2.75 2.75Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\folder.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 898 B |
|
|
@ -0,0 +1,167 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['exception', 'request']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['exception', 'request']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div
|
||||
x-data="{
|
||||
copied: false,
|
||||
async copyToClipboard() {
|
||||
try {
|
||||
await window.copyToClipboard('<?php echo e($request->fullUrl()); ?>');
|
||||
this.copied = true;
|
||||
setTimeout(() => { this.copied = false }, 3000);
|
||||
} catch (err) {
|
||||
console.error('Failed to copy the requestURL: ', err);
|
||||
}
|
||||
}
|
||||
}"
|
||||
<?php echo e($attributes->merge(['class' => "bg-white dark:bg-[#1a1a1a] border border-neutral-200 dark:border-white/10 rounded-lg flex items-center justify-between h-10 px-2 shadow-xs"])); ?>
|
||||
|
||||
>
|
||||
<div class="flex items-center gap-3 w-full">
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => 'error','variant' => 'solid']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => 'error','variant' => 'solid']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalebc8ec9a834a8051f56913d6745a7050 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalebc8ec9a834a8051f56913d6745a7050 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.alert','data' => ['class' => 'w-2.5 h-2.5']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.alert'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $attributes = $__attributesOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $component = $__componentOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__componentOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo e($exception->httpStatusCode()); ?>
|
||||
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.http-method','data' => ['method' => ''.e($request->method()).'']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::http-method'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['method' => ''.e($request->method()).'']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413)): ?>
|
||||
<?php $attributes = $__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413; ?>
|
||||
<?php unset($__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413)): ?>
|
||||
<?php $component = $__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413; ?>
|
||||
<?php unset($__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413); ?>
|
||||
<?php endif; ?>
|
||||
<div class="flex-1 text-sm font-light truncate text-neutral-950 dark:text-white">
|
||||
<span data-tippy-content="<?php echo e($request->fullUrl()); ?>">
|
||||
<?php echo e($request->fullUrl()); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
x-cloak
|
||||
@click="copyToClipboard()"
|
||||
class="<?php echo \Illuminate\Support\Arr::toCssClasses([
|
||||
"rounded-md w-6 h-6 flex flex-shrink-0 items-center justify-center cursor-pointer border transition-colors duration-200 ease-in-out",
|
||||
"bg-white/5 border-neutral-200 hover:bg-neutral-100 dark:bg-white/5 dark:border-white/10 dark:hover:bg-white/10",
|
||||
]); ?>"
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal8894ff2e6e6bd543865d608162806b35 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal8894ff2e6e6bd543865d608162806b35 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.copy','data' => ['class' => 'w-3 h-3 text-neutral-400','xShow' => '!copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.copy'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3 text-neutral-400','x-show' => '!copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $attributes = $__attributesOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__attributesOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $component = $__componentOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__componentOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal394a4f59b8774713925fcf456ba90b57 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal394a4f59b8774713925fcf456ba90b57 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.check','data' => ['class' => 'w-3 h-3 text-emerald-500','xShow' => 'copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.check'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3 text-emerald-500','x-show' => 'copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $attributes = $__attributesOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__attributesOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $component = $__componentOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__componentOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\request-url.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,694 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>JTI Monitoring - Politeknik Negeri Jember</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 {
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.1;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.brand-text p {
|
||||
margin-top: 2px;
|
||||
color: var(--muted);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.role-switch {
|
||||
display: inline-flex;
|
||||
gap: 8px;
|
||||
padding: 6px;
|
||||
border-radius: 999px;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.role-switch button {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 18px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
|
||||
color: #475569;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.role-switch button:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.role-switch button.active {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 20px rgba(79, 70, 229, 0.22);
|
||||
}
|
||||
|
||||
.hero {
|
||||
margin-top: 18px;
|
||||
border-radius: 28px;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.96) 0%, rgba(124, 58, 237, 0.9) 100%);
|
||||
color: white;
|
||||
box-shadow: var(--shadow);
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
.hero::before,
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: auto;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.14);
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
.hero::before {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
top: -110px;
|
||||
right: -70px;
|
||||
}
|
||||
|
||||
.hero::after {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
bottom: -80px;
|
||||
left: -40px;
|
||||
}
|
||||
|
||||
.hero-inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 42px 32px 38px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero-kicker {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 7px 14px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.hero h2 {
|
||||
margin-top: 18px;
|
||||
font-size: clamp(2rem, 4vw, 3.5rem);
|
||||
line-height: 1.05;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
margin-top: 12px;
|
||||
font-size: 1.05rem;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 18px;
|
||||
border-radius: 28px;
|
||||
background: var(--panel);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h3 {
|
||||
font-size: 1.45rem;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.section-head span {
|
||||
color: var(--muted);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.role-pane {
|
||||
display: none;
|
||||
padding: 26px;
|
||||
animation: fadeIn 0.35s ease;
|
||||
}
|
||||
|
||||
.role-pane.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.prodi-groups {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.prodi-group {
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.prodi-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed rgba(148, 163, 184, 0.35);
|
||||
}
|
||||
|
||||
.prodi-title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.prodi-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 999px;
|
||||
padding: 6px 10px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary), var(--primary-2));
|
||||
}
|
||||
|
||||
.bagian-groups {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.bagian-group {
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.bagian-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dashed rgba(148, 163, 184, 0.35);
|
||||
}
|
||||
|
||||
.bagian-title {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 800;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.bagian-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-radius: 999px;
|
||||
padding: 6px 10px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--green), #14b8a6);
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 24px;
|
||||
padding: 22px;
|
||||
background: var(--panel-strong);
|
||||
border: 1px solid rgba(148, 163, 184, 0.16);
|
||||
box-shadow: 0 14px 34px rgba(15, 23, 42, 0.08);
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0 auto auto 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, var(--primary), var(--primary-2));
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
border-radius: 50%;
|
||||
flex: 0 0 auto;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
background-image: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 26px rgba(79, 70, 229, 0.28);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar.teknisi {
|
||||
background-image: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
box-shadow: 0 12px 26px rgba(5, 150, 105, 0.25);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.avatar.teknisi .avatar-placeholder {
|
||||
background-image: linear-gradient(135deg, #059669 0%, #10b981 100%);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.35;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.card-meta {
|
||||
margin-top: 8px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.88rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card-meta.dosen {
|
||||
background: linear-gradient(135deg, var(--primary), var(--primary-2));
|
||||
}
|
||||
|
||||
.card-meta.teknisi {
|
||||
background: linear-gradient(135deg, var(--green), #14b8a6);
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
margin-top: 16px;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.detail {
|
||||
display: grid;
|
||||
grid-template-columns: 84px 1fr;
|
||||
gap: 12px;
|
||||
align-items: start;
|
||||
padding: 11px 14px;
|
||||
border-radius: 14px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: #64748b;
|
||||
font-weight: 700;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
color: var(--text);
|
||||
font-weight: 600;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
margin-top: 18px;
|
||||
padding: 24px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px dashed rgba(100, 116, 139, 0.3);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.footer-note {
|
||||
padding: 0 26px 26px;
|
||||
color: var(--muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.topbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.role-switch {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cards {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.page-shell {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.hero-inner,
|
||||
.role-pane,
|
||||
.section-head,
|
||||
.footer-note {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.detail {
|
||||
grid-template-columns: 1fr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 0.84rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-shell">
|
||||
<header class="topbar">
|
||||
<a class="brand" href="/">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>Politeknik Negeri Jember</h1>
|
||||
<p>Dashboard data dosen dan teknisi</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="role-switch" aria-label="Pilih role tampilan">
|
||||
<button id="btnDosen" class="active" type="button" onclick="showRole('dosen')">Dosen</button>
|
||||
<button id="btnTeknisi" type="button" onclick="showRole('teknisi')">Teknisi</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-inner">
|
||||
<div class="hero-kicker">Jurusan Teknologi Informasi</div>
|
||||
<h2 id="heroTitle">Dosen JTI</h2>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h3 id="sectionTitle">Program Studi Dosen</h3>
|
||||
<span id="sectionDesc">Daftar dosen aktif berdasarkan program studi.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$makeInitial = static function (string $nama): string {
|
||||
$parts = preg_split('/\s+/', trim($nama)) ?: [];
|
||||
$initials = '';
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
|
||||
if (strlen($initials) >= 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
?>
|
||||
|
||||
<section id="dosenPane" class="role-pane active">
|
||||
<?php
|
||||
$dosenByProdi = $dosen
|
||||
->sortBy([['prodi', 'asc'], ['nama', 'asc']])
|
||||
->groupBy(function ($item) {
|
||||
$prodi = trim((string) ($item->prodi ?? ''));
|
||||
return $prodi !== '' ? $prodi : 'Prodi Belum Ditentukan';
|
||||
});
|
||||
?>
|
||||
|
||||
<?php if($dosenByProdi->isEmpty()): ?>
|
||||
<div class="empty-state">Belum ada data dosen di database.</div>
|
||||
<?php else: ?>
|
||||
<div class="prodi-groups">
|
||||
<?php $__currentLoopData = $dosenByProdi; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $prodiName => $prodiItems): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<section class="prodi-group">
|
||||
<header class="prodi-head">
|
||||
<h4 class="prodi-title"><?php echo e($prodiName); ?></h4>
|
||||
<span class="prodi-count"><?php echo e($prodiItems->count()); ?> Dosen</span>
|
||||
</header>
|
||||
|
||||
<div class="cards">
|
||||
<?php $__currentLoopData = $prodiItems; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<article class="card">
|
||||
<?php
|
||||
$fotoUrl = $resolveFoto($item->foto);
|
||||
?>
|
||||
<div class="avatar" <?php if($fotoUrl): ?> style="background-image: url('<?php echo e($fotoUrl); ?>')" <?php endif; ?>>
|
||||
<?php if(!$fotoUrl): ?>
|
||||
<div class="avatar-placeholder"><?php echo e($makeInitial($item->nama)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-title"><?php echo e($item->nama); ?></div>
|
||||
<div class="card-meta dosen">Dosen</div>
|
||||
<div class="detail-list">
|
||||
<div class="detail"><div class="detail-label">NIP</div><div class="detail-value"><?php echo e($item->nip ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">NIDN</div><div class="detail-value"><?php echo e($item->nidn ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">Lokasi</div><div class="detail-value">Gedung JTI Lt. 1</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<section id="teknisiPane" class="role-pane">
|
||||
<?php
|
||||
$teknisiByBagian = $teknisi
|
||||
->sortBy([['bagian', 'asc'], ['nama', 'asc']])
|
||||
->groupBy(function ($item) {
|
||||
$bagian = trim((string) ($item->bagian ?? ''));
|
||||
return $bagian !== '' ? $bagian : 'Bagian Belum Ditentukan';
|
||||
});
|
||||
?>
|
||||
|
||||
<?php if($teknisiByBagian->isEmpty()): ?>
|
||||
<div class="empty-state">Belum ada data teknisi/staff di database.</div>
|
||||
<?php else: ?>
|
||||
<div class="bagian-groups">
|
||||
<?php $__currentLoopData = $teknisiByBagian; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $bagianName => $bagianItems): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<section class="bagian-group">
|
||||
<header class="bagian-head">
|
||||
<h4 class="bagian-title"><?php echo e($bagianName); ?></h4>
|
||||
<span class="bagian-count"><?php echo e($bagianItems->count()); ?> Orang</span>
|
||||
</header>
|
||||
|
||||
<div class="cards">
|
||||
<?php $__currentLoopData = $bagianItems; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<article class="card">
|
||||
<?php
|
||||
$fotoUrl = $resolveFoto($item->foto);
|
||||
?>
|
||||
<div class="avatar teknisi" <?php if($fotoUrl): ?> style="background-image: url('<?php echo e($fotoUrl); ?>')" <?php endif; ?>>
|
||||
<?php if(!$fotoUrl): ?>
|
||||
<div class="avatar-placeholder"><?php echo e($makeInitial($item->nama)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-title"><?php echo e($item->nama); ?></div>
|
||||
<div class="card-meta teknisi"><?php echo e(ucfirst($item->role ?? 'staff')); ?></div>
|
||||
<div class="detail-list">
|
||||
<div class="detail"><div class="detail-label">NIP</div><div class="detail-value"><?php echo e($item->nip ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">NIDN</div><div class="detail-value"><?php echo e($item->nidn ?? '-'); ?></div></div>
|
||||
<div class="detail"><div class="detail-label">Lokasi</div><div class="detail-value">Gedung JTI Lt. 1</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<div class="footer-note">
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showRole(role) {
|
||||
const dosenPane = document.getElementById('dosenPane');
|
||||
const teknisiPane = document.getElementById('teknisiPane');
|
||||
const btnDosen = document.getElementById('btnDosen');
|
||||
const btnTeknisi = document.getElementById('btnTeknisi');
|
||||
const heroTitle = document.getElementById('heroTitle');
|
||||
const sectionTitle = document.getElementById('sectionTitle');
|
||||
const sectionDesc = document.getElementById('sectionDesc');
|
||||
|
||||
const isDosen = role === 'dosen';
|
||||
|
||||
dosenPane.classList.toggle('active', isDosen);
|
||||
teknisiPane.classList.toggle('active', !isDosen);
|
||||
btnDosen.classList.toggle('active', isDosen);
|
||||
btnTeknisi.classList.toggle('active', !isDosen);
|
||||
|
||||
heroTitle.textContent = isDosen ? 'Dosen JTI' : 'Teknisi JTI';
|
||||
sectionTitle.textContent = isDosen ? 'Program Studi Dosen' : 'Teknisi dan Staff';
|
||||
sectionDesc.textContent = isDosen
|
||||
? 'Daftar dosen aktif berdasarkan program studi.'
|
||||
: 'Daftar teknisi dan staff aktif berdasarkan bagian.';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views/dashboard.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php $__env->startSection('title', __('Not Found')); ?>
|
||||
<?php $__env->startSection('code', '404'); ?>
|
||||
<?php $__env->startSection('message', __('Not Found')); ?>
|
||||
|
||||
<?php echo $__env->make('errors::minimal', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\views\404.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,673 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tambah Dosen Baru - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 18px;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1rem; line-height: 1.1; color: var(--text); font-weight: 900; }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.85rem; }
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s ease;
|
||||
font-size: 0.9rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.22);
|
||||
}
|
||||
|
||||
.btn.primary:hover {
|
||||
box-shadow: 0 16px 32px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
padding: 28px 32px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 {
|
||||
font-size: 1.8rem;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.section-head p {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
padding: 36px 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 40px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.photo-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.photo-preview {
|
||||
width: 100%;
|
||||
aspect-ratio: 3/4;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 3.5rem;
|
||||
font-weight: 900;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: 0 16px 40px rgba(79, 70, 229, 0.25);
|
||||
border: 3px solid rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.photo-preview:hover {
|
||||
transform: scale(1.03);
|
||||
box-shadow: 0 20px 50px rgba(79, 70, 229, 0.32);
|
||||
}
|
||||
|
||||
.photo-preview img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.photo-initial {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.photo-label {
|
||||
border: 2px dashed rgba(79, 70, 229, 0.3);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(79, 70, 229, 0.02);
|
||||
}
|
||||
|
||||
.photo-label:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(79, 70, 229, 0.1);
|
||||
}
|
||||
|
||||
.photo-label-text {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 800;
|
||||
color: var(--primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.photo-label-hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.photo-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-row.full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-weight: 800;
|
||||
color: #475569;
|
||||
font-size: 0.9rem;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 13px 14px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.25);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
transition: all 0.3s ease;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.input:focus, .select:focus {
|
||||
border-color: var(--primary);
|
||||
background: rgba(79, 70, 229, 0.02);
|
||||
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
|
||||
}
|
||||
|
||||
.input.error, .select.error {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.02);
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.field-error {
|
||||
font-size: 0.8rem;
|
||||
color: #dc2626;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.error-box {
|
||||
padding: 16px 20px;
|
||||
border-radius: 16px;
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
color: #7f1d1d;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.error-box strong {
|
||||
display: block;
|
||||
font-weight: 800;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.error-box ul {
|
||||
list-style: none;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.error-box li {
|
||||
font-weight: 700;
|
||||
margin-bottom: 6px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.error-box li:before {
|
||||
content: "•";
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.12);
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.btn.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 12px 24px rgba(16, 185, 129, 0.22);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn.success:hover {
|
||||
box-shadow: 0 16px 32px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.form-wrapper {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.section-head h2 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.photo-preview {
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-shell">
|
||||
<header class="topbar">
|
||||
<a class="brand" href="<?php echo e(route('users.index')); ?>">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>Tambah Dosen</h1>
|
||||
<p>Data dosen baru</p>
|
||||
</div>
|
||||
</a>
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="<?php echo e(route('users.dosen')); ?>">Kembali</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<h2>👨🏫 Form Tambah Dosen Baru</h2>
|
||||
<p>Lengkapi informasi dosen dengan data yang akurat dan benar.</p>
|
||||
</div>
|
||||
|
||||
<?php if($errors->any()): ?>
|
||||
<div style="padding: 0 32px; padding-top: 20px;">
|
||||
<div class="error-box">
|
||||
<strong>❌ Validasi gagal, periksa kembali data Anda:</strong>
|
||||
<ul>
|
||||
<?php $__currentLoopData = $errors->all(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $error): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<li><?php echo e($error); ?></li>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST" action="<?php echo e(route('dosen.store')); ?>" class="form-wrapper" id="dosenForm">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<!-- Photo Section -->
|
||||
<div class="photo-section">
|
||||
<div class="photo-preview" id="photoPreview">
|
||||
<div class="photo-initial" id="photoInitial">👨🏫</div>
|
||||
<img id="photoImg" style="display: none;" alt="Preview" />
|
||||
</div>
|
||||
<label class="photo-label" for="photoInput">
|
||||
<div class="photo-label-text">📤 Upload Foto</div>
|
||||
<div class="photo-label-hint">Klik untuk pilih gambar</div>
|
||||
</label>
|
||||
<input id="photoInput" class="photo-input" type="file" accept="image/*">
|
||||
<input
|
||||
id="fotoUrl"
|
||||
class="input"
|
||||
type="text"
|
||||
name="foto"
|
||||
value="<?php echo e(old('foto')); ?>"
|
||||
placeholder="atau URL gambar"
|
||||
>
|
||||
<div class="hint">📝 Gunakan file atau URL gambar untuk foto profil</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Fields -->
|
||||
<div class="form-fields">
|
||||
<!-- Nama -->
|
||||
<div class="field-row full">
|
||||
<div class="field">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input
|
||||
id="nama"
|
||||
class="input <?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nama"
|
||||
value="<?php echo e(old('nama')); ?>"
|
||||
required
|
||||
>
|
||||
<?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Masukkan nama lengkap dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- NIP & NIDN -->
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label for="nip">NIP</label>
|
||||
<input
|
||||
id="nip"
|
||||
class="input <?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nip"
|
||||
value="<?php echo e(old('nip')); ?>"
|
||||
placeholder="Contoh: 19850315 200901 1 001"
|
||||
>
|
||||
<?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Nomor Induk Pegawai (opsional)</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="nidn">NIDN</label>
|
||||
<input
|
||||
id="nidn"
|
||||
class="input <?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nidn"
|
||||
value="<?php echo e(old('nidn')); ?>"
|
||||
placeholder="Contoh: 0017058003"
|
||||
>
|
||||
<?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Nomor Induk Dosen Nasional (opsional)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Prodi -->
|
||||
<div class="field-row full">
|
||||
<div class="field">
|
||||
<label for="prodi">Program Studi <span class="required">*</span></label>
|
||||
<select
|
||||
id="prodi"
|
||||
class="select <?php $__errorArgs = ['prodi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
name="prodi"
|
||||
required
|
||||
>
|
||||
<option value="">-- Pilih Program Studi --</option>
|
||||
<option value="Manajemen Informatika" <?php if(old('prodi') === 'Manajemen Informatika'): echo 'selected'; endif; ?>>Manajemen Informatika</option>
|
||||
<option value="Teknik Informatika" <?php if(old('prodi') === 'Teknik Informatika'): echo 'selected'; endif; ?>>Teknik Informatika</option>
|
||||
<option value="Teknik Komputer" <?php if(old('prodi') === 'Teknik Komputer'): echo 'selected'; endif; ?>>Teknik Komputer</option>
|
||||
<option value="Teknologi Rekayasa Komputer" <?php if(old('prodi') === 'Teknologi Rekayasa Komputer'): echo 'selected'; endif; ?>>Teknologi Rekayasa Komputer</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['prodi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Pilih program studi untuk dosen</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Role (Hidden for Dosen) -->
|
||||
<input type="hidden" name="role" value="dosen">
|
||||
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<button class="btn success" type="submit">✅ Simpan Dosen</button>
|
||||
<a class="btn ghost" href="<?php echo e(route('users.dosen')); ?>">❌ Batal</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const photoInput = document.getElementById('photoInput');
|
||||
const fotoUrl = document.getElementById('fotoUrl');
|
||||
const photoPreview = document.getElementById('photoPreview');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const dosenForm = document.getElementById('dosenForm');
|
||||
let isSubmitting = false;
|
||||
|
||||
// Prevent double submit
|
||||
dosenForm.addEventListener('submit', function(e) {
|
||||
if (isSubmitting) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
isSubmitting = true;
|
||||
|
||||
// Disable submit button
|
||||
const submitBtn = dosenForm.querySelector('button[type="submit"]');
|
||||
if (submitBtn) {
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.style.opacity = '0.6';
|
||||
submitBtn.style.cursor = 'not-allowed';
|
||||
submitBtn.textContent = '⏳ Sedang menyimpan...';
|
||||
}
|
||||
});
|
||||
|
||||
// Handle file input
|
||||
photoInput.addEventListener('change', (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
photoImg.src = event.target.result;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
fotoUrl.value = event.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle URL input
|
||||
fotoUrl.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
// Update initial dari nama
|
||||
namaInput.addEventListener('input', () => {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama && !photoImg.src) {
|
||||
const words = nama.split(/\s+/);
|
||||
const initials = words.slice(0, 2).map(w => w.charAt(0).toUpperCase()).join('');
|
||||
photoInitial.textContent = initials || '👨🏫';
|
||||
}
|
||||
});
|
||||
|
||||
// Restore state saat halaman load
|
||||
window.addEventListener('load', () => {
|
||||
// Reset form state jika ada error
|
||||
isSubmitting = false;
|
||||
const submitBtn = dosenForm.querySelector('button[type="submit"]');
|
||||
if (submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.style.opacity = '1';
|
||||
submitBtn.style.cursor = 'pointer';
|
||||
submitBtn.textContent = '✅ Simpan Dosen';
|
||||
}
|
||||
|
||||
if (fotoUrl.value.trim()) {
|
||||
fotoUrl.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (namaInput.value.trim()) {
|
||||
namaInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views/Dosen/create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M2.75 2.75H5.614L5.316 2.114C5.069 1.587 4.54 1.25 3.958 1.25H2.25C1.422 1.25 0.75 1.922 0.75 2.75V4.75C0.75 3.645 1.645 2.75 2.75 2.75Z" />
|
||||
<path d="M0.75 4.75V2.75C0.75 1.922 1.422 1.25 2.25 1.25H3.958C4.54 1.25 5.069 1.587 5.316 2.114L5.614 2.75" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.75 2.75H9.25C10.355 2.75 11.25 3.645 11.25 4.75V8.25C11.25 9.355 10.355 10.25 9.25 10.25H2.75C1.645 10.25 0.75 9.355 0.75 8.25V4.75C0.75 3.645 1.645 2.75 2.75 2.75Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/folder.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 911 B |
|
|
@ -0,0 +1,626 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tambah Staff/Teknisi - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #e0fdf4;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #059669;
|
||||
--primary-2: #14b8a6;
|
||||
--purple: #4f46e5;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(5, 150, 105, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(20, 184, 166, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #d1fae5 0%, #e0fdf4 45%, #f0fdfa 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 900;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header-desc {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
padding: 36px;
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 36px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.photo-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.photo-frame {
|
||||
width: 100%;
|
||||
aspect-ratio: 3/4;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-size: 4rem;
|
||||
font-weight: 900;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
box-shadow: 0 16px 36px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.photo-frame:hover {
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 20px 48px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.photo-frame img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.photo-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.photo-label {
|
||||
border: 2px dashed rgba(5, 150, 105, 0.3);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
}
|
||||
|
||||
.photo-label:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
}
|
||||
|
||||
.photo-label-text {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.photo-label-hint {
|
||||
font-size: 0.8rem;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.field-section.full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
font-weight: 800;
|
||||
color: #475569;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.field label .required {
|
||||
color: var(--orange);
|
||||
}
|
||||
|
||||
.input, .select {
|
||||
padding: 13px 14px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.25);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.input:focus, .select:focus {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.02);
|
||||
box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.1);
|
||||
}
|
||||
|
||||
.input::placeholder {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
margin: 18px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 16px;
|
||||
background: rgba(217, 119, 6, 0.08);
|
||||
border: 1px solid rgba(217, 119, 6, 0.18);
|
||||
color: #7c2d12;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.error-message ul {
|
||||
margin-top: 8px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.field-error {
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
color: #991b1b;
|
||||
font-weight: 700;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.input.error, .select.error {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.02);
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 14px;
|
||||
padding: 16px;
|
||||
background: rgba(5, 150, 105, 0.05);
|
||||
border-radius: 14px;
|
||||
border: 1.5px solid rgba(5, 150, 105, 0.2);
|
||||
}
|
||||
|
||||
.role-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
background: #fff;
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"] {
|
||||
cursor: pointer;
|
||||
accent-color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option:hover {
|
||||
border-color: var(--primary);
|
||||
background: rgba(5, 150, 105, 0.04);
|
||||
}
|
||||
|
||||
.role-option input[type="radio"]:checked ~ label {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.role-option label {
|
||||
cursor: pointer;
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
padding: 14px 18px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
gap: 8px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(5, 150, 105, 0.22);
|
||||
}
|
||||
|
||||
.btn.primary:hover {
|
||||
box-shadow: 0 16px 32px rgba(5, 150, 105, 0.28);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.form-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.field-section {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.role-selector {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-shell">
|
||||
<header class="header">
|
||||
<h1 class="header-title">🔧 Tambah Staff/Teknisi</h1>
|
||||
<p class="header-desc">Lengkapi data staff atau teknisi dengan informasi yang akurat.</p>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<?php if($errors->any()): ?>
|
||||
<div class="error-message">
|
||||
<strong>❌ Terjadi kesalahan validasi:</strong>
|
||||
<ul>
|
||||
<?php $__currentLoopData = $errors->all(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $error): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<li><?php echo e($error); ?></li>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST" action="<?php echo e(route('staff.store')); ?>" class="form-container">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<!-- Foto Section -->
|
||||
<div class="photo-section">
|
||||
<div class="photo-frame" id="photoPreview">
|
||||
<span id="photoInitial">🔧</span>
|
||||
<img id="photoImg" style="display:none;" />
|
||||
</div>
|
||||
<label class="photo-label" for="fotoInput">
|
||||
<div class="photo-label-text">📤 Upload Foto</div>
|
||||
<div class="photo-label-hint">Klik untuk memilih gambar</div>
|
||||
</label>
|
||||
<input
|
||||
id="fotoInput"
|
||||
class="input"
|
||||
type="text"
|
||||
name="foto"
|
||||
value="<?php echo e(old('foto')); ?>"
|
||||
placeholder="atau masukkan URL foto"
|
||||
>
|
||||
<div class="hint">Format: URL gambar (https://...)</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Fields -->
|
||||
<div class="form-fields">
|
||||
<!-- Row 1: Nama -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="nama">Nama Lengkap <span class="required">*</span></label>
|
||||
<input
|
||||
id="nama"
|
||||
class="input <?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nama"
|
||||
value="<?php echo e(old('nama')); ?>"
|
||||
placeholder="Masukkan nama lengkap"
|
||||
required
|
||||
>
|
||||
<?php $__errorArgs = ['nama'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 2: NIP dan NIDN -->
|
||||
<div class="field-section">
|
||||
<div class="field">
|
||||
<label for="nip">NIP</label>
|
||||
<input
|
||||
id="nip"
|
||||
class="input <?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nip"
|
||||
value="<?php echo e(old('nip')); ?>"
|
||||
placeholder="Contoh: 12345678 900000 1 001"
|
||||
>
|
||||
<?php $__errorArgs = ['nip'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Nomor Induk Pegawai (opsional)</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="nidn">Identitas Lain / BioID</label>
|
||||
<input
|
||||
id="nidn"
|
||||
class="input <?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
type="text"
|
||||
name="nidn"
|
||||
value="<?php echo e(old('nidn')); ?>"
|
||||
placeholder="Contoh: BiometricID atau nomor lain"
|
||||
>
|
||||
<?php $__errorArgs = ['nidn'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Identitas tambahan (opsional)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 3: Bagian -->
|
||||
<div class="field-section full">
|
||||
<div class="field">
|
||||
<label for="bagian">Bagian <span class="required">*</span></label>
|
||||
<select
|
||||
id="bagian"
|
||||
class="select <?php $__errorArgs = ['bagian'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> error <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
name="bagian"
|
||||
required
|
||||
>
|
||||
<option value="">-- Pilih Bagian --</option>
|
||||
<option value="Staff Administrasi" <?php if(old('bagian') === 'Staff Administrasi'): echo 'selected'; endif; ?>>Staff Administrasi</option>
|
||||
<option value="Arsitektur dan Jaringan Komputer" <?php if(old('bagian') === 'Arsitektur dan Jaringan Komputer'): echo 'selected'; endif; ?>>Arsitektur dan Jaringan Komputer</option>
|
||||
<option value="Komputasi dan Sistem Informasi" <?php if(old('bagian') === 'Komputasi dan Sistem Informasi'): echo 'selected'; endif; ?>>Komputasi dan Sistem Informasi</option>
|
||||
<option value="Rekayasa Sistem Informasi" <?php if(old('bagian') === 'Rekayasa Sistem Informasi'): echo 'selected'; endif; ?>>Rekayasa Sistem Informasi</option>
|
||||
<option value="Sistem Komputer dan Kontrol" <?php if(old('bagian') === 'Sistem Komputer dan Kontrol'): echo 'selected'; endif; ?>>Sistem Komputer dan Kontrol</option>
|
||||
<option value="Rekayasa Perangkat Lunak" <?php if(old('bagian') === 'Rekayasa Perangkat Lunak'): echo 'selected'; endif; ?>>Rekayasa Perangkat Lunak</option>
|
||||
<option value="Multimedia Cerdas" <?php if(old('bagian') === 'Multimedia Cerdas'): echo 'selected'; endif; ?>>Multimedia Cerdas</option>
|
||||
<option value="Staff Lainnya" <?php if(old('bagian') === 'Staff Lainnya'): echo 'selected'; endif; ?>>Staff Lainnya</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['bagian'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="field-error"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<div class="hint">Pilih bagian/divisi staff</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Role Selection -->
|
||||
<div class="field-section full">
|
||||
<label style="font-weight: 800; color: #475569; font-size: 0.92rem; margin-bottom: 8px;">Pilih Role <span class="required">*</span></label>
|
||||
<div class="role-selector">
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleStaff" name="role" value="staff" <?php if(old('role') === 'staff' || !old('role')): echo 'checked'; endif; ?> required>
|
||||
<label for="roleStaff">👤 Staff</label>
|
||||
</div>
|
||||
<div class="role-option">
|
||||
<input type="radio" id="roleTeknik" name="role" value="teknisi" <?php if(old('role') === 'teknisi'): echo 'checked'; endif; ?> required>
|
||||
<label for="roleTeknik">🔧 Teknisi</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<button class="btn primary" type="submit">✅ Simpan Staff/Teknisi</button>
|
||||
<a class="btn ghost" href="<?php echo e(route('users.staff')); ?>">❌ Batal</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Photo preview dari URL
|
||||
const fotoInput = document.getElementById('fotoInput');
|
||||
const photoPreview = document.getElementById('photoPreview');
|
||||
const photoImg = document.getElementById('photoImg');
|
||||
const photoInitial = document.getElementById('photoInitial');
|
||||
const namaInput = document.getElementById('nama');
|
||||
const roleStaffInput = document.getElementById('roleStaff');
|
||||
const roleTeknikInput = document.getElementById('roleTeknik');
|
||||
const submitBtn = document.querySelector('button[type="submit"]');
|
||||
const form = document.querySelector('form');
|
||||
let isSubmitting = false;
|
||||
|
||||
function updatePhotoIcon() {
|
||||
if (roleTeknikInput.checked) {
|
||||
return '🔧';
|
||||
}
|
||||
return '👤';
|
||||
}
|
||||
|
||||
// Prevent double submission
|
||||
form.addEventListener('submit', (e) => {
|
||||
if (isSubmitting) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
isSubmitting = true;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = '⏳ Menyimpan...';
|
||||
});
|
||||
|
||||
fotoInput.addEventListener('change', (e) => {
|
||||
const url = e.target.value.trim();
|
||||
if (url && (url.startsWith('http') || url.startsWith('data:'))) {
|
||||
photoImg.src = url;
|
||||
photoImg.style.display = 'block';
|
||||
photoInitial.style.display = 'none';
|
||||
} else {
|
||||
photoImg.style.display = 'none';
|
||||
photoInitial.style.display = 'block';
|
||||
updateInitials();
|
||||
}
|
||||
});
|
||||
|
||||
function updateInitials() {
|
||||
const nama = namaInput.value.trim();
|
||||
if (nama) {
|
||||
const initials = nama.split(/\s+/)
|
||||
.slice(0, 2)
|
||||
.map(w => w.charAt(0).toUpperCase())
|
||||
.join('');
|
||||
photoInitial.textContent = initials || updatePhotoIcon();
|
||||
} else {
|
||||
photoInitial.textContent = updatePhotoIcon();
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger dari input nama
|
||||
namaInput.addEventListener('input', updateInitials);
|
||||
|
||||
// Trigger dari role selection
|
||||
roleStaffInput.addEventListener('change', updateInitials);
|
||||
roleTeknikInput.addEventListener('change', updateInitials);
|
||||
|
||||
// Inisialisasi saat halaman load
|
||||
window.addEventListener('load', () => {
|
||||
isSubmitting = false;
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = '✅ Simpan Staff/Teknisi';
|
||||
if (fotoInput.value.trim()) {
|
||||
fotoInput.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (namaInput.value.trim()) {
|
||||
namaInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views\staff\create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['frame', 'direction' => 'ltr']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['frame', 'direction' => 'ltr']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$file = $frame->file();
|
||||
$line = $frame->line();
|
||||
?>
|
||||
|
||||
<div
|
||||
<?php echo e($attributes->merge(['class' => 'truncate font-mono text-xs text-neutral-500 dark:text-neutral-400'])); ?>
|
||||
|
||||
dir="<?php echo e($direction); ?>"
|
||||
>
|
||||
<span data-tippy-content="<?php echo e($file); ?>:<?php echo e($line); ?>">
|
||||
<?php if(config('app.editor')): ?>
|
||||
<a href="<?php echo e($frame->editorHref()); ?>" @click.stop>
|
||||
<span class="hover:underline decoration-neutral-400"><?php echo e($file); ?></span><span class="text-neutral-500">:<?php echo e($line); ?></span>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<?php echo e($file); ?><span class="text-neutral-500">:<?php echo e($line); ?></span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\file-with-line.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php $__env->startSection('title', __('Payment Required')); ?>
|
||||
<?php $__env->startSection('code', '402'); ?>
|
||||
<?php $__env->startSection('message', __('Payment Required')); ?>
|
||||
|
||||
<?php echo $__env->make('errors::minimal', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\views\402.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php $__env->startSection('title', __('Service Unavailable')); ?>
|
||||
<?php $__env->startSection('code', '503'); ?>
|
||||
<?php $__env->startSection('message', __('Service Unavailable')); ?>
|
||||
|
||||
<?php echo $__env->make('errors::minimal', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\views\503.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['body']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['body']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<h2 class="text-lg font-semibold">Body</h2>
|
||||
<?php if($body): ?>
|
||||
<div class="bg-white dark:bg-white/[2%] border border-neutral-200 dark:border-neutral-800 rounded-md overflow-x-auto p-5 text-sm font-mono shadow-xs">
|
||||
<?php if (isset($component)) { $__componentOriginal12cb286571f553eebcbe98210b217f94 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal12cb286571f553eebcbe98210b217f94 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.syntax-highlight','data' => ['code' => $body,'language' => 'json']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::syntax-highlight'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['code' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($body),'language' => 'json']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $attributes = $__attributesOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__attributesOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $component = $__componentOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__componentOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php if (isset($component)) { $__componentOriginal612ffe32146e3bd2ac6ba6076cca9520 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.empty-state','data' => ['message' => 'No request body']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::empty-state'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['message' => 'No request body']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520)): ?>
|
||||
<?php $attributes = $__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520; ?>
|
||||
<?php unset($__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal612ffe32146e3bd2ac6ba6076cca9520)): ?>
|
||||
<?php $component = $__componentOriginal612ffe32146e3bd2ac6ba6076cca9520; ?>
|
||||
<?php unset($__componentOriginal612ffe32146e3bd2ac6ba6076cca9520); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\request-body.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['exception']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['exception']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="flex flex-col pt-8 sm:pt-16 overflow-x-auto">
|
||||
<div class="flex flex-col gap-5 mb-8">
|
||||
<h1 class="text-3xl font-semibold text-neutral-950 dark:text-white"><?php echo e($exception->class()); ?></h1>
|
||||
<?php if (isset($component)) { $__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.file-with-line','data' => ['frame' => $exception->frames()->first(),'class' => '-mt-3 text-xs']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::file-with-line'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frame' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->frames()->first()),'class' => '-mt-3 text-xs']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d)): ?>
|
||||
<?php $attributes = $__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d; ?>
|
||||
<?php unset($__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d)): ?>
|
||||
<?php $component = $__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d; ?>
|
||||
<?php unset($__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d); ?>
|
||||
<?php endif; ?>
|
||||
<p class="text-xl font-light text-neutral-800 dark:text-neutral-300">
|
||||
<?php echo e($exception->message()); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start gap-2 mb-8 sm:mb-16">
|
||||
<div class="bg-white dark:bg-white/[3%] border border-neutral-200 dark:border-white/10 divide-x divide-neutral-200 dark:divide-white/10 rounded-md shadow-xs flex items-center gap-0.5">
|
||||
<div class="flex items-center gap-1.5 h-6 px-[6px] font-mono text-[13px]">
|
||||
<span class="text-neutral-400 dark:text-neutral-500">LARAVEL</span>
|
||||
<span class="text-neutral-500 dark:text-neutral-300"><?php echo e(app()->version()); ?></span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 h-6 px-[6px] font-mono text-[13px]">
|
||||
<span class="text-neutral-400 dark:text-neutral-500">PHP</span>
|
||||
<span class="text-neutral-500 dark:text-neutral-300"><?php echo e(PHP_VERSION); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => 'error']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => 'error']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalebc8ec9a834a8051f56913d6745a7050 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalebc8ec9a834a8051f56913d6745a7050 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.alert','data' => ['class' => 'w-2.5 h-2.5']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.alert'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $attributes = $__attributesOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $component = $__componentOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__componentOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
UNHANDLED
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => 'error','variant' => 'solid']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => 'error','variant' => 'solid']); ?>
|
||||
CODE <?php echo e($exception->code()); ?>
|
||||
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginalb581a7e3a55d371fae986833ecafa668 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalb581a7e3a55d371fae986833ecafa668 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.request-url','data' => ['exception' => $exception,'request' => $exception->request(),'class' => 'relative z-50']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::request-url'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['exception' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception),'request' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->request()),'class' => 'relative z-50']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalb581a7e3a55d371fae986833ecafa668)): ?>
|
||||
<?php $attributes = $__attributesOriginalb581a7e3a55d371fae986833ecafa668; ?>
|
||||
<?php unset($__attributesOriginalb581a7e3a55d371fae986833ecafa668); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalb581a7e3a55d371fae986833ecafa668)): ?>
|
||||
<?php $component = $__componentOriginalb581a7e3a55d371fae986833ecafa668; ?>
|
||||
<?php unset($__componentOriginalb581a7e3a55d371fae986833ecafa668); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\header.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames(([
|
||||
'code',
|
||||
'language',
|
||||
'editor' => false,
|
||||
'startingLine' => 1,
|
||||
'highlightedLine' => null,
|
||||
'truncate' => false,
|
||||
]));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter(([
|
||||
'code',
|
||||
'language',
|
||||
'editor' => false,
|
||||
'startingLine' => 1,
|
||||
'highlightedLine' => null,
|
||||
'truncate' => false,
|
||||
]), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$fallback = $truncate ? '<pre class="truncate"><code>' : '<pre><code>';
|
||||
|
||||
if ($editor) {
|
||||
$lines = explode("\n", $code);
|
||||
|
||||
foreach ($lines as $index => $line) {
|
||||
$lineNumber = $startingLine + $index;
|
||||
$highlight = $highlightedLine === $index;
|
||||
$lineClass = implode(' ', [
|
||||
'block px-4 py-1 h-7 even:bg-white odd:bg-white/2 even:dark:bg-white/2 odd:dark:bg-white/4',
|
||||
$highlight ? 'bg-rose-200! dark:bg-rose-900!' : '',
|
||||
]);
|
||||
$lineNumberClass = implode(' ', [
|
||||
'mr-6 text-neutral-500! dark:text-neutral-600!',
|
||||
$highlight ? 'dark:text-white!' : '',
|
||||
]);
|
||||
|
||||
$fallback .= '<span class="' . $lineClass . '">';
|
||||
$fallback .= '<span class="' . $lineNumberClass . '">' . $lineNumber . '</span>';
|
||||
$fallback .= htmlspecialchars($line);
|
||||
$fallback .= '</span>';
|
||||
}
|
||||
|
||||
} else {
|
||||
$fallback .= htmlspecialchars($code);
|
||||
}
|
||||
|
||||
$fallback .= '</code></pre>';
|
||||
?>
|
||||
|
||||
<div
|
||||
x-data="{ highlightedCode: null }"
|
||||
x-init="
|
||||
highlightedCode = window.highlight(
|
||||
<?php echo e(Illuminate\Support\Js::from($code)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($language)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($truncate)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($editor)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($startingLine)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($highlightedLine)); ?>
|
||||
|
||||
);
|
||||
"
|
||||
<?php echo e($attributes); ?>
|
||||
|
||||
>
|
||||
<div
|
||||
x-cloak
|
||||
x-html="highlightedCode"
|
||||
></div>
|
||||
<div x-show="!highlightedCode"><?php echo $fallback; ?></div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/syntax-highlight.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['type' => 'default', 'variant' => 'soft']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['type' => 'default', 'variant' => 'soft']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$baseClasses = 'inline-flex w-fit shrink-0 items-center justify-center gap-1 font-mono leading-3 uppercase transition-colors dark:border [&_svg]:size-2.5 h-6 min-w-5 rounded-md px-1.5 text-xs/none';
|
||||
|
||||
$types = [
|
||||
'default' => [
|
||||
'soft' => 'bg-black/8 text-neutral-900 dark:border-neutral-700 dark:bg-white/10 dark:text-neutral-100',
|
||||
'solid' => 'bg-neutral-600 text-neutral-100 dark:border-neutral-500 dark:bg-neutral-600',
|
||||
],
|
||||
'success' => [
|
||||
'soft' => 'bg-emerald-200 text-emerald-900 dark:border-emerald-600 dark:bg-emerald-900/70 dark:text-emerald-400',
|
||||
'solid' => 'bg-emerald-600 dark:border-emerald-500 dark:bg-emerald-600',
|
||||
],
|
||||
'primary' => [
|
||||
'soft' => 'bg-blue-100 text-blue-900 dark:border-blue-800 dark:bg-blue-950 dark:text-blue-300',
|
||||
'solid' => 'bg-blue-700 dark:border-blue-600 dark:bg-blue-700',
|
||||
],
|
||||
'error' => [
|
||||
'soft' => 'bg-rose-200 text-rose-900 dark:border-rose-900 dark:bg-rose-950 dark:text-rose-100 dark:[&_svg]:!text-white',
|
||||
'solid' => 'bg-rose-600 dark:border-rose-500 dark:bg-rose-600',
|
||||
],
|
||||
'alert' => [
|
||||
'soft' => 'bg-amber-200 text-amber-900 dark:border-amber-800 dark:bg-amber-950 dark:text-amber-300',
|
||||
'solid' => 'bg-amber-600 dark:border-amber-500 dark:bg-amber-600',
|
||||
],
|
||||
'white' => [
|
||||
'soft' => 'bg-white text-neutral-900 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100',
|
||||
'solid' => 'bg-black/10 text-neutral-900 dark:text-neutral-900 dark:bg-white',
|
||||
],
|
||||
];
|
||||
|
||||
$variants = [
|
||||
'soft' => '',
|
||||
'solid' => 'text-white dark:text-white [&_svg]:!text-white',
|
||||
];
|
||||
|
||||
$typeClasses = $types[$type][$variant] ?? $types['default']['soft'];
|
||||
$variantClasses = $variants[$variant] ?? $variants['soft'];
|
||||
|
||||
$classes = implode(' ', [$baseClasses, $typeClasses, $variantClasses]);
|
||||
|
||||
?>
|
||||
|
||||
<div <?php echo e($attributes->merge(['class' => $classes])); ?>>
|
||||
<?php echo e($slot); ?>
|
||||
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/badge.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" <?php echo e($attributes); ?>>
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 16v-4"/>
|
||||
<path d="M12 8h.01"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\info.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 480 B |
|
|
@ -0,0 +1,12 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<g clip-path="url(#clip0_14732_6211)">
|
||||
<path d="M1.75 5.25V2.75C1.75 1.922 2.422 1.25 3.25 1.25H4.202C4.808 1.25 5.381 1.525 5.761 1.998L6.364 2.75H8.25C9.355 2.75 10.25 3.645 10.25 4.75V5.25" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.46801 5.25H9.53101C10.44 5.25 11.14 6.052 11.017 6.953L10.735 9.021C10.6 10.012 9.75301 10.751 8.75301 10.751H3.24601C2.24601 10.751 1.39901 10.012 1.26401 9.021L0.982011 6.953C0.859011 6.052 1.55901 5.25 2.46801 5.25Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_14732_6211">
|
||||
<rect width="12" height="12" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\folder-open.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" <?php echo e($attributes); ?>>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\check.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 371 B |
|
|
@ -0,0 +1,83 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['method']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['method']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$type = match ($method) {
|
||||
'GET', 'OPTIONS', 'ANY' => 'default',
|
||||
'POST' => 'success',
|
||||
'PUT', 'PATCH' => 'primary',
|
||||
'DELETE' => 'error',
|
||||
default => 'default',
|
||||
};
|
||||
?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => ''.e($type).'']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => ''.e($type).'']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalba2eecb54ab69c011eea9820c76048d8 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalba2eecb54ab69c011eea9820c76048d8 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.globe','data' => ['class' => 'w-2.5 h-2.5']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.globe'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalba2eecb54ab69c011eea9820c76048d8)): ?>
|
||||
<?php $attributes = $__attributesOriginalba2eecb54ab69c011eea9820c76048d8; ?>
|
||||
<?php unset($__attributesOriginalba2eecb54ab69c011eea9820c76048d8); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalba2eecb54ab69c011eea9820c76048d8)): ?>
|
||||
<?php $component = $__componentOriginalba2eecb54ab69c011eea9820c76048d8; ?>
|
||||
<?php unset($__componentOriginalba2eecb54ab69c011eea9820c76048d8); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo e($method); ?>
|
||||
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\http-method.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['frame']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['frame']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div
|
||||
x-data="{
|
||||
expanded: <?php echo e($frame->isMain() ? 'true' : 'false'); ?>,
|
||||
hasCode: <?php echo e($frame->snippet() ? 'true' : 'false'); ?>
|
||||
|
||||
}"
|
||||
class="group rounded-lg border border-neutral-200 dark:border-white/10 overflow-hidden shadow-xs"
|
||||
:class="{ 'dark:border-white/5': expanded }"
|
||||
>
|
||||
<div
|
||||
class="flex h-11 items-center gap-3 bg-white pr-2.5 pl-4 overflow-x-auto dark:bg-white/3"
|
||||
:class="{
|
||||
'cursor-pointer hover:bg-white/50 dark:hover:bg-white/5 hover:[&_svg]:stroke-emerald-500': hasCode,
|
||||
'dark:bg-white/5 rounded-t-lg': expanded,
|
||||
'dark:bg-white/3 rounded-lg': !expanded
|
||||
}"
|
||||
@click="hasCode && (expanded = !expanded)"
|
||||
>
|
||||
|
||||
<div class="flex size-3 items-center justify-center flex-shrink-0">
|
||||
<div
|
||||
class="size-2 rounded-full"
|
||||
:class="{
|
||||
'bg-rose-500 dark:bg-neutral-400': expanded,
|
||||
'bg-rose-200 dark:bg-neutral-700': !expanded
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-1 items-center justify-between gap-6 min-w-0">
|
||||
<?php if (isset($component)) { $__componentOriginalc33171fb5f34409a0ad661ae1625dcb2 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalc33171fb5f34409a0ad661ae1625dcb2 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.formatted-source','data' => ['frame' => $frame]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::formatted-source'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frame' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($frame)]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalc33171fb5f34409a0ad661ae1625dcb2)): ?>
|
||||
<?php $attributes = $__attributesOriginalc33171fb5f34409a0ad661ae1625dcb2; ?>
|
||||
<?php unset($__attributesOriginalc33171fb5f34409a0ad661ae1625dcb2); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalc33171fb5f34409a0ad661ae1625dcb2)): ?>
|
||||
<?php $component = $__componentOriginalc33171fb5f34409a0ad661ae1625dcb2; ?>
|
||||
<?php unset($__componentOriginalc33171fb5f34409a0ad661ae1625dcb2); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.file-with-line','data' => ['frame' => $frame,'direction' => 'rtl']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::file-with-line'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frame' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($frame),'direction' => 'rtl']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d)): ?>
|
||||
<?php $attributes = $__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d; ?>
|
||||
<?php unset($__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d)): ?>
|
||||
<?php $component = $__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d; ?>
|
||||
<?php unset($__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="flex-shrink-0">
|
||||
<button
|
||||
x-cloak
|
||||
type="button"
|
||||
class="flex h-6 w-6 cursor-pointer items-center justify-center rounded-md dark:border dark:border-white/8 group-hover:text-blue-500 group-hover:dark:text-emerald-500"
|
||||
:class="{
|
||||
'text-blue-500 dark:text-emerald-500 dark:bg-white/5': expanded,
|
||||
'text-neutral-500 dark:text-neutral-500 dark:bg-white/3': !expanded,
|
||||
}"
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.chevrons-down-up','data' => ['xShow' => 'expanded']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.chevrons-down-up'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['x-show' => 'expanded']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28)): ?>
|
||||
<?php $attributes = $__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28; ?>
|
||||
<?php unset($__attributesOriginal4400c4a71d3ea90a0e0b846e7d689a28); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28)): ?>
|
||||
<?php $component = $__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28; ?>
|
||||
<?php unset($__componentOriginal4400c4a71d3ea90a0e0b846e7d689a28); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal7348bb70f498d75e0a91acc6a707f136 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal7348bb70f498d75e0a91acc6a707f136 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.chevrons-up-down','data' => ['xShow' => '!expanded']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.chevrons-up-down'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['x-show' => '!expanded']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal7348bb70f498d75e0a91acc6a707f136)): ?>
|
||||
<?php $attributes = $__attributesOriginal7348bb70f498d75e0a91acc6a707f136; ?>
|
||||
<?php unset($__attributesOriginal7348bb70f498d75e0a91acc6a707f136); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal7348bb70f498d75e0a91acc6a707f136)): ?>
|
||||
<?php $component = $__componentOriginal7348bb70f498d75e0a91acc6a707f136; ?>
|
||||
<?php unset($__componentOriginal7348bb70f498d75e0a91acc6a707f136); ?>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if($snippet = $frame->snippet()): ?>
|
||||
<?php if (isset($component)) { $__componentOriginala7df34c267a7ce6efa01f63b793ef234 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginala7df34c267a7ce6efa01f63b793ef234 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.frame-code','data' => ['code' => $snippet,'highlightedLine' => $frame->line(),'xShow' => 'expanded','xCloak' => !$frame->isMain()]] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::frame-code'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['code' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($snippet),'highlightedLine' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($frame->line()),'x-show' => 'expanded','x-cloak' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute(!$frame->isMain())]); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginala7df34c267a7ce6efa01f63b793ef234)): ?>
|
||||
<?php $attributes = $__attributesOriginala7df34c267a7ce6efa01f63b793ef234; ?>
|
||||
<?php unset($__attributesOriginala7df34c267a7ce6efa01f63b793ef234); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginala7df34c267a7ce6efa01f63b793ef234)): ?>
|
||||
<?php $component = $__componentOriginala7df34c267a7ce6efa01f63b793ef234; ?>
|
||||
<?php unset($__componentOriginala7df34c267a7ce6efa01f63b793ef234); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\frame.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Management Portal - Dosen & Staff/Teknisi</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f5f7f4;
|
||||
--panel: #ffffff;
|
||||
--ink: #17211f;
|
||||
--muted: #5f6d69;
|
||||
--line: #d8dfdc;
|
||||
--brand: #0f766e;
|
||||
--brand-soft: #e7f3f1;
|
||||
--accent: #f97316;
|
||||
--ok: #16a34a;
|
||||
--warn: #c2410c;
|
||||
--shadow: 0 18px 42px rgba(23, 33, 31, 0.08);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: "Trebuchet MS", "Segoe UI", sans-serif;
|
||||
color: var(--ink);
|
||||
background:
|
||||
radial-gradient(65rem 45rem at 120% -10%, #d7f0ec 0%, transparent 45%),
|
||||
radial-gradient(55rem 40rem at -20% 120%, #ffe8d4 0%, transparent 38%),
|
||||
var(--bg);
|
||||
}
|
||||
|
||||
.layout {
|
||||
min-height: 100vh;
|
||||
display: grid;
|
||||
grid-template-columns: 270px 1fr;
|
||||
gap: 18px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background: linear-gradient(180deg, #0f172a, #111827);
|
||||
color: #e5e7eb;
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
box-shadow: var(--shadow);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.brand {
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 18px;
|
||||
border-bottom: 1px solid rgba(229, 231, 235, 0.2);
|
||||
}
|
||||
|
||||
.brand h1 {
|
||||
font-size: 1.1rem;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.brand p {
|
||||
margin-top: 4px;
|
||||
color: #9ca3af;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
text-decoration: none;
|
||||
color: #d1d5db;
|
||||
border: 1px solid rgba(209, 213, 219, 0.15);
|
||||
border-radius: 12px;
|
||||
padding: 12px 14px;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.menu a:hover,
|
||||
.menu a.active {
|
||||
color: #ffffff;
|
||||
background: rgba(15, 118, 110, 0.35);
|
||||
border-color: rgba(94, 234, 212, 0.45);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
.sidebar-note {
|
||||
margin-top: auto;
|
||||
border-top: 1px solid rgba(229, 231, 235, 0.18);
|
||||
padding-top: 14px;
|
||||
font-size: 0.84rem;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
box-shadow: var(--shadow);
|
||||
padding: 16px 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.welcome h2 {
|
||||
font-size: clamp(1.15rem, 2.5vw, 1.8rem);
|
||||
}
|
||||
|
||||
.welcome p {
|
||||
margin-top: 4px;
|
||||
color: var(--muted);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
position: relative;
|
||||
min-width: 240px;
|
||||
}
|
||||
|
||||
.status-trigger {
|
||||
width: 100%;
|
||||
border: 1px solid var(--line);
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.status-current {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 999px;
|
||||
background: var(--ok);
|
||||
box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.18);
|
||||
}
|
||||
|
||||
.status-minus {
|
||||
display: inline-flex;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 999px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
background: var(--warn);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.status-menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 8px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
border: 1px solid var(--line);
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow);
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.status-menu.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.status-option {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: #fff;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #edf0ef;
|
||||
padding: 10px 12px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.status-option:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.status-option:hover {
|
||||
background: #f8faf9;
|
||||
}
|
||||
|
||||
.main-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
box-shadow: var(--shadow);
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.card p {
|
||||
color: var(--muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.chart-wrap {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.chart-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.chip {
|
||||
background: var(--brand-soft);
|
||||
color: var(--brand);
|
||||
border: 1px solid #b5ddd8;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.chart {
|
||||
display: grid;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: grid;
|
||||
grid-template-columns: 70px 1fr 55px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.day {
|
||||
font-weight: 700;
|
||||
color: #33413e;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.bar-bg {
|
||||
height: 12px;
|
||||
background: #e9efed;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bar {
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, var(--brand), #14b8a6);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.hours {
|
||||
text-align: right;
|
||||
font-weight: 700;
|
||||
color: #33413e;
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
.settings-list {
|
||||
margin-top: 14px;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1px solid #e7ecea;
|
||||
border-radius: 12px;
|
||||
padding: 10px 12px;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.setting-item span {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 1px solid #d2dad7;
|
||||
border-radius: 9px;
|
||||
background: #fff;
|
||||
padding: 6px 9px;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
color: #33413e;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: #a9bbb6;
|
||||
background: #f6faf9;
|
||||
}
|
||||
|
||||
@media (max-width: 980px) {
|
||||
.layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.main-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 620px) {
|
||||
.topbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.row {
|
||||
grid-template-columns: 56px 1fr 45px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$namaString = $nama ?? 'Dosen/Staff';
|
||||
$durasiMingguan = $durasiMingguan ?? [
|
||||
'Senin' => 7.5,
|
||||
'Selasa' => 6.8,
|
||||
'Rabu' => 8.2,
|
||||
'Kamis' => 7.1,
|
||||
'Jumat' => 5.4,
|
||||
];
|
||||
$maksJam = max($durasiMingguan);
|
||||
?>
|
||||
|
||||
<div class="layout">
|
||||
<aside class="sidebar">
|
||||
<div class="brand">
|
||||
<h1>JTI MANAGEMENT</h1>
|
||||
<p>Portal Dosen & Staff/Teknisi</p>
|
||||
</div>
|
||||
|
||||
<nav class="menu" aria-label="Menu utama">
|
||||
<a href="#" class="active">
|
||||
<span>Home</span>
|
||||
<span>01</span>
|
||||
</a>
|
||||
<a href="#">
|
||||
<span>Setting</span>
|
||||
<span>02</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-note">
|
||||
Monitoring kehadiran kampus aktif Senin - Jumat dan reset otomatis tiap minggu.
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<section class="content">
|
||||
<header class="topbar">
|
||||
<div class="welcome">
|
||||
<h2>Selamat datang, <?php echo e($namaString); ?></h2>
|
||||
<p>Semoga aktivitas akademik dan operasional hari ini berjalan lancar.</p>
|
||||
</div>
|
||||
|
||||
<div class="status-wrap">
|
||||
<button id="statusTrigger" class="status-trigger" type="button" aria-expanded="false" aria-controls="statusMenu">
|
||||
<span id="statusCurrent" class="status-current">
|
||||
<span class="status-dot" aria-hidden="true"></span>
|
||||
Online
|
||||
</span>
|
||||
<span aria-hidden="true">v</span>
|
||||
</button>
|
||||
|
||||
<div id="statusMenu" class="status-menu" role="listbox" aria-label="Pilih status">
|
||||
<button type="button" class="status-option" data-type="online" role="option">
|
||||
<span class="status-dot" aria-hidden="true"></span>
|
||||
Online
|
||||
</button>
|
||||
<button type="button" class="status-option" data-type="dnd" role="option">
|
||||
<span class="status-minus" aria-hidden="true">-</span>
|
||||
Tidak Bisa Diganggu
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="main-grid">
|
||||
<article class="card">
|
||||
<h3>Grafik Durasi Kehadiran Dosen di Kampus</h3>
|
||||
<p>Rekap otomatis dari Senin sampai Jumat, reset pada awal minggu berikutnya.</p>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-head">
|
||||
<strong>Durasi mingguan (jam)</strong>
|
||||
<span class="chip">Reset Mingguan Otomatis</span>
|
||||
</div>
|
||||
|
||||
<div class="chart">
|
||||
<?php $__currentLoopData = $durasiMingguan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $hari => $jam): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php
|
||||
$persen = $maksJam > 0 ? ($jam / $maksJam) * 100 : 0;
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="day"><?php echo e($hari); ?></div>
|
||||
<div class="bar-bg" aria-hidden="true">
|
||||
<div class="bar" style="width: <?php echo e(number_format($persen, 2, '.', '')); ?>%"></div>
|
||||
</div>
|
||||
<div class="hours"><?php echo e(rtrim(rtrim(number_format($jam, 1, '.', ''), '0'), '.')); ?>j</div>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<aside class="card">
|
||||
<h3>Setting</h3>
|
||||
<p>Pengaturan singkat untuk akun dosen dan staff/teknisi.</p>
|
||||
|
||||
<div class="settings-list">
|
||||
<div class="setting-item">
|
||||
<span>Nama Tampilan</span>
|
||||
<button class="btn" type="button">Ubah</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<span>Notifikasi Kehadiran</span>
|
||||
<button class="btn" type="button">Aktif</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<span>Sinkron Mingguan</span>
|
||||
<button class="btn" type="button">Jadwalkan</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
const trigger = document.getElementById('statusTrigger');
|
||||
const menu = document.getElementById('statusMenu');
|
||||
const current = document.getElementById('statusCurrent');
|
||||
|
||||
if (!trigger || !menu || !current) return;
|
||||
|
||||
const closeMenu = function () {
|
||||
menu.classList.remove('open');
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
};
|
||||
|
||||
trigger.addEventListener('click', function () {
|
||||
const isOpen = menu.classList.contains('open');
|
||||
menu.classList.toggle('open', !isOpen);
|
||||
trigger.setAttribute('aria-expanded', String(!isOpen));
|
||||
});
|
||||
|
||||
menu.querySelectorAll('.status-option').forEach(function (option) {
|
||||
option.addEventListener('click', function () {
|
||||
const type = option.getAttribute('data-type');
|
||||
|
||||
if (type === 'online') {
|
||||
current.innerHTML = '<span class="status-dot" aria-hidden="true"></span>Online';
|
||||
} else {
|
||||
current.innerHTML = '<span class="status-minus" aria-hidden="true">-</span>Tidak Bisa Diganggu';
|
||||
}
|
||||
|
||||
closeMenu();
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (event) {
|
||||
if (!menu.contains(event.target) && !trigger.contains(event.target)) {
|
||||
closeMenu();
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views\welcome.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['method']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['method']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$type = match ($method) {
|
||||
'GET', 'OPTIONS', 'ANY' => 'default',
|
||||
'POST' => 'success',
|
||||
'PUT', 'PATCH' => 'primary',
|
||||
'DELETE' => 'error',
|
||||
default => 'default',
|
||||
};
|
||||
?>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => ''.e($type).'']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => ''.e($type).'']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalba2eecb54ab69c011eea9820c76048d8 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalba2eecb54ab69c011eea9820c76048d8 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.globe','data' => ['class' => 'w-2.5 h-2.5']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.globe'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalba2eecb54ab69c011eea9820c76048d8)): ?>
|
||||
<?php $attributes = $__attributesOriginalba2eecb54ab69c011eea9820c76048d8; ?>
|
||||
<?php unset($__attributesOriginalba2eecb54ab69c011eea9820c76048d8); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalba2eecb54ab69c011eea9820c76048d8)): ?>
|
||||
<?php $component = $__componentOriginalba2eecb54ab69c011eea9820c76048d8; ?>
|
||||
<?php unset($__componentOriginalba2eecb54ab69c011eea9820c76048d8); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo e($method); ?>
|
||||
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/http-method.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames(([
|
||||
'code',
|
||||
'language',
|
||||
'editor' => false,
|
||||
'startingLine' => 1,
|
||||
'highlightedLine' => null,
|
||||
'truncate' => false,
|
||||
]));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter(([
|
||||
'code',
|
||||
'language',
|
||||
'editor' => false,
|
||||
'startingLine' => 1,
|
||||
'highlightedLine' => null,
|
||||
'truncate' => false,
|
||||
]), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$fallback = $truncate ? '<pre class="truncate"><code>' : '<pre><code>';
|
||||
|
||||
if ($editor) {
|
||||
$lines = explode("\n", $code);
|
||||
|
||||
foreach ($lines as $index => $line) {
|
||||
$lineNumber = $startingLine + $index;
|
||||
$highlight = $highlightedLine === $index;
|
||||
$lineClass = implode(' ', [
|
||||
'block px-4 py-1 h-7 even:bg-white odd:bg-white/2 even:dark:bg-white/2 odd:dark:bg-white/4',
|
||||
$highlight ? 'bg-rose-200! dark:bg-rose-900!' : '',
|
||||
]);
|
||||
$lineNumberClass = implode(' ', [
|
||||
'mr-6 text-neutral-500! dark:text-neutral-600!',
|
||||
$highlight ? 'dark:text-white!' : '',
|
||||
]);
|
||||
|
||||
$fallback .= '<span class="' . $lineClass . '">';
|
||||
$fallback .= '<span class="' . $lineNumberClass . '">' . $lineNumber . '</span>';
|
||||
$fallback .= htmlspecialchars($line);
|
||||
$fallback .= '</span>';
|
||||
}
|
||||
|
||||
} else {
|
||||
$fallback .= htmlspecialchars($code);
|
||||
}
|
||||
|
||||
$fallback .= '</code></pre>';
|
||||
?>
|
||||
|
||||
<div
|
||||
x-data="{ highlightedCode: null }"
|
||||
x-init="
|
||||
highlightedCode = window.highlight(
|
||||
<?php echo e(Illuminate\Support\Js::from($code)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($language)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($truncate)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($editor)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($startingLine)); ?>,
|
||||
<?php echo e(Illuminate\Support\Js::from($highlightedLine)); ?>
|
||||
|
||||
);
|
||||
"
|
||||
<?php echo e($attributes); ?>
|
||||
|
||||
>
|
||||
<div
|
||||
x-cloak
|
||||
x-html="highlightedCode"
|
||||
></div>
|
||||
<div x-show="!highlightedCode"><?php echo $fallback; ?></div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\syntax-highlight.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['routing']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['routing']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<h2 class="text-lg font-semibold">Routing</h2>
|
||||
<div class="flex flex-col">
|
||||
<?php $__empty_1 = true; $__currentLoopData = $routing; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<div class="flex max-w-full items-baseline gap-2 h-10 text-sm font-mono">
|
||||
<div class="uppercase text-neutral-500 dark:text-neutral-400 shrink-0"><?php echo e($key); ?></div>
|
||||
<div class="min-w-6 grow h-3 border-b-2 border-dotted border-neutral-300 dark:border-white/20"></div>
|
||||
<div class="truncate text-neutral-900 dark:text-white">
|
||||
<span data-tippy-content="<?php echo e($value); ?>">
|
||||
<?php echo e($value); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<?php if (isset($component)) { $__componentOriginal612ffe32146e3bd2ac6ba6076cca9520 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.empty-state','data' => ['message' => 'No routing context']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::empty-state'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['message' => 'No routing context']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520)): ?>
|
||||
<?php $attributes = $__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520; ?>
|
||||
<?php unset($__attributesOriginal612ffe32146e3bd2ac6ba6076cca9520); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal612ffe32146e3bd2ac6ba6076cca9520)): ?>
|
||||
<?php $component = $__componentOriginal612ffe32146e3bd2ac6ba6076cca9520; ?>
|
||||
<?php unset($__componentOriginal612ffe32146e3bd2ac6ba6076cca9520); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\routing.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['type' => 'default', 'variant' => 'soft']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['type' => 'default', 'variant' => 'soft']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$baseClasses = 'inline-flex w-fit shrink-0 items-center justify-center gap-1 font-mono leading-3 uppercase transition-colors dark:border [&_svg]:size-2.5 h-6 min-w-5 rounded-md px-1.5 text-xs/none';
|
||||
|
||||
$types = [
|
||||
'default' => [
|
||||
'soft' => 'bg-black/8 text-neutral-900 dark:border-neutral-700 dark:bg-white/10 dark:text-neutral-100',
|
||||
'solid' => 'bg-neutral-600 text-neutral-100 dark:border-neutral-500 dark:bg-neutral-600',
|
||||
],
|
||||
'success' => [
|
||||
'soft' => 'bg-emerald-200 text-emerald-900 dark:border-emerald-600 dark:bg-emerald-900/70 dark:text-emerald-400',
|
||||
'solid' => 'bg-emerald-600 dark:border-emerald-500 dark:bg-emerald-600',
|
||||
],
|
||||
'primary' => [
|
||||
'soft' => 'bg-blue-100 text-blue-900 dark:border-blue-800 dark:bg-blue-950 dark:text-blue-300',
|
||||
'solid' => 'bg-blue-700 dark:border-blue-600 dark:bg-blue-700',
|
||||
],
|
||||
'error' => [
|
||||
'soft' => 'bg-rose-200 text-rose-900 dark:border-rose-900 dark:bg-rose-950 dark:text-rose-100 dark:[&_svg]:!text-white',
|
||||
'solid' => 'bg-rose-600 dark:border-rose-500 dark:bg-rose-600',
|
||||
],
|
||||
'alert' => [
|
||||
'soft' => 'bg-amber-200 text-amber-900 dark:border-amber-800 dark:bg-amber-950 dark:text-amber-300',
|
||||
'solid' => 'bg-amber-600 dark:border-amber-500 dark:bg-amber-600',
|
||||
],
|
||||
'white' => [
|
||||
'soft' => 'bg-white text-neutral-900 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100',
|
||||
'solid' => 'bg-black/10 text-neutral-900 dark:text-neutral-900 dark:bg-white',
|
||||
],
|
||||
];
|
||||
|
||||
$variants = [
|
||||
'soft' => '',
|
||||
'solid' => 'text-white dark:text-white [&_svg]:!text-white',
|
||||
];
|
||||
|
||||
$typeClasses = $types[$type][$variant] ?? $types['default']['soft'];
|
||||
$variantClasses = $variants[$variant] ?? $variants['soft'];
|
||||
|
||||
$classes = implode(' ', [$baseClasses, $typeClasses, $variantClasses]);
|
||||
|
||||
?>
|
||||
|
||||
<div <?php echo e($attributes->merge(['class' => $classes])); ?>>
|
||||
<?php echo e($slot); ?>
|
||||
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\badge.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['title', 'markdown']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['title', 'markdown']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<script>
|
||||
const markdown = <?php echo e(Illuminate\Support\Js::from($markdown)); ?>
|
||||
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex items-center justify-between"
|
||||
x-data="{
|
||||
copied: false,
|
||||
async copyToClipboard() {
|
||||
try {
|
||||
await window.copyToClipboard(markdown);
|
||||
this.copied = true;
|
||||
setTimeout(() => { this.copied = false }, 3000);
|
||||
} catch (err) {
|
||||
console.error('Failed to copy the markdown: ', err);
|
||||
}
|
||||
}
|
||||
}"
|
||||
>
|
||||
<div class="flex items-center gap-2 h-[56px]">
|
||||
<div class="w-[18px] h-[18px] flex items-center justify-center bg-rose-500 rounded-md">
|
||||
<svg width="2" height="10" class="text-white" viewBox="0 0 2 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.00006 6.3188C1.41416 6.3188 1.75006 5.98295 1.75006 5.56885V1.43115C1.75006 1.01705 1.41416 0.681152 1.00006 0.681152C0.585961 0.681152 0.250061 1.01705 0.250061 1.43115V5.56885C0.250061 5.98295 0.585961 6.3188 1.00006 6.3188Z" fill="currentColor" />
|
||||
<path d="M1.00006 9.41699C1.55235 9.41699 2.00007 8.96929 2.00007 8.41699C2.00007 7.86469 1.55235 7.41699 1.00006 7.41699C0.447781 7.41699 6.10352e-05 7.86469 6.10352e-05 8.41699C6.10352e-05 8.96929 0.447781 9.41699 1.00006 9.41699Z" fill="currentColor "/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="font-medium text-sm text-neutral-900 dark:text-white">
|
||||
<?php echo e($title); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
x-cloak
|
||||
class="<?php echo \Illuminate\Support\Arr::toCssClasses([
|
||||
"text-sm rounded-md border px-3 h-8 flex items-center gap-2 transition-colors duration-200 ease-in-out cursor-pointer shadow-xs",
|
||||
"text-neutral-600 dark:text-neutral-400 bg-white/5 border-neutral-200 hover:bg-neutral-100 dark:bg-white/5 dark:border-white/10 dark:hover:bg-white/10",
|
||||
]); ?>"
|
||||
@click="copyToClipboard()"
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal8894ff2e6e6bd543865d608162806b35 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal8894ff2e6e6bd543865d608162806b35 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.copy','data' => ['class' => 'w-3 h-3','xShow' => '!copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.copy'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3','x-show' => '!copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $attributes = $__attributesOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__attributesOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $component = $__componentOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__componentOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal394a4f59b8774713925fcf456ba90b57 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal394a4f59b8774713925fcf456ba90b57 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.check','data' => ['class' => 'w-3 h-3 text-emerald-500','xShow' => 'copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.check'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3 text-emerald-500','x-show' => 'copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $attributes = $__attributesOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__attributesOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $component = $__componentOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__componentOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
<span x-text="copied ? 'Copied to clipboard' : 'Copy as Markdown'"></span>
|
||||
</button>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/topbar.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<g clip-path="url(#clip0_14732_6211)">
|
||||
<path d="M1.75 5.25V2.75C1.75 1.922 2.422 1.25 3.25 1.25H4.202C4.808 1.25 5.381 1.525 5.761 1.998L6.364 2.75H8.25C9.355 2.75 10.25 3.645 10.25 4.75V5.25" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.46801 5.25H9.53101C10.44 5.25 11.14 6.052 11.017 6.953L10.735 9.021C10.6 10.012 9.75301 10.751 8.75301 10.751H3.24601C2.24601 10.751 1.39901 10.012 1.26401 9.021L0.982011 6.953C0.859011 6.052 1.55901 5.25 2.46801 5.25Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_14732_6211">
|
||||
<rect width="12" height="12" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/folder-open.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="6" height="10" viewBox="0 0 6 10" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M0.875 9.25L5.125 5L0.875 0.75" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\chevron-right.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 428 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M9.75 2.56944C9.75 3.29815 8.07107 3.88889 6 3.88889C3.92893 3.88889 2.25 3.29815 2.25 2.56944M9.75 2.56944C9.75 1.84074 8.07107 1.25 6 1.25C3.92893 1.25 2.25 1.84074 2.25 2.56944M9.75 2.56944V9.43056C9.75 10.1593 8.07107 10.75 6 10.75C3.92893 10.75 2.25 10.1593 2.25 9.43056V2.56944M9.75 5.94434C9.75 6.67304 8.07107 7.26378 6 7.26378C3.92893 7.26378 2.25 6.67304 2.25 5.94434" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\database.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 772 B |
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M5.99996 10.6876C7.10936 10.6876 8.00871 8.58896 8.00871 6.00012C8.00871 3.41129 7.10936 1.31262 5.99996 1.31262C4.89056 1.31262 3.99121 3.41129 3.99121 6.00012C3.99121 8.58896 4.89056 10.6876 5.99996 10.6876Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M1.3125 6.00012H10.6875" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 10.6876C8.58883 10.6876 10.6875 8.58896 10.6875 6.00012C10.6875 3.41129 8.58883 1.31262 6 1.31262C3.41117 1.31262 1.3125 3.41129 1.3125 6.00012C1.3125 8.58896 3.41117 10.6876 6 10.6876Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\globe.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 984 B |
|
|
@ -0,0 +1,20 @@
|
|||
<?php if($paginator->hasPages()): ?>
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
|
||||
<?php if($paginator->onFirstPage()): ?>
|
||||
<li class="disabled" aria-disabled="true"><span><?php echo app('translator')->get('pagination.previous'); ?></span></li>
|
||||
<?php else: ?>
|
||||
<li><a href="<?php echo e($paginator->previousPageUrl()); ?>" rel="prev"><?php echo app('translator')->get('pagination.previous'); ?></a></li>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php if($paginator->hasMorePages()): ?>
|
||||
<li><a href="<?php echo e($paginator->nextPageUrl()); ?>" rel="next"><?php echo app('translator')->get('pagination.next'); ?></a></li>
|
||||
<?php else: ?>
|
||||
<li class="disabled" aria-disabled="true"><span><?php echo app('translator')->get('pagination.next'); ?></span></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Pagination\resources\views\simple-bootstrap-3.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['frame', 'direction' => 'ltr']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['frame', 'direction' => 'ltr']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<?php
|
||||
$file = $frame->file();
|
||||
$line = $frame->line();
|
||||
?>
|
||||
|
||||
<div
|
||||
<?php echo e($attributes->merge(['class' => 'truncate font-mono text-xs text-neutral-500 dark:text-neutral-400'])); ?>
|
||||
|
||||
dir="<?php echo e($direction); ?>"
|
||||
>
|
||||
<span data-tippy-content="<?php echo e($file); ?>:<?php echo e($line); ?>">
|
||||
<?php if(config('app.editor')): ?>
|
||||
<a href="<?php echo e($frame->editorHref()); ?>" @click.stop>
|
||||
<span class="hover:underline decoration-neutral-400"><?php echo e($file); ?></span><span class="text-neutral-500">:<?php echo e($line); ?></span>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<?php echo e($file); ?><span class="text-neutral-500">:<?php echo e($line); ?></span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/file-with-line.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['code', 'highlightedLine']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['code', 'highlightedLine']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div
|
||||
class="text-sm rounded-b-lg bg-neutral-50 border-t border-neutral-100 dark:bg-neutral-900 dark:border-white/10"
|
||||
<?php echo e($attributes); ?>
|
||||
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal12cb286571f553eebcbe98210b217f94 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal12cb286571f553eebcbe98210b217f94 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.syntax-highlight','data' => ['code' => $code,'language' => 'php','editor' => true,'startingLine' => max(1, $highlightedLine - 5),'highlightedLine' => min(5, $highlightedLine - 1),'class' => 'overflow-x-auto']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::syntax-highlight'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['code' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($code),'language' => 'php','editor' => true,'starting-line' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute(max(1, $highlightedLine - 5)),'highlighted-line' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute(min(5, $highlightedLine - 1)),'class' => 'overflow-x-auto']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $attributes = $__attributesOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__attributesOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal12cb286571f553eebcbe98210b217f94)): ?>
|
||||
<?php $component = $__componentOriginal12cb286571f553eebcbe98210b217f94; ?>
|
||||
<?php unset($__componentOriginal12cb286571f553eebcbe98210b217f94); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/frame-code.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['exception', 'request']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['exception', 'request']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div
|
||||
x-data="{
|
||||
copied: false,
|
||||
async copyToClipboard() {
|
||||
try {
|
||||
await window.copyToClipboard('<?php echo e($request->fullUrl()); ?>');
|
||||
this.copied = true;
|
||||
setTimeout(() => { this.copied = false }, 3000);
|
||||
} catch (err) {
|
||||
console.error('Failed to copy the requestURL: ', err);
|
||||
}
|
||||
}
|
||||
}"
|
||||
<?php echo e($attributes->merge(['class' => "bg-white dark:bg-[#1a1a1a] border border-neutral-200 dark:border-white/10 rounded-lg flex items-center justify-between h-10 px-2 shadow-xs"])); ?>
|
||||
|
||||
>
|
||||
<div class="flex items-center gap-3 w-full">
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => 'error','variant' => 'solid']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => 'error','variant' => 'solid']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalebc8ec9a834a8051f56913d6745a7050 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalebc8ec9a834a8051f56913d6745a7050 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.alert','data' => ['class' => 'w-2.5 h-2.5']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.alert'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $attributes = $__attributesOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $component = $__componentOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__componentOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo e($exception->httpStatusCode()); ?>
|
||||
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.http-method','data' => ['method' => ''.e($request->method()).'']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::http-method'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['method' => ''.e($request->method()).'']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413)): ?>
|
||||
<?php $attributes = $__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413; ?>
|
||||
<?php unset($__attributesOriginal5131cdd8ffd44ce9fe7ed2c3030dd413); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413)): ?>
|
||||
<?php $component = $__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413; ?>
|
||||
<?php unset($__componentOriginal5131cdd8ffd44ce9fe7ed2c3030dd413); ?>
|
||||
<?php endif; ?>
|
||||
<div class="flex-1 text-sm font-light truncate text-neutral-950 dark:text-white">
|
||||
<span data-tippy-content="<?php echo e($request->fullUrl()); ?>">
|
||||
<?php echo e($request->fullUrl()); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
x-cloak
|
||||
@click="copyToClipboard()"
|
||||
class="<?php echo \Illuminate\Support\Arr::toCssClasses([
|
||||
"rounded-md w-6 h-6 flex flex-shrink-0 items-center justify-center cursor-pointer border transition-colors duration-200 ease-in-out",
|
||||
"bg-white/5 border-neutral-200 hover:bg-neutral-100 dark:bg-white/5 dark:border-white/10 dark:hover:bg-white/10",
|
||||
]); ?>"
|
||||
>
|
||||
<?php if (isset($component)) { $__componentOriginal8894ff2e6e6bd543865d608162806b35 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal8894ff2e6e6bd543865d608162806b35 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.copy','data' => ['class' => 'w-3 h-3 text-neutral-400','xShow' => '!copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.copy'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3 text-neutral-400','x-show' => '!copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $attributes = $__attributesOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__attributesOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal8894ff2e6e6bd543865d608162806b35)): ?>
|
||||
<?php $component = $__componentOriginal8894ff2e6e6bd543865d608162806b35; ?>
|
||||
<?php unset($__componentOriginal8894ff2e6e6bd543865d608162806b35); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal394a4f59b8774713925fcf456ba90b57 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal394a4f59b8774713925fcf456ba90b57 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.check','data' => ['class' => 'w-3 h-3 text-emerald-500','xShow' => 'copied']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.check'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-3 h-3 text-emerald-500','x-show' => 'copied']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $attributes = $__attributesOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__attributesOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal394a4f59b8774713925fcf456ba90b57)): ?>
|
||||
<?php $component = $__componentOriginal394a4f59b8774713925fcf456ba90b57; ?>
|
||||
<?php unset($__componentOriginal394a4f59b8774713925fcf456ba90b57); ?>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/request-url.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="6" height="10" viewBox="0 0 6 10" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M5.125 0.75L0.875 5L5.125 9.25" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/chevron-left.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 440 B |
|
|
@ -0,0 +1,28 @@
|
|||
<?php use \Illuminate\Foundation\Exceptions\Renderer\Renderer; ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
|
||||
|
||||
<title><?php echo e(config('app.name', 'Laravel')); ?></title>
|
||||
|
||||
<link
|
||||
rel="icon" type="image/svg+xml"
|
||||
href="data:image/svg+xml,%3Csvg viewBox='0 -.11376601 49.74245785 51.31690859' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m49.626 11.564a.809.809 0 0 1 .028.209v10.972a.8.8 0 0 1 -.402.694l-9.209 5.302v10.509c0 .286-.152.55-.4.694l-19.223 11.066c-.044.025-.092.041-.14.058-.018.006-.035.017-.054.022a.805.805 0 0 1 -.41 0c-.022-.006-.042-.018-.063-.026-.044-.016-.09-.03-.132-.054l-19.219-11.066a.801.801 0 0 1 -.402-.694v-32.916c0-.072.01-.142.028-.21.006-.023.02-.044.028-.067.015-.042.029-.085.051-.124.015-.026.037-.047.055-.071.023-.032.044-.065.071-.093.023-.023.053-.04.079-.06.029-.024.055-.05.088-.069h.001l9.61-5.533a.802.802 0 0 1 .8 0l9.61 5.533h.002c.032.02.059.045.088.068.026.02.055.038.078.06.028.029.048.062.072.094.017.024.04.045.054.071.023.04.036.082.052.124.008.023.022.044.028.068a.809.809 0 0 1 .028.209v20.559l8.008-4.611v-10.51c0-.07.01-.141.028-.208.007-.024.02-.045.028-.068.016-.042.03-.085.052-.124.015-.026.037-.047.054-.071.024-.032.044-.065.072-.093.023-.023.052-.04.078-.06.03-.024.056-.05.088-.069h.001l9.611-5.533a.801.801 0 0 1 .8 0l9.61 5.533c.034.02.06.045.09.068.025.02.054.038.077.06.028.029.048.062.072.094.018.024.04.045.054.071.023.039.036.082.052.124.009.023.022.044.028.068zm-1.574 10.718v-9.124l-3.363 1.936-4.646 2.675v9.124l8.01-4.611zm-9.61 16.505v-9.13l-4.57 2.61-13.05 7.448v9.216zm-36.84-31.068v31.068l17.618 10.143v-9.214l-9.204-5.209-.003-.002-.004-.002c-.031-.018-.057-.044-.086-.066-.025-.02-.054-.036-.076-.058l-.002-.003c-.026-.025-.044-.056-.066-.084-.02-.027-.044-.05-.06-.078l-.001-.003c-.018-.03-.029-.066-.042-.1-.013-.03-.03-.058-.038-.09v-.001c-.01-.038-.012-.078-.016-.117-.004-.03-.012-.06-.012-.09v-21.483l-4.645-2.676-3.363-1.934zm8.81-5.994-8.007 4.609 8.005 4.609 8.006-4.61-8.006-4.608zm4.164 28.764 4.645-2.674v-20.096l-3.363 1.936-4.646 2.675v20.096zm24.667-23.325-8.006 4.609 8.006 4.609 8.005-4.61zm-.801 10.605-4.646-2.675-3.363-1.936v9.124l4.645 2.674 3.364 1.937zm-18.422 20.561 11.743-6.704 5.87-3.35-8-4.606-9.211 5.303-8.395 4.833z' fill='%23ff2d20'/%3E%3C/svg%3E"
|
||||
/>
|
||||
|
||||
<?php echo Renderer::css(); ?>
|
||||
|
||||
</head>
|
||||
<body class="font-sans antialiased overflow-x-hidden bg-neutral-50 dark:bg-neutral-900 dark:text-white scheme-light-dark">
|
||||
<div class="min-h-dvh">
|
||||
<?php echo e($slot); ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php echo Renderer::js(); ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\layout.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,865 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kelola Users - Dashboard JTI</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #eef2ff;
|
||||
--panel: rgba(255, 255, 255, 0.9);
|
||||
--panel-strong: #ffffff;
|
||||
--text: #1f2937;
|
||||
--muted: #6b7280;
|
||||
--primary: #4f46e5;
|
||||
--primary-2: #7c3aed;
|
||||
--green: #059669;
|
||||
--orange: #d97706;
|
||||
--shadow: 0 24px 70px rgba(31, 41, 55, 0.18);
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(99, 102, 241, 0.25), transparent 35%),
|
||||
radial-gradient(circle at top right, rgba(168, 85, 247, 0.18), transparent 32%),
|
||||
linear-gradient(135deg, #e0e7ff 0%, #eef2ff 45%, #f8fafc 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page-shell {
|
||||
min-height: 100vh;
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
height: fit-content;
|
||||
position: sticky;
|
||||
top: 18px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.sidebar.hidden {
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 16px 18px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sidebar-menu li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-menu a:hover {
|
||||
background: rgba(79, 70, 229, 0.08);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-menu a.active {
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 16px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
border: 0;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 1.5rem;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text);
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s ease;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.sidebar-toggle:hover {
|
||||
color: var(--primary);
|
||||
transform: scale(1.15) rotate(90deg);
|
||||
}
|
||||
|
||||
.sidebar-toggle.active {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.sidebar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.main-content > header {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 14px 18px;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow: 0 10px 35px rgba(79, 70, 229, 0.08);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-shell.sidebar-hidden .sidebar-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
|
||||
|
||||
.brand-mark {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 24px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.brand-text h1 { font-size: 1.05rem; line-height: 1.1; color: var(--text); }
|
||||
.brand-text p { margin-top: 2px; color: var(--muted); font-size: 0.9rem; }
|
||||
|
||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
|
||||
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
padding: 11px 16px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(79, 70, 229, 0.18);
|
||||
}
|
||||
|
||||
.btn.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
}
|
||||
|
||||
.btn.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--orange) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 12px 22px rgba(217, 119, 6, 0.18);
|
||||
}
|
||||
|
||||
.content {
|
||||
border-radius: 28px;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
backdrop-filter: blur(16px);
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 22px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.1), rgba(124, 58, 237, 0.08));
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.section-head h2 { font-size: 1.35rem; color: var(--text); }
|
||||
.section-head p { margin-top: 4px; color: var(--muted); font-size: 0.95rem; }
|
||||
|
||||
.filters {
|
||||
padding: 18px 26px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.16);
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 220px 180px auto;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field label { display: block; font-size: 0.9rem; font-weight: 800; color: #475569; margin-bottom: 6px; }
|
||||
.input, .select {
|
||||
width: 100%;
|
||||
padding: 11px 12px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
outline: none;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin: 18px 26px 0;
|
||||
padding: 14px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(5, 150, 105, 0.08);
|
||||
border: 1px solid rgba(5, 150, 105, 0.18);
|
||||
color: #065f46;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.table-wrap { padding: 18px 26px 26px; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
text-align: left;
|
||||
padding: 16px 18px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 900;
|
||||
color: #475569;
|
||||
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
||||
border-bottom: 2px solid rgba(148, 163, 184, 0.2);
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
transition: all 0.3s ease;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
||||
}
|
||||
|
||||
tbody tr:hover {
|
||||
background: rgba(79, 70, 229, 0.04);
|
||||
box-shadow: inset 0 0 12px rgba(79, 70, 229, 0.08);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background: rgba(248, 250, 252, 0.5);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even):hover {
|
||||
background: rgba(79, 70, 229, 0.06);
|
||||
}
|
||||
|
||||
tbody td {
|
||||
padding: 14px 18px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
||||
vertical-align: middle;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
tbody tr:last-child td { border-bottom: 0; }
|
||||
|
||||
.avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 14px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 10px 24px rgba(79, 70, 229, 0.28);
|
||||
border: 2.5px solid rgba(255, 255, 255, 0.35);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 1.25rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
tbody tr:hover .avatar {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 14px 32px rgba(79, 70, 229, 0.35);
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
color: #fff;
|
||||
font-weight: 900;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.meta { color: var(--muted); font-weight: 700; font-size: 0.85rem; margin-top: 6px; letter-spacing: 0.3px; }
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
padding: 8px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-2) 100%);
|
||||
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.22);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.pill:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(79, 70, 229, 0.28);
|
||||
}
|
||||
|
||||
.pill.dosen {
|
||||
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
|
||||
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.22);
|
||||
}
|
||||
|
||||
.pill.dosen:hover {
|
||||
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.28);
|
||||
}
|
||||
|
||||
.pill.teknisi {
|
||||
background: linear-gradient(135deg, #10b981 0%, #14b8a6 100%);
|
||||
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.22);
|
||||
}
|
||||
|
||||
.pill.teknisi:hover {
|
||||
box-shadow: 0 6px 16px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.pill.staff {
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #f97316 100%);
|
||||
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.22);
|
||||
}
|
||||
|
||||
.pill.staff:hover {
|
||||
box-shadow: 0 6px 16px rgba(245, 158, 11, 0.28);
|
||||
}
|
||||
|
||||
.row-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
|
||||
|
||||
.btn-sm {
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
padding: 10px 14px;
|
||||
font-weight: 900;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 0.3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.btn-sm:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.btn-sm:active {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn-sm.ghost {
|
||||
color: #475569;
|
||||
background: rgba(226, 232, 240, 0.8);
|
||||
border: 1.5px solid rgba(148, 163, 184, 0.3);
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.btn-sm.ghost:hover {
|
||||
background: rgba(226, 232, 240, 1);
|
||||
border-color: rgba(99, 102, 241, 0.5);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.btn-sm.success {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||||
box-shadow: 0 6px 16px rgba(16, 185, 129, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.success:hover {
|
||||
box-shadow: 0 8px 24px rgba(16, 185, 129, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.warning {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
|
||||
box-shadow: 0 6px 16px rgba(245, 158, 11, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.warning:hover {
|
||||
box-shadow: 0 8px 24px rgba(245, 158, 11, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.primary {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
box-shadow: 0 6px 16px rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.primary:hover {
|
||||
box-shadow: 0 8px 24px rgba(59, 130, 246, 0.28);
|
||||
}
|
||||
|
||||
.btn-sm.danger {
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
||||
box-shadow: 0 6px 16px rgba(239, 68, 68, 0.2);
|
||||
}
|
||||
|
||||
.btn-sm.danger:hover {
|
||||
box-shadow: 0 8px 24px rgba(239, 68, 68, 0.28);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.12);
|
||||
}
|
||||
|
||||
.pager {
|
||||
display: inline-flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.page-shell { grid-template-columns: 1fr; }
|
||||
.sidebar { position: static; }
|
||||
.filters-row { grid-template-columns: 1fr; }
|
||||
.actions { justify-content: stretch; }
|
||||
.btn { width: 100%; }
|
||||
}
|
||||
|
||||
.welcome-section {
|
||||
padding: 32px 26px;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.08) 0%, rgba(124, 58, 237, 0.06) 100%);
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.15);
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 24px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.welcome-text h3 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 900;
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.welcome-text p {
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 14px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.welcome-stats {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(148, 163, 184, 0.12);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
background: linear-gradient(135deg, rgba(79, 70, 229, 0.15), rgba(124, 58, 237, 0.1));
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 900;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.75rem;
|
||||
color: var(--muted);
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
font-size: 5rem;
|
||||
opacity: 0.15;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$makeInitial = static function (?string $nama): string {
|
||||
$nama = trim((string) $nama);
|
||||
if ($nama === '') return 'NA';
|
||||
$parts = preg_split('/\s+/', $nama) ?: [];
|
||||
$initials = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($part === '') continue;
|
||||
$initials .= strtoupper(substr($part, 0, 1));
|
||||
if (strlen($initials) >= 2) break;
|
||||
}
|
||||
return $initials !== '' ? $initials : 'NA';
|
||||
};
|
||||
|
||||
$resolveFoto = static function (?string $foto): ?string {
|
||||
$foto = trim((string) $foto);
|
||||
if ($foto === '') return null;
|
||||
if (preg_match('~^(https?://|data:|//)~i', $foto)) return $foto;
|
||||
if (str_starts_with($foto, '/')) return $foto;
|
||||
return asset($foto);
|
||||
};
|
||||
?>
|
||||
|
||||
<div class="page-shell sidebar-hidden">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="sidebar hidden">
|
||||
<div class="sidebar-card">
|
||||
<div class="sidebar-top">
|
||||
<button class="sidebar-toggle" id="sidebarToggle" title="Toggle Sidebar">✕</button>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="<?php echo e(route('users.index')); ?>" class="active"><span class="sidebar-icon">🏠</span> Home</a></li>
|
||||
<li><a href="<?php echo e(route('users.dosen')); ?>"><span class="sidebar-icon">👨🏫</span> CRUD Dosen</a></li>
|
||||
<li><a href="<?php echo e(route('users.staff')); ?>"><span class="sidebar-icon">🔧</span> CRUD Staff/Teknisi</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content">
|
||||
<header class="topbar">
|
||||
<button class="sidebar-toggle sidebar-open" id="sidebarOpen" title="Buka Sidebar">☰</button>
|
||||
<a class="brand" href="<?php echo e(url('/dashboard')); ?>">
|
||||
<div class="brand-mark">JTI</div>
|
||||
<div class="brand-text">
|
||||
<h1>Kelola Users</h1>
|
||||
<p>Lihat semua data dosen, staff dan teknisi</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="actions"></div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Daftar Users</h2>
|
||||
<p>Gunakan filter untuk mencari dan batasi jumlah data.</p>
|
||||
</div>
|
||||
<div class="meta">Total: <?php echo e($totalCount ?? 0); ?></div>
|
||||
</div>
|
||||
|
||||
<div class="welcome-section">
|
||||
<div class="welcome-content">
|
||||
<div class="welcome-text">
|
||||
<h3>🎉 Selamat Datang di Admin Panel</h3>
|
||||
<p>Kelola semua data dosen, staff, dan teknisi dengan mudah. Cari, filter, dan kelola informasi pengguna dalam satu tempat yang terintegrasi.</p>
|
||||
</div>
|
||||
<div class="welcome-icon">👥</div>
|
||||
</div>
|
||||
<div class="welcome-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">👨🏫</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number"><?php echo e($totalCount); ?></span>
|
||||
<span class="stat-label">Total Users</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">📊</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number">3</span>
|
||||
<span class="stat-label">Kategori</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">⚙️</div>
|
||||
<div class="stat-value">
|
||||
<span class="stat-number">∞</span>
|
||||
<span class="stat-label">Fitur</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="filters" method="GET" action="<?php echo e(route('users.index')); ?>">
|
||||
<div class="filters-row">
|
||||
<div class="field">
|
||||
<label for=" q">Cari</label>
|
||||
<input id="q" class="input" type="text" name="q" value="<?php echo e($q); ?>" placeholder="Nama / NIP / NIDN">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="role">Role</label>
|
||||
<select id="role" class="select" name="role">
|
||||
<option value="">Semua</option>
|
||||
<?php $__currentLoopData = $roleOptions; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $opt): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($opt); ?>" <?php if($role === $opt): echo 'selected'; endif; ?>><?php echo e(ucfirst($opt)); ?></option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="per_page">Per Halaman</label>
|
||||
<select id="per_page" class="select" name="per_page">
|
||||
<?php $__currentLoopData = ['10','25','50','100','all']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $size): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($size); ?>" <?php if($perPage === $size): echo 'selected'; endif; ?>>
|
||||
<?php echo e($size === 'all' ? 'Semua' : $size); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<button class="btn primary" type="submit">Terapkan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a class="btn ghost" href="<?php echo e(route('users.index')); ?>">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="notice"><?php echo e(session('success')); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 80px;">Foto</th>
|
||||
<th style="flex: 1; min-width: 280px;">Nama</th>
|
||||
<th style="width: 160px;">NIP</th>
|
||||
<th style="width: 140px;">NIDN</th>
|
||||
<th style="width: 110px;">Role</th>
|
||||
<th style="width: 160px;">Waktu Input</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__empty_1 = true; $__currentLoopData = $users; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php ($fotoUrl = $resolveFoto($item->foto)); ?>
|
||||
<div class="avatar" <?php if($fotoUrl): ?> style="background-image: url('<?php echo e($fotoUrl); ?>')" <?php endif; ?>>
|
||||
<?php if(!$fotoUrl): ?>
|
||||
<div class="avatar-placeholder"><?php echo e($makeInitial($item->nama)); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div style="font-weight: 900; font-size: 1.05rem; color: #1f2937; line-height: 1.4;"><?php echo e($item->nama); ?></div>
|
||||
<div class="meta" style="font-size: 0.8rem;">ID: <?php echo e($item->id); ?></div>
|
||||
</td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #475569;"><?php echo e($item->nip ?? '-'); ?></td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #475569;"><?php echo e($item->nidn ?? '-'); ?></td>
|
||||
<td>
|
||||
<?php ($r = (string) ($item->role ?? 'staff')); ?>
|
||||
<?php ($r = in_array($r, ['dosen', 'teknisi', 'staff'], true) ? $r : 'staff'); ?>
|
||||
<span class="pill <?php echo e($r); ?>"><?php echo e(ucfirst($r)); ?></span>
|
||||
</td>
|
||||
<td style="font-family: 'Monaco', 'Courier New', monospace; color: #6b7280; font-size: 0.95rem;">
|
||||
<?php echo e($item->created_at ? $item->created_at->format('d M Y H:i') : '-'); ?>
|
||||
|
||||
<div class="meta" style="font-size: 0.75rem; margin-top: 4px;"><?php echo e($item->created_at ? $item->created_at->diffForHumans() : '-'); ?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<tr>
|
||||
<td colspan="6" style="text-align: center; padding: 48px 18px;">
|
||||
<div style="color: var(--muted); font-size: 1.1rem; font-weight: 700;">📭 Belum ada data</div>
|
||||
<div style="color: #9ca3af; font-size: 0.9rem; margin-top: 8px;">Coba ubah filter atau tambahkan data baru untuk memulai</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<div>
|
||||
Menampilkan <?php echo e($users->firstItem() ?? 0); ?>–<?php echo e($users->lastItem() ?? 0); ?> dari <?php echo e($totalCount ?? 0); ?>
|
||||
|
||||
</div>
|
||||
<div class="pager">
|
||||
<?php if($users->currentPage() == 1): ?>
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Sebelumnya</span>
|
||||
<?php else: ?>
|
||||
<a class="btn-sm ghost" href="<?php echo e($users->previousPageUrl()); ?>">Sebelumnya</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($users->lastPage() > $users->currentPage()): ?>
|
||||
<a class="btn-sm ghost" href="<?php echo e($users->nextPageUrl()); ?>">Berikutnya</a>
|
||||
<?php else: ?>
|
||||
<span class="btn-sm ghost" style="opacity:0.6; cursor:not-allowed;">Berikutnya</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const sidebarToggle = document.getElementById('sidebarToggle');
|
||||
const sidebarOpen = document.getElementById('sidebarOpen');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const pageShell = document.querySelector('.page-shell');
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebar.classList.toggle('hidden');
|
||||
pageShell.classList.toggle('sidebar-hidden');
|
||||
sidebarToggle.classList.toggle('active');
|
||||
sidebarOpen.classList.toggle('active');
|
||||
}
|
||||
|
||||
if (sidebarToggle) sidebarToggle.addEventListener('click', toggleSidebar);
|
||||
if (sidebarOpen) sidebarOpen.addEventListener('click', toggleSidebar);
|
||||
|
||||
// Close sidebar when clicking on a menu link
|
||||
const menuLinks = document.querySelectorAll('.sidebar-menu a');
|
||||
menuLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
if (!sidebar.classList.contains('hidden')) {
|
||||
toggleSidebar();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\resources\views/user/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M4.75 1L0.75 5L4.75 9" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.25 1L5.25 5L9.25 9" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\icons\chevrons-left.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 528 B |
|
|
@ -0,0 +1,157 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['exception']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['exception']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="flex flex-col pt-8 sm:pt-16 overflow-x-auto">
|
||||
<div class="flex flex-col gap-5 mb-8">
|
||||
<h1 class="text-3xl font-semibold text-neutral-950 dark:text-white"><?php echo e($exception->class()); ?></h1>
|
||||
<?php if (isset($component)) { $__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.file-with-line','data' => ['frame' => $exception->frames()->first(),'class' => '-mt-3 text-xs']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::file-with-line'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['frame' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->frames()->first()),'class' => '-mt-3 text-xs']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d)): ?>
|
||||
<?php $attributes = $__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d; ?>
|
||||
<?php unset($__attributesOriginalfe2bc8d0a6d110d41fdc8740012cee8d); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d)): ?>
|
||||
<?php $component = $__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d; ?>
|
||||
<?php unset($__componentOriginalfe2bc8d0a6d110d41fdc8740012cee8d); ?>
|
||||
<?php endif; ?>
|
||||
<p class="text-xl font-light text-neutral-800 dark:text-neutral-300">
|
||||
<?php echo e($exception->message()); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start gap-2 mb-8 sm:mb-16">
|
||||
<div class="bg-white dark:bg-white/[3%] border border-neutral-200 dark:border-white/10 divide-x divide-neutral-200 dark:divide-white/10 rounded-md shadow-xs flex items-center gap-0.5">
|
||||
<div class="flex items-center gap-1.5 h-6 px-[6px] font-mono text-[13px]">
|
||||
<span class="text-neutral-400 dark:text-neutral-500">LARAVEL</span>
|
||||
<span class="text-neutral-500 dark:text-neutral-300"><?php echo e(app()->version()); ?></span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 h-6 px-[6px] font-mono text-[13px]">
|
||||
<span class="text-neutral-400 dark:text-neutral-500">PHP</span>
|
||||
<span class="text-neutral-500 dark:text-neutral-300"><?php echo e(PHP_VERSION); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => 'error']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => 'error']); ?>
|
||||
<?php if (isset($component)) { $__componentOriginalebc8ec9a834a8051f56913d6745a7050 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalebc8ec9a834a8051f56913d6745a7050 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.icons.alert','data' => ['class' => 'w-2.5 h-2.5']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::icons.alert'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['class' => 'w-2.5 h-2.5']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $attributes = $__attributesOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__attributesOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalebc8ec9a834a8051f56913d6745a7050)): ?>
|
||||
<?php $component = $__componentOriginalebc8ec9a834a8051f56913d6745a7050; ?>
|
||||
<?php unset($__componentOriginalebc8ec9a834a8051f56913d6745a7050); ?>
|
||||
<?php endif; ?>
|
||||
UNHANDLED
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($component)) { $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.badge','data' => ['type' => 'error','variant' => 'solid']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::badge'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['type' => 'error','variant' => 'solid']); ?>
|
||||
CODE <?php echo e($exception->code()); ?>
|
||||
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $attributes = $__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__attributesOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb)): ?>
|
||||
<?php $component = $__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb; ?>
|
||||
<?php unset($__componentOriginal0bc865510ef3ecddbe48edc4e8cc9ddb); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (isset($component)) { $__componentOriginalb581a7e3a55d371fae986833ecafa668 = $component; } ?>
|
||||
<?php if (isset($attributes)) { $__attributesOriginalb581a7e3a55d371fae986833ecafa668 = $attributes; } ?>
|
||||
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'laravel-exceptions-renderer::components.request-url','data' => ['exception' => $exception,'request' => $exception->request(),'class' => 'relative z-50']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
|
||||
<?php $component->withName('laravel-exceptions-renderer::request-url'); ?>
|
||||
<?php if ($component->shouldRender()): ?>
|
||||
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
|
||||
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
|
||||
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
|
||||
<?php endif; ?>
|
||||
<?php $component->withAttributes(['exception' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception),'request' => \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($exception->request()),'class' => 'relative z-50']); ?>
|
||||
<?php echo $__env->renderComponent(); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__attributesOriginalb581a7e3a55d371fae986833ecafa668)): ?>
|
||||
<?php $attributes = $__attributesOriginalb581a7e3a55d371fae986833ecafa668; ?>
|
||||
<?php unset($__attributesOriginalb581a7e3a55d371fae986833ecafa668); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($__componentOriginalb581a7e3a55d371fae986833ecafa668)): ?>
|
||||
<?php $component = $__componentOriginalb581a7e3a55d371fae986833ecafa668; ?>
|
||||
<?php unset($__componentOriginalb581a7e3a55d371fae986833ecafa668); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/header.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<div <?php echo e($attributes->merge(['class' => "h-0 w-full relative"])); ?>>
|
||||
<div class="absolute top-[-1px] left-0 right-0 bottom-0 border-t border-dashed border-neutral-300 dark:border-white/[9%]"></div>
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\separator.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php $attributes ??= new \Illuminate\View\ComponentAttributeBag;
|
||||
|
||||
$__newAttributes = [];
|
||||
$__propNames = \Illuminate\View\ComponentAttributeBag::extractPropNames((['message']));
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (in_array($__key, $__propNames)) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
} else {
|
||||
$__newAttributes[$__key] = $__value;
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = new \Illuminate\View\ComponentAttributeBag($__newAttributes);
|
||||
|
||||
unset($__propNames);
|
||||
unset($__newAttributes);
|
||||
|
||||
foreach (array_filter((['message']), 'is_string', ARRAY_FILTER_USE_KEY) as $__key => $__value) {
|
||||
$$__key = $$__key ?? $__value;
|
||||
}
|
||||
|
||||
$__defined_vars = get_defined_vars();
|
||||
|
||||
foreach ($attributes->all() as $__key => $__value) {
|
||||
if (array_key_exists($__key, $__defined_vars)) unset($$__key);
|
||||
}
|
||||
|
||||
unset($__defined_vars, $__key, $__value); ?>
|
||||
|
||||
<div class="bg-white/[2%] border border-neutral-200 dark:border-neutral-800 rounded-md w-full p-5 uppercase text-sm text-center font-mono shadow-xs text-neutral-600 dark:text-neutral-400">
|
||||
<span class="text-neutral-400 dark:text-neutral-600">// </span><?php echo e($message); ?>
|
||||
|
||||
</div>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\resources\exceptions\renderer\components\empty-state.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" <?php echo e($attributes); ?>>
|
||||
<path d="M5.99996 10.6876C7.10936 10.6876 8.00871 8.58896 8.00871 6.00012C8.00871 3.41129 7.10936 1.31262 5.99996 1.31262C4.89056 1.31262 3.99121 3.41129 3.99121 6.00012C3.99121 8.58896 4.89056 10.6876 5.99996 10.6876Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M1.3125 6.00012H10.6875" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 10.6876C8.58883 10.6876 10.6875 8.58896 10.6875 6.00012C10.6875 3.41129 8.58883 1.31262 6 1.31262C3.41117 1.31262 1.3125 3.41129 1.3125 6.00012C1.3125 8.58896 3.41117 10.6876 6 10.6876Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<?php /**PATH F:\Sempro TA\project\Laravel\TA\vendor\laravel\framework\src\Illuminate\Foundation\Providers/../resources/exceptions/renderer/components/icons/globe.blade.php ENDPATH**/ ?>
|
||||
|
After Width: | Height: | Size: 997 B |