Initial commit for combined ProjectKP
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
|
||||
@source '../../storage/framework/views/*.php';
|
||||
@source '../**/*.blade.php';
|
||||
@source '../**/*.js';
|
||||
|
||||
@theme {
|
||||
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
//
|
||||
@@ -0,0 +1,60 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
{{-- Flex container untuk menarik konten ke tengah horizontal --}}
|
||||
<div class="flex justify-center items-center w-full pb-20">
|
||||
|
||||
<div class="w-full max-w-lg"> {{-- max-w-lg membatasi lebar form supaya simetris --}}
|
||||
|
||||
<div class="mb-8 text-center">
|
||||
<h1 class="text-3xl font-extrabold text-[#0D215C] tracking-tight">Tambah Petugas Baru</h1>
|
||||
<p class="text-slate-500 mt-2 font-medium">Buat akun untuk pengawas lapangan</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-[2.5rem] shadow-2xl shadow-slate-200/60 border border-slate-100 overflow-hidden">
|
||||
<div class="p-8 md:p-12">
|
||||
|
||||
<form action="{{ route('admin.users.store') }}" method="POST" class="space-y-6">
|
||||
@csrf
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-[11px] font-black text-slate-400 uppercase tracking-[2px] ml-1">Nama Lengkap</label>
|
||||
<input type="text" name="name"
|
||||
class="w-full px-6 py-4 bg-[#F2F5FB] border-none rounded-2xl focus:ring-4 focus:ring-[#0D215C]/10 transition-all outline-none text-slate-700 placeholder:text-slate-300"
|
||||
placeholder="Contoh: Budi Santoso" required>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-[11px] font-black text-slate-400 uppercase tracking-[2px] ml-1">Username</label>
|
||||
<input type="text" name="username"
|
||||
class="w-full px-6 py-4 bg-[#F2F5FB] border-none rounded-2xl focus:ring-4 focus:ring-[#0D215C]/10 transition-all outline-none text-slate-700 placeholder:text-slate-300"
|
||||
placeholder="budi_petugas" required>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-[11px] font-black text-slate-400 uppercase tracking-[2px] ml-1">Password</label>
|
||||
<input type="password" name="password"
|
||||
class="w-full px-6 py-4 bg-[#F2F5FB] border-none rounded-2xl focus:ring-4 focus:ring-[#0D215C]/10 transition-all outline-none text-slate-700 placeholder:text-slate-300"
|
||||
placeholder="Masukkan password" required>
|
||||
</div>
|
||||
|
||||
<div class="pt-6">
|
||||
<button type="submit"
|
||||
class="w-full bg-[#0D215C] text-white font-bold py-5 rounded-2xl shadow-xl shadow-blue-900/20 hover:bg-[#081a45] transition-all transform active:scale-95">
|
||||
Simpan Akun Petugas
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 text-center">
|
||||
<a href="{{ route('admin.users') }}" class="text-sm font-bold text-slate-400 hover:text-[#0D215C] transition-colors flex items-center justify-center">
|
||||
<i data-lucide="arrow-left" class="w-4 h-4 mr-2"></i> KEMBALI KE DAFTAR
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,913 @@
|
||||
@extends('admin.layouts.app')
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
/* ══════════════════════════════════════════════
|
||||
DISNAKER KALBAR – ADMIN DASHBOARD
|
||||
Professional Government Dashboard UI
|
||||
══════════════════════════════════════════════ */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
.d-wrap {
|
||||
padding: 2rem 2.5rem 3rem;
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
}
|
||||
|
||||
/* ── Page Header ─────────────────────────────── */
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
.page-header-left h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #0D215C;
|
||||
letter-spacing: -0.3px;
|
||||
line-height: 1;
|
||||
}
|
||||
.page-header-left .subtitle {
|
||||
font-size: 12.5px;
|
||||
color: #94a3b8;
|
||||
font-weight: 500;
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.status-dot {
|
||||
width: 7px; height: 7px;
|
||||
border-radius: 50%;
|
||||
background: #22c55e;
|
||||
display: inline-block;
|
||||
box-shadow: 0 0 0 3px rgba(34,197,94,0.2);
|
||||
animation: pulse-dot 2s infinite;
|
||||
}
|
||||
@keyframes pulse-dot {
|
||||
0%,100% { box-shadow: 0 0 0 3px rgba(34,197,94,0.2); }
|
||||
50% { box-shadow: 0 0 0 6px rgba(34,197,94,0.08); }
|
||||
}
|
||||
.page-header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.hdr-chip {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 7px 18px;
|
||||
border-radius: 50px;
|
||||
letter-spacing: 0.4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.hdr-chip.navy { background: #0D215C; color: #fff; box-shadow: 0 4px 14px rgba(13,33,92,0.22); }
|
||||
.hdr-chip.light { background: #fff; color: #64748b; border: 1px solid #e2e8f0; }
|
||||
.hdr-chip svg { flex-shrink: 0; }
|
||||
|
||||
/* ── Stat Cards ──────────────────────────────── */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 18px;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
.s-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 1.5rem 1.6rem 1.4rem;
|
||||
border: 1px solid #edf1f7;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
cursor: default;
|
||||
transition: transform 0.22s cubic-bezier(.4,0,.2,1),
|
||||
box-shadow 0.22s cubic-bezier(.4,0,.2,1);
|
||||
}
|
||||
.s-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 16px 40px rgba(13,33,92,0.12);
|
||||
}
|
||||
.s-card::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0; left: 0; right: 0;
|
||||
height: 4px;
|
||||
border-radius: 0 0 20px 20px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.s-card.c-blue::after { background: linear-gradient(90deg,#3b82f6,#6366f1); }
|
||||
.s-card.c-green::after { background: linear-gradient(90deg,#22c55e,#10b981); }
|
||||
.s-card.c-yellow::after { background: linear-gradient(90deg,#f59e0b,#f97316); }
|
||||
.s-card.c-red::after { background: linear-gradient(90deg,#64748b,#475569); }
|
||||
.s-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -20px; right: -20px;
|
||||
width: 100px; height: 100px;
|
||||
border-radius: 50%;
|
||||
opacity: 0.04;
|
||||
}
|
||||
.s-card.c-blue::before { background: #3b82f6; }
|
||||
.s-card.c-green::before { background: #22c55e; }
|
||||
.s-card.c-yellow::before { background: #f59e0b; }
|
||||
.s-card.c-red::before { background: #64748b; }
|
||||
|
||||
.s-icon {
|
||||
width: 44px; height: 44px;
|
||||
border-radius: 12px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.s-icon.c-blue { background: #eff6ff; color: #3b82f6; }
|
||||
.s-icon.c-green { background: #f0fdf4; color: #16a34a; }
|
||||
.s-icon.c-yellow { background: #fffbeb; color: #d97706; }
|
||||
.s-icon.c-red { background: #f8fafc; color: #475569; }
|
||||
.s-icon svg { width: 20px; height: 20px; }
|
||||
|
||||
.s-num {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
letter-spacing: -2px;
|
||||
line-height: 1;
|
||||
}
|
||||
.s-label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #94a3b8;
|
||||
margin-top: 5px;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.s-trend {
|
||||
font-size: 11.5px;
|
||||
font-weight: 500;
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.s-trend.up { color: #16a34a; }
|
||||
.s-trend.down { color: #94a3b8; }
|
||||
.s-trend.flat { color: #94a3b8; }
|
||||
.s-trend svg { width: 13px; height: 13px; }
|
||||
|
||||
/* ── Main Content Grid ───────────────────────── */
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 360px;
|
||||
gap: 20px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
/* ── Generic Card ────────────────────────────── */
|
||||
.g-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 1.5rem 1.6rem;
|
||||
border: 1px solid #edf1f7;
|
||||
box-shadow: 0 2px 12px rgba(13,33,92,0.04);
|
||||
}
|
||||
.g-card-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
.g-card-title h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #0D215C;
|
||||
letter-spacing: -0.1px;
|
||||
}
|
||||
.g-card-title a {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #3b82f6;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
transition: gap 0.18s;
|
||||
}
|
||||
.g-card-title a:hover { gap: 8px; }
|
||||
|
||||
/* ── Divider ─────────────────────────────────── */
|
||||
.act-divider {
|
||||
height: 1px;
|
||||
background: #f1f5f9;
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
|
||||
/* ── Filter Tabs ─────────────────────────────── */
|
||||
.ftabs {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
margin-bottom: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.ftab {
|
||||
padding: 5px 15px;
|
||||
border-radius: 50px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
border: 1.5px solid transparent;
|
||||
transition: all 0.15s;
|
||||
user-select: none;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.ftab.on { background: #0D215C; color: #fff; border-color: #0D215C; }
|
||||
.ftab.off { background: #f8fafc; color: #94a3b8; border-color: #e2e8f0; }
|
||||
.ftab.off:hover { background: #eff6ff; color: #3b82f6; border-color: #bfdbfe; }
|
||||
|
||||
/* ── Activity Rows ───────────────────────────── */
|
||||
.act-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 13px;
|
||||
padding: 10px 10px;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, box-shadow 0.15s, transform 0.15s;
|
||||
}
|
||||
.act-item:hover {
|
||||
background: #f8fafc;
|
||||
box-shadow: 0 4px 16px rgba(13,33,92,0.06);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
.act-item:active { transform: scale(0.99); }
|
||||
|
||||
.act-ava {
|
||||
width: 38px; height: 38px;
|
||||
border-radius: 10px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.av-1 { background: linear-gradient(135deg,#3b82f6,#6366f1); }
|
||||
.av-2 { background: linear-gradient(135deg,#14b8a6,#06b6d4); }
|
||||
.av-3 { background: linear-gradient(135deg,#a855f7,#ec4899); }
|
||||
.av-4 { background: linear-gradient(135deg,#f97316,#f59e0b); }
|
||||
.av-5 { background: linear-gradient(135deg,#22c55e,#10b981); }
|
||||
|
||||
.act-body { flex: 1; min-width: 0; }
|
||||
.act-name {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.act-meta {
|
||||
font-size: 11px;
|
||||
color: #94a3b8;
|
||||
font-weight: 400;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.pill {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
padding: 4px 12px;
|
||||
border-radius: 50px;
|
||||
letter-spacing: 0.3px;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pill-ok { background: #dcfce7; color: #15803d; }
|
||||
.pill-run { background: #dbeafe; color: #1d4ed8; }
|
||||
.pill-del { background: #fee2e2; color: #b91c1c; }
|
||||
.pill-pnd { background: #fef9c3; color: #92400e; }
|
||||
|
||||
.empty-box {
|
||||
padding: 3.5rem 1rem;
|
||||
text-align: center;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
.empty-box .ei {
|
||||
width: 48px; height: 48px;
|
||||
margin: 0 auto 12px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
background: #f1f5f9;
|
||||
border-radius: 14px;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.empty-box .ei svg { width: 22px; height: 22px; }
|
||||
.empty-box p { font-size: 13px; font-weight: 500; color: #94a3b8; }
|
||||
|
||||
/* ── Modal ────────────────────────────────────── */
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(13,33,92,0.28);
|
||||
backdrop-filter: blur(4px);
|
||||
z-index: 999;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: fadeIn 0.2s ease;
|
||||
}
|
||||
.modal-overlay.show { display: flex; }
|
||||
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
|
||||
.modal-box {
|
||||
background: #fff;
|
||||
border-radius: 22px;
|
||||
padding: 2rem;
|
||||
width: 460px;
|
||||
max-width: 95vw;
|
||||
box-shadow: 0 30px 80px rgba(13,33,92,0.18);
|
||||
animation: slideUp 0.25s cubic-bezier(.4,0,.2,1);
|
||||
}
|
||||
@keyframes slideUp {
|
||||
from { opacity:0; transform:translateY(20px); }
|
||||
to { opacity:1; transform:translateY(0); }
|
||||
}
|
||||
.modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
.modal-header h4 {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #0D215C;
|
||||
line-height: 1.4;
|
||||
max-width: 85%;
|
||||
}
|
||||
.modal-close {
|
||||
width: 30px; height: 30px;
|
||||
border-radius: 50%;
|
||||
background: #f1f5f9;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: #64748b;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.modal-close:hover { background: #fee2e2; color: #ef4444; }
|
||||
.modal-close svg { width: 14px; height: 14px; }
|
||||
.modal-field {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
font-size: 13px;
|
||||
}
|
||||
.modal-field:last-child { border-bottom: none; }
|
||||
.modal-field .mf-label {
|
||||
width: 120px;
|
||||
flex-shrink: 0;
|
||||
color: #94a3b8;
|
||||
font-weight: 500;
|
||||
font-size: 11.5px;
|
||||
letter-spacing: 0.3px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
.modal-field .mf-value {
|
||||
color: #1e293b;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ── Sidebar ─────────────────────────────────── */
|
||||
.sidebar-col { display: flex; flex-direction: column; gap: 18px; }
|
||||
|
||||
/* Bar Chart */
|
||||
.chart-bars {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 8px;
|
||||
height: 88px;
|
||||
margin: 4px 0 8px;
|
||||
}
|
||||
.bar-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
gap: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bar-body {
|
||||
width: 100%;
|
||||
border-radius: 6px 6px 0 0;
|
||||
background: #e0e7ff;
|
||||
margin-top: auto;
|
||||
transition: all 0.3s cubic-bezier(.4,0,.2,1);
|
||||
position: relative;
|
||||
}
|
||||
.bar-wrap:hover .bar-body {
|
||||
filter: brightness(0.9);
|
||||
transform: scaleY(1.04);
|
||||
transform-origin: bottom;
|
||||
}
|
||||
.bar-body::after {
|
||||
content: attr(data-val);
|
||||
position: absolute;
|
||||
top: -28px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #0D215C;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
padding: 3px 8px;
|
||||
border-radius: 6px;
|
||||
white-space: nowrap;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
.bar-wrap:hover .bar-body::after { opacity: 1; }
|
||||
.bar-body.today { background: linear-gradient(180deg,#3b82f6 0%,#0D215C 100%); }
|
||||
.bar-body.active { background: #93c5fd; }
|
||||
.bar-lbl {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
color: #94a3b8;
|
||||
text-align: center;
|
||||
}
|
||||
.bar-lbl.today-lbl { color: #3b82f6; font-weight: 600; }
|
||||
.chart-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
font-weight: 400;
|
||||
}
|
||||
.chart-footer span { color: #94a3b8; }
|
||||
.chart-footer strong { color: #0D215C; font-weight: 700; }
|
||||
|
||||
/* Progress */
|
||||
.prog-item { margin-bottom: 14px; }
|
||||
.prog-item:last-child { margin-bottom: 0; }
|
||||
.prog-head { display: flex; justify-content: space-between; margin-bottom: 7px; }
|
||||
.prog-head span { font-size: 12.5px; font-weight: 500; color: #334155; }
|
||||
.prog-head strong { font-size: 12.5px; font-weight: 700; color: #0D215C; }
|
||||
.prog-track { height: 8px; background: #f1f5f9; border-radius: 50px; overflow: hidden; }
|
||||
.prog-fill { height: 100%; border-radius: 50px; transition: width 1.2s cubic-bezier(.4,0,.2,1); }
|
||||
|
||||
/* Top Users */
|
||||
.usr-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 11px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 12px;
|
||||
transition: background 0.15s, box-shadow 0.15s;
|
||||
cursor: default;
|
||||
}
|
||||
.usr-row:hover {
|
||||
background: #f8fafc;
|
||||
box-shadow: 0 2px 10px rgba(13,33,92,0.05);
|
||||
}
|
||||
.usr-rank {
|
||||
width: 24px; height: 24px;
|
||||
border-radius: 7px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.rank-1 { background: #fef9c3; color: #b45309; }
|
||||
.rank-2 { background: #f1f5f9; color: #64748b; }
|
||||
.rank-3 { background: #fff7ed; color: #c2410c; }
|
||||
.rank-n { background: #f8fafc; color: #94a3b8; }
|
||||
.usr-ava {
|
||||
width: 32px; height: 32px;
|
||||
border-radius: 9px;
|
||||
background: linear-gradient(135deg,#0D215C,#2563eb);
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.usr-name { flex: 1; font-size: 12.5px; font-weight: 500; color: #334155; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.usr-count {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #3b82f6;
|
||||
background: #eff6ff;
|
||||
padding: 3px 11px;
|
||||
border-radius: 50px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ── Animations ──────────────────────────────── */
|
||||
@keyframes fadeUp {
|
||||
from { opacity:0; transform:translateY(16px); }
|
||||
to { opacity:1; transform:translateY(0); }
|
||||
}
|
||||
.s-card { animation: fadeUp 0.4s ease both; }
|
||||
.s-card:nth-child(1) { animation-delay:.06s; }
|
||||
.s-card:nth-child(2) { animation-delay:.12s; }
|
||||
.s-card:nth-child(3) { animation-delay:.18s; }
|
||||
.s-card:nth-child(4) { animation-delay:.24s; }
|
||||
.content-grid { animation: fadeUp 0.4s .28s ease both; }
|
||||
|
||||
/* ── Responsive ──────────────────────────────── */
|
||||
@media (max-width:1100px) { .content-grid { grid-template-columns:1fr; } }
|
||||
@media (max-width:768px) {
|
||||
.stats-grid { grid-template-columns:repeat(2,1fr); gap: 12px; }
|
||||
.d-wrap { padding: 1rem 0.5rem; }
|
||||
.page-header { flex-direction:column; align-items:flex-start; gap:12px; }
|
||||
.page-header-right { flex-wrap: wrap; gap: 8px; }
|
||||
.g-card { padding: 1.2rem; }
|
||||
.act-item { gap: 10px; padding: 8px; }
|
||||
.hdr-chip { padding: 6px 12px; }
|
||||
}
|
||||
@media (max-width:480px) {
|
||||
.stats-grid { grid-template-columns:1fr; }
|
||||
.d-wrap { padding: 0.8rem 0; }
|
||||
.g-card { padding: 1rem; border-radius: 16px; }
|
||||
.act-meta { font-size: 10px; }
|
||||
.s-card { padding: 1.2rem; }
|
||||
.act-item { flex-direction: column; align-items: flex-start; gap: 8px; }
|
||||
.act-item .pill { align-self: flex-start; }
|
||||
}
|
||||
</style>
|
||||
|
||||
{{-- ═══════ MODAL (Detail Kegiatan) ═══════ --}}
|
||||
<div class="modal-overlay" id="detailModal">
|
||||
<div class="modal-box">
|
||||
<div class="modal-header">
|
||||
<h4 id="mdl-title">—</h4>
|
||||
<button class="modal-close" onclick="closeModal()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="mdl-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-wrap">
|
||||
|
||||
{{-- ── PAGE HEADER ── --}}
|
||||
<div class="page-header">
|
||||
<div class="page-header-left">
|
||||
<h2>Dashboard Admin</h2>
|
||||
<div class="subtitle">
|
||||
<span class="status-dot"></span>
|
||||
{{ \Carbon\Carbon::now()->timezone('Asia/Jakarta')->locale('id')->translatedFormat('l, d F Y') }}
|
||||
· Sistem Online
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-header-right">
|
||||
<span class="hdr-chip light">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
||||
{{ \Carbon\Carbon::now()->timezone('Asia/Jakarta')->format('H:i') }} WIB
|
||||
</span>
|
||||
<span class="hdr-chip navy">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
Disnaker Kalbar
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ── STAT CARDS ── --}}
|
||||
<div class="stats-grid">
|
||||
|
||||
<div class="s-card c-blue">
|
||||
<div class="s-icon c-blue">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2"/>
|
||||
<rect x="9" y="3" width="6" height="4" rx="1"/>
|
||||
<line x1="9" y1="12" x2="15" y2="12"/>
|
||||
<line x1="9" y1="16" x2="13" y2="16"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="s-num">{{ $stats['total'] ?? 0 }}</div>
|
||||
<div class="s-label">Total Kegiatan</div>
|
||||
<div class="s-trend up">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></svg>
|
||||
12% bulan ini
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="s-card c-green">
|
||||
<div class="s-icon c-green">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
|
||||
<polyline points="22 4 12 14.01 9 11.01"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="s-num">{{ $stats['selesai'] ?? 0 }}</div>
|
||||
<div class="s-label">Kegiatan Selesai</div>
|
||||
<div class="s-trend up">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></svg>
|
||||
8% dari kemarin
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="s-card c-yellow">
|
||||
<div class="s-icon c-yellow">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="12" y1="2" x2="12" y2="6"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22"/>
|
||||
<line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/>
|
||||
<line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/>
|
||||
<line x1="2" y1="12" x2="6" y2="12"/>
|
||||
<line x1="18" y1="12" x2="22" y2="12"/>
|
||||
<line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/>
|
||||
<line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="s-num">{{ $stats['proses'] ?? 0 }}</div>
|
||||
<div class="s-label">Sedang Berjalan</div>
|
||||
<div class="s-trend flat">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
Sama seperti kemarin
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="s-card c-red">
|
||||
<div class="s-icon c-red">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="s-num">{{ $stats['users'] ?? 0 }}</div>
|
||||
<div class="s-label">Pengguna Aktif</div>
|
||||
<div class="s-trend down">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
|
||||
3% minggu ini
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- ── MAIN GRID ── --}}
|
||||
<div class="content-grid">
|
||||
|
||||
{{-- LEFT: Kegiatan Terbaru --}}
|
||||
<div class="g-card">
|
||||
<div class="g-card-title">
|
||||
<h3>5 Kegiatan Terbaru</h3>
|
||||
<a href="{{ route('admin.kegiatan.index') }}">Lihat Semua →</a>
|
||||
</div>
|
||||
|
||||
<div class="ftabs">
|
||||
<div class="ftab on" onclick="filterAct(this,'semua')">Semua</div>
|
||||
<div class="ftab off" onclick="filterAct(this,'selesai')">Selesai</div>
|
||||
<div class="ftab off" onclick="filterAct(this,'on_progres')">Berjalan</div>
|
||||
<div class="ftab off" onclick="filterAct(this,'terlambat')">Terlambat</div>
|
||||
<div class="ftab off" onclick="filterAct(this,'dibatalkan')">Dibatalkan</div>
|
||||
</div>
|
||||
|
||||
<div class="act-divider"></div>
|
||||
|
||||
<div id="act-list">
|
||||
@php
|
||||
$avClasses = ['av-1','av-2','av-3','av-4','av-5'];
|
||||
$pillMap = [
|
||||
'selesai' => ['pill-ok', 'Selesai'],
|
||||
'telah_ditinjau' => ['pill-ok', 'Ditinjau'],
|
||||
'on_progres' => ['pill-run', 'Berjalan'],
|
||||
'terlambat' => ['pill-del', 'Terlambat'],
|
||||
'dibatalkan' => ['pill-del', 'Dibatalkan'],
|
||||
'review' => ['pill-pnd', 'Review'],
|
||||
'pending' => ['pill-pnd', 'Pending'],
|
||||
];
|
||||
@endphp
|
||||
|
||||
@forelse($activities ?? [] as $idx => $item)
|
||||
@php
|
||||
$st = strtolower($item->status ?? 'pending');
|
||||
$pc = $pillMap[$st] ?? ['pill-pnd', ucfirst($st)];
|
||||
$ac = $avClasses[$idx % 5];
|
||||
$tgl = \Carbon\Carbon::parse($item->tanggal)->locale('id')->translatedFormat('d M Y');
|
||||
$usr = e($item->user->name ?? 'Sistem');
|
||||
$nm = e($item->nama_kegiatan);
|
||||
@endphp
|
||||
<div class="act-item"
|
||||
data-status="{{ $st }}"
|
||||
onclick="openModal(
|
||||
'{{ addslashes($nm) }}',
|
||||
'{{ addslashes($usr) }}',
|
||||
'{{ $tgl }}',
|
||||
'{{ $st }}',
|
||||
'{{ addslashes(str_replace(["\r", "\n"], ["", "\\n"], $item->keterangan ?? '-')) }}',
|
||||
'{{ addslashes(str_replace(["\r", "\n"], ["", "\\n"], $item->status_note ?? '')) }}',
|
||||
'{{ addslashes($item->lokasi ?? '-') }}',
|
||||
'{{ $item->lampiran ? rtrim(env('BACKEND_API_URL', 'http://127.0.0.1:8000'), '/api') . '/storage/' . $item->lampiran : '' }}'
|
||||
)">
|
||||
<div class="act-ava {{ $ac }}">{{ strtoupper(substr($item->user->name ?? 'U', 0, 2)) }}</div>
|
||||
<div class="act-body">
|
||||
<div class="act-name">{{ $nm }}</div>
|
||||
<div class="act-meta">{{ $usr }} • {{ $tgl }}</div>
|
||||
</div>
|
||||
<span class="pill {{ $pc[0] }}">{{ $pc[1] }}</span>
|
||||
</div>
|
||||
@empty
|
||||
<div class="empty-box">
|
||||
<div class="ei">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>
|
||||
</div>
|
||||
<p>Belum ada aktivitas kegiatan yang tercatat.</p>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- RIGHT: Sidebar --}}
|
||||
<div class="sidebar-col">
|
||||
|
||||
{{-- Weekly Chart --}}
|
||||
<div class="g-card">
|
||||
<div class="g-card-title" style="margin-bottom:.8rem">
|
||||
<h3>Aktivitas Minggu Ini</h3>
|
||||
@php $wTotal = array_sum($weeklyData ?? [0,0,0,0,0,0,0]); @endphp
|
||||
<span class="pill pill-run">{{ $wTotal }} kegiatan</span>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$days = ['Sen','Sel','Rab','Kam','Jum','Sab','Min'];
|
||||
$wData = $weeklyData ?? [0,0,0,0,0,0,0];
|
||||
$maxBar = max($wData) ?: 1;
|
||||
$todayDI = (int)\Carbon\Carbon::now()->dayOfWeekIso - 1;
|
||||
@endphp
|
||||
|
||||
<div class="chart-bars">
|
||||
@foreach($days as $i => $d)
|
||||
@php $pct = round(($wData[$i] / $maxBar) * 100); $isToday = $i === $todayDI; @endphp
|
||||
<div class="bar-wrap">
|
||||
<div class="bar-body {{ $isToday ? 'today' : ($wData[$i] > 0 ? 'active' : '') }}"
|
||||
style="height:{{ max($pct, 8) }}%"
|
||||
data-val="{{ $wData[$i] }} kegiatan">
|
||||
</div>
|
||||
<span class="bar-lbl {{ $isToday ? 'today-lbl' : '' }}">{{ $d }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="chart-footer">
|
||||
<span>Total minggu ini</span>
|
||||
<strong>{{ $wTotal }} kegiatan</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Division Progress --}}
|
||||
<div class="g-card">
|
||||
<div class="g-card-title" style="margin-bottom:.8rem">
|
||||
<h3>Progres Divisi</h3>
|
||||
</div>
|
||||
{{-- FIX: Gunakan $divisionProgress dari controller, fallback jika tidak ada --}}
|
||||
@php
|
||||
$divs = $divisionProgress ?? [
|
||||
['name' => 'Operasional', 'pct' => 78, 'clr' => 'linear-gradient(90deg,#3b82f6,#6366f1)'],
|
||||
['name' => 'Keuangan', 'pct' => 64, 'clr' => 'linear-gradient(90deg,#22c55e,#10b981)'],
|
||||
['name' => 'SDM', 'pct' => 91, 'clr' => 'linear-gradient(90deg,#f97316,#f59e0b)'],
|
||||
['name' => 'IT', 'pct' => 55, 'clr' => 'linear-gradient(90deg,#a855f7,#ec4899)'],
|
||||
];
|
||||
@endphp
|
||||
@foreach($divs as $dv)
|
||||
<div class="prog-item">
|
||||
<div class="prog-head">
|
||||
<span>{{ $dv['name'] }}</span>
|
||||
<strong>{{ $dv['pct'] ?? 0 }}%</strong>
|
||||
</div>
|
||||
<div class="prog-track">
|
||||
<div class="prog-fill" style="width:{{ $dv['pct'] ?? 0 }}%;background:{{ $dv['clr'] ?? '#3b82f6' }}"></div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
{{-- Top Kontributor --}}
|
||||
@if(!empty($topUsers) && count($topUsers))
|
||||
<div class="g-card">
|
||||
<div class="g-card-title" style="margin-bottom:.8rem">
|
||||
<h3>Top Kontributor</h3>
|
||||
</div>
|
||||
@foreach($topUsers as $ri => $u)
|
||||
@php
|
||||
$rankCls = match($ri) { 0 => 'rank-1', 1 => 'rank-2', 2 => 'rank-3', default => 'rank-n' };
|
||||
$medal = match($ri) {
|
||||
0 => '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#b45309" stroke="none"><circle cx="12" cy="8" r="6"/><path d="M15.477 12.89L17 22l-5-3-5 3 1.523-9.11"/></svg>',
|
||||
1 => '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#64748b" stroke="none"><circle cx="12" cy="8" r="6"/><path d="M15.477 12.89L17 22l-5-3-5 3 1.523-9.11"/></svg>',
|
||||
2 => '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#c2410c" stroke="none"><circle cx="12" cy="8" r="6"/><path d="M15.477 12.89L17 22l-5-3-5 3 1.523-9.11"/></svg>',
|
||||
default => $ri + 1
|
||||
};
|
||||
@endphp
|
||||
<div class="usr-row">
|
||||
<div class="usr-rank {{ $rankCls }}">{!! $medal !!}</div>
|
||||
<div class="usr-ava">{{ strtoupper(substr($u->name, 0, 2)) }}</div>
|
||||
<span class="usr-name">{{ $u->name }}</span>
|
||||
{{-- FIX: Ganti kegiatan_count → activities_count (sesuai withCount('activities')) --}}
|
||||
<span class="usr-count">{{ $u->activities_count ?? 0 }} Lap.</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>{{-- /sidebar --}}
|
||||
</div>{{-- /content-grid --}}
|
||||
|
||||
</div>{{-- /d-wrap --}}
|
||||
|
||||
<script>
|
||||
/* ── Filter Tabs ─────────────────── */
|
||||
function filterAct(el, status) {
|
||||
document.querySelectorAll('.ftab').forEach(t => {
|
||||
t.classList.remove('on');
|
||||
t.classList.add('off');
|
||||
});
|
||||
el.classList.add('on');
|
||||
el.classList.remove('off');
|
||||
document.querySelectorAll('#act-list .act-item').forEach(row => {
|
||||
row.style.display = (status === 'semua' || row.dataset.status === status) ? 'flex' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
/* ── Modal ───────────────────────── */
|
||||
const pillLabels = {
|
||||
selesai: '<span class="pill pill-ok">Selesai</span>',
|
||||
on_progres: '<span class="pill pill-run">Berjalan</span>',
|
||||
terlambat: '<span class="pill pill-del">Terlambat</span>',
|
||||
dibatalkan: '<span class="pill pill-del">Dibatalkan</span>',
|
||||
review: '<span class="pill pill-pnd">Review</span>',
|
||||
pending: '<span class="pill pill-pnd">Pending</span>'
|
||||
};
|
||||
|
||||
function openModal(nama, user, tgl, status, ket, statusNote, lokasi, lampiranUrl) {
|
||||
document.getElementById('mdl-title').textContent = nama;
|
||||
|
||||
let lampiranHtml = '';
|
||||
if (lampiranUrl) {
|
||||
lampiranHtml = `
|
||||
<div class="modal-field" style="margin-top: 15px; grid-column: span 2;">
|
||||
<span class="mf-label">Lampiran Foto/Dokumen</span>
|
||||
<div style="margin-top: 8px;">
|
||||
<img src="${lampiranUrl}" alt="Lampiran" style="max-width: 100%; max-height: 400px; border-radius: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
document.getElementById('mdl-body').innerHTML = `
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
|
||||
<div class="modal-field">
|
||||
<span class="mf-label">Pegawai Ditugaskan</span>
|
||||
<span class="mf-value">${user}</span>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<span class="mf-label">Tanggal</span>
|
||||
<span class="mf-value">${tgl}</span>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<span class="mf-label">Lokasi Tugas</span>
|
||||
<span class="mf-value">${lokasi}</span>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<span class="mf-label">Status</span>
|
||||
<span class="mf-value">${pillLabels[status] || status}</span>
|
||||
</div>
|
||||
<div class="modal-field" style="grid-column: span 2;">
|
||||
<span class="mf-label">Deskripsi Laporan (Keterangan)</span>
|
||||
<span class="mf-value" style="white-space: pre-wrap; line-height: 1.5;">${ket || '—'}</span>
|
||||
</div>
|
||||
${statusNote ? `
|
||||
<div class="modal-field" style="grid-column: span 2; background: #eff6ff; padding: 12px; border-radius: 8px;">
|
||||
<span class="mf-label" style="color: #2563eb; margin-bottom: 4px; display: block;">Catatan Status (Node Petugas)</span>
|
||||
<span class="mf-value" style="white-space: pre-wrap; line-height: 1.5; color: #1e3a8a;">${statusNote}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
${lampiranHtml}
|
||||
</div>
|
||||
`;
|
||||
document.getElementById('detailModal').classList.add('show');
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('detailModal').classList.remove('show');
|
||||
}
|
||||
|
||||
document.getElementById('detailModal').addEventListener('click', function(e) {
|
||||
if (e.target === this) closeModal();
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape') closeModal();
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,212 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
body, * { font-family: 'Plus Jakarta Sans', sans-serif; }
|
||||
|
||||
.eu-wrap {
|
||||
padding: 2rem 2.5rem 3rem;
|
||||
max-width: 640px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.eu-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.eu-title { font-size: 22px; font-weight: 700; color: #0D215C; }
|
||||
.eu-sub { font-size: 13px; color: #94a3b8; margin-top: 4px; }
|
||||
.btn-back {
|
||||
padding: 8px 18px;
|
||||
border-radius: 10px;
|
||||
background: #eef2ff;
|
||||
color: #3730a3;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: .2s;
|
||||
}
|
||||
.btn-back:hover { background: #dbeafe; color: #1d4ed8; }
|
||||
|
||||
.eu-card {
|
||||
background: #fff;
|
||||
border: 1px solid #edf1f7;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 12px rgba(13,33,92,.05);
|
||||
}
|
||||
.eu-card-header {
|
||||
padding: 1.2rem 1.5rem;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
background: #f8fafc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.eu-card-header h3 { font-size: 14px; font-weight: 700; color: #0D215C; margin: 0; }
|
||||
.eu-body { padding: 1.5rem; }
|
||||
|
||||
.form-group { margin-bottom: 1.2rem; }
|
||||
.form-label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #374151;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
.form-input, .form-select-field {
|
||||
width: 100%;
|
||||
padding: 11px 14px;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
color: #0f172a;
|
||||
background: #fff;
|
||||
transition: border .2s, box-shadow .2s;
|
||||
}
|
||||
.form-input:focus, .form-select-field:focus {
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 0 0 3px rgba(59,130,246,.1);
|
||||
}
|
||||
.form-hint {
|
||||
font-size: 11px;
|
||||
color: #94a3b8;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.pw-wrap { position: relative; }
|
||||
.pw-wrap .form-input { padding-right: 44px; }
|
||||
.pw-toggle {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: #94a3b8;
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.pw-toggle:hover { color: #3b82f6; }
|
||||
|
||||
.btn-submit {
|
||||
width: 100%;
|
||||
padding: 13px;
|
||||
margin-top: .5rem;
|
||||
background: #0D215C;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
box-shadow: 0 4px 14px rgba(13,33,92,.2);
|
||||
}
|
||||
.btn-submit:hover { background: #1e3a8a; transform: translateY(-1px); }
|
||||
|
||||
.alert-error {
|
||||
background: #fee2e2;
|
||||
color: #b91c1c;
|
||||
padding: 12px 16px;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="eu-wrap">
|
||||
<div class="eu-header">
|
||||
<div>
|
||||
<div class="eu-title">Edit Pengguna</div>
|
||||
<div class="eu-sub">Perbarui informasi akun pengguna</div>
|
||||
</div>
|
||||
<a href="{{ route('admin.users') }}" class="btn-back">← Kembali</a>
|
||||
</div>
|
||||
|
||||
<div class="eu-card">
|
||||
<div class="eu-card-header">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#0D215C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||
<h3>Form Edit Pengguna</h3>
|
||||
</div>
|
||||
<div class="eu-body">
|
||||
|
||||
@if($errors->any())
|
||||
<div class="alert-error">
|
||||
@foreach($errors->all() as $e) <div>• {{ $e }}</div> @endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
<div class="alert-error">✗ {{ session('error') }}</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('admin.users.update', $user->id) }}" method="POST">
|
||||
@csrf
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="name">Nama Lengkap</label>
|
||||
<input type="text" id="name" name="name" class="form-input"
|
||||
value="{{ old('name', $user->name) }}" placeholder="Nama lengkap pengguna" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="username">Username</label>
|
||||
<input type="text" id="username" name="username" class="form-input"
|
||||
value="{{ old('username', $user->username) }}" placeholder="Username login" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="jabatan">Jabatan</label>
|
||||
<input type="text" id="jabatan" name="jabatan" class="form-input"
|
||||
value="{{ old('jabatan', $user->jabatan ?? '') }}" placeholder="Jabatan pengguna (opsional)">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="role">Role / Hak Akses</label>
|
||||
<select id="role" name="role" class="form-select-field">
|
||||
<option value="user" {{ old('role', $user->role) == 'user' ? 'selected' : '' }}>Petugas Lapangan</option>
|
||||
<option value="admin" {{ old('role', $user->role) == 'admin' ? 'selected' : '' }}>Administrator (Kasi)</option>
|
||||
<option value="superadmin" {{ old('role', $user->role) == 'superadmin' ? 'selected' : '' }}>Super Admin (Kabid)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="password">Password Baru</label>
|
||||
<div class="pw-wrap">
|
||||
<input type="password" id="password" name="password" class="form-input"
|
||||
placeholder="Kosongkan jika tidak ingin mengubah">
|
||||
<button type="button" class="pw-toggle" onclick="togglePassword('password','eyeIconPw')">
|
||||
<svg id="eyeIconPw" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-hint">Minimal 6 karakter. Kosongkan jika tidak ingin mengubah password.</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-submit">Simpan Perubahan</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function togglePassword(fieldId, iconId) {
|
||||
const field = document.getElementById(fieldId);
|
||||
const icon = document.getElementById(iconId);
|
||||
if (field.type === 'password') {
|
||||
field.type = 'text';
|
||||
icon.innerHTML = '<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/>';
|
||||
} else {
|
||||
field.type = 'password';
|
||||
icon.innerHTML = '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,242 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
body, * { font-family: 'Plus Jakarta Sans', sans-serif; }
|
||||
|
||||
.detail-wrap {
|
||||
padding: 2rem 2.5rem 3rem;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.detail-title { font-size: 22px; font-weight: 700; color: #0D215C; }
|
||||
.detail-sub { font-size: 13px; color: #94a3b8; margin-top: 4px; }
|
||||
|
||||
.btn-back {
|
||||
padding: 8px 18px;
|
||||
border-radius: 10px;
|
||||
background: #eef2ff;
|
||||
color: #3730a3;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all .2s;
|
||||
}
|
||||
.btn-back:hover { background: #dbeafe; color: #1d4ed8; }
|
||||
|
||||
.detail-card {
|
||||
background: #fff;
|
||||
border: 1px solid #edf1f7;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 12px rgba(13,33,92,.05);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.detail-card-header {
|
||||
padding: 1.2rem 1.5rem;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
background: #f8fafc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.detail-card-header h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #0D215C;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.detail-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0;
|
||||
}
|
||||
.detail-field {
|
||||
padding: 1rem 1.5rem;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.detail-field:nth-child(odd) { border-right: 1px solid #f1f5f9; }
|
||||
.detail-field.full {
|
||||
grid-column: 1 / -1;
|
||||
border-right: none;
|
||||
}
|
||||
.df-label {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #94a3b8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
.df-value {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
padding: 5px 14px;
|
||||
border-radius: 50px;
|
||||
letter-spacing: .3px;
|
||||
}
|
||||
.pill-ok { background: #dcfce7; color: #15803d; }
|
||||
.pill-run { background: #dbeafe; color: #1d4ed8; }
|
||||
.pill-rev { background: #fef9c3; color: #92400e; }
|
||||
.pill-del { background: #fee2e2; color: #b91c1c; }
|
||||
|
||||
.petugas-list {
|
||||
padding: 1rem 1.5rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
.petugas-chip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: #f1f5f9;
|
||||
border-radius: 10px;
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #334155;
|
||||
}
|
||||
.petugas-ava {
|
||||
width: 28px; height: 28px;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(135deg, #0D215C, #2563eb);
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
.action-btn {
|
||||
padding: 10px 22px;
|
||||
border-radius: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.btn-edit { background: #0D215C; color: #fff; box-shadow: 0 4px 12px rgba(13,33,92,.2); }
|
||||
.btn-edit:hover { background: #1e3a8a; }
|
||||
.btn-batal { background: #fee2e2; color: #b91c1c; }
|
||||
.btn-batal:hover { background: #fecaca; }
|
||||
</style>
|
||||
|
||||
<div class="detail-wrap">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="detail-header">
|
||||
<div>
|
||||
<div class="detail-title">Detail Kegiatan</div>
|
||||
<div class="detail-sub">Informasi lengkap penugasan lapangan</div>
|
||||
</div>
|
||||
<a href="{{ route('admin.kegiatan.index') }}" class="btn-back">← Kembali</a>
|
||||
</div>
|
||||
|
||||
{{-- INFO UTAMA --}}
|
||||
<div class="detail-card">
|
||||
<div class="detail-card-header">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#0D215C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/></svg>
|
||||
<h3>Informasi Penugasan</h3>
|
||||
</div>
|
||||
|
||||
<div class="detail-grid">
|
||||
<div class="detail-field">
|
||||
<div class="df-label">Nomor Surat</div>
|
||||
<div class="df-value">{{ $activity->nomor_surat ?? '-' }}</div>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<div class="df-label">Status</div>
|
||||
<div class="df-value">
|
||||
@php
|
||||
$pillMap = [
|
||||
'selesai' => ['pill-ok', 'Selesai'],
|
||||
'on_progres' => ['pill-run', 'Sedang Berjalan'],
|
||||
'telah_ditinjau' => ['pill-rev', 'Telah Ditinjau'],
|
||||
'dibatalkan' => ['pill-del', 'Dibatalkan'],
|
||||
];
|
||||
$pc = $pillMap[$activity->status] ?? ['pill-run', ucfirst($activity->status)];
|
||||
@endphp
|
||||
<span class="pill {{ $pc[0] }}">{{ $pc[1] }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field full">
|
||||
<div class="df-label">Nama Kegiatan</div>
|
||||
<div class="df-value">{{ $activity->nama_kegiatan }}</div>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<div class="df-label">Tanggal Mulai</div>
|
||||
<div class="df-value">{{ \Carbon\Carbon::parse($activity->tanggal)->locale('id')->translatedFormat('d F Y') }}</div>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<div class="df-label">Tanggal Selesai</div>
|
||||
<div class="df-value">
|
||||
{{ $activity->tanggal_selesai ? \Carbon\Carbon::parse($activity->tanggal_selesai)->locale('id')->translatedFormat('d F Y') : '-' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<div class="df-label">Penanggung Jawab</div>
|
||||
<div class="df-value">{{ optional($activity->user)->name ?? '-' }}</div>
|
||||
</div>
|
||||
<div class="detail-field">
|
||||
<div class="df-label">Terakhir Diperbarui</div>
|
||||
<div class="df-value">{{ \Carbon\Carbon::parse($activity->updated_at)->locale('id')->translatedFormat('d F Y, H:i') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- DAFTAR PETUGAS --}}
|
||||
<div class="detail-card">
|
||||
<div class="detail-card-header">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#0D215C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
||||
<h3>Petugas yang Ditugaskan</h3>
|
||||
</div>
|
||||
<div class="petugas-list">
|
||||
@forelse($activity->petugas ?? [] as $p)
|
||||
@php $nm = is_array($p) ? ($p['name'] ?? '-') : ($p->name ?? '-'); @endphp
|
||||
<div class="petugas-chip">
|
||||
<div class="petugas-ava">{{ strtoupper(substr($nm, 0, 2)) }}</div>
|
||||
{{ $nm }}
|
||||
</div>
|
||||
@empty
|
||||
<span style="color:#94a3b8;font-size:13px;">Belum ada petugas yang ditetapkan.</span>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,220 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
body, * { font-family: 'Plus Jakarta Sans', sans-serif; }
|
||||
|
||||
.edit-wrap {
|
||||
padding: 2rem 2.5rem 3rem;
|
||||
max-width: 680px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.edit-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.edit-title { font-size: 22px; font-weight: 700; color: #0D215C; }
|
||||
.edit-sub { font-size: 13px; color: #94a3b8; margin-top: 4px; }
|
||||
|
||||
.btn-back {
|
||||
padding: 8px 18px;
|
||||
border-radius: 10px;
|
||||
background: #eef2ff;
|
||||
color: #3730a3;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all .2s;
|
||||
}
|
||||
.btn-back:hover { background: #dbeafe; color: #1d4ed8; }
|
||||
|
||||
.edit-card {
|
||||
background: #fff;
|
||||
border: 1px solid #edf1f7;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 12px rgba(13,33,92,.05);
|
||||
}
|
||||
.edit-card-header {
|
||||
padding: 1.2rem 1.5rem;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
background: #f8fafc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.edit-card-header h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #0D215C;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.edit-body { padding: 1.5rem; }
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.info-row:last-of-type { border-bottom: none; }
|
||||
.info-label {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #94a3b8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
.info-value {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.form-group { margin-top: 1.5rem; }
|
||||
.form-label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #374151;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.form-select {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
color: #0f172a;
|
||||
transition: border .2s;
|
||||
appearance: auto;
|
||||
}
|
||||
.form-select:focus { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,.1); }
|
||||
|
||||
.status-info {
|
||||
margin-top: 10px;
|
||||
padding: 10px 14px;
|
||||
background: #fffbeb;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
color: #92400e;
|
||||
border: 1px solid #fde68a;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
margin-top: 1.5rem;
|
||||
background: #0D215C;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
box-shadow: 0 4px 14px rgba(13,33,92,.2);
|
||||
}
|
||||
.btn-submit:hover { background: #1e3a8a; transform: translateY(-1px); }
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
padding: 4px 12px;
|
||||
border-radius: 50px;
|
||||
}
|
||||
.pill-ok { background: #dcfce7; color: #15803d; }
|
||||
.pill-run { background: #dbeafe; color: #1d4ed8; }
|
||||
.pill-rev { background: #fef9c3; color: #92400e; }
|
||||
.pill-del { background: #fee2e2; color: #b91c1c; }
|
||||
</style>
|
||||
|
||||
<div class="edit-wrap">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="edit-header">
|
||||
<div>
|
||||
<div class="edit-title">Ubah Status Kegiatan</div>
|
||||
<div class="edit-sub">Perbarui status kemajuan kegiatan lapangan</div>
|
||||
</div>
|
||||
<a href="{{ route('admin.kegiatan.show', $activity->id) }}" class="btn-back">← Kembali</a>
|
||||
</div>
|
||||
|
||||
{{-- FORM CARD --}}
|
||||
<div class="edit-card">
|
||||
<div class="edit-card-header">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#0D215C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
|
||||
<h3>Form Edit Status</h3>
|
||||
</div>
|
||||
|
||||
<div class="edit-body">
|
||||
{{-- ALERT --}}
|
||||
@if($errors->any())
|
||||
<div style="background:#fee2e2;color:#b91c1c;padding:12px 16px;border-radius:10px;margin-bottom:1rem;font-size:13px;">
|
||||
@foreach($errors->all() as $e) <div>• {{ $e }}</div> @endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- INFO KEGIATAN --}}
|
||||
<div class="info-row">
|
||||
<div class="info-label">Nomor Surat</div>
|
||||
<div class="info-value">{{ $activity->nomor_surat ?? '-' }}</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">Nama Kegiatan</div>
|
||||
<div class="info-value">{{ $activity->nama_kegiatan }}</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-label">Status Saat Ini</div>
|
||||
<div class="info-value">
|
||||
@php
|
||||
$pillMap = [
|
||||
'selesai' => ['pill-ok', 'Selesai'],
|
||||
'on_progres' => ['pill-run', 'Sedang Berjalan'],
|
||||
'telah_ditinjau' => ['pill-rev', 'Telah Ditinjau'],
|
||||
'dibatalkan' => ['pill-del', 'Dibatalkan'],
|
||||
];
|
||||
$pc = $pillMap[$activity->status] ?? ['pill-run', ucfirst($activity->status)];
|
||||
@endphp
|
||||
<span class="pill {{ $pc[0] }}">{{ $pc[1] }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- FORM --}}
|
||||
<form action="{{ route('admin.kegiatan.update', $activity->id) }}" method="POST">
|
||||
@csrf
|
||||
@method('POST')
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="status">Status Baru</label>
|
||||
<select name="status" id="status" class="form-select">
|
||||
<option value="on_progres" {{ $activity->status == 'on_progres' ? 'selected' : '' }}>Sedang Berjalan</option>
|
||||
<option value="selesai" {{ $activity->status == 'selesai' ? 'selected' : '' }}>Selesai</option>
|
||||
<option value="telah_ditinjau" {{ $activity->status == 'telah_ditinjau' ? 'selected' : '' }}>Telah Ditinjau</option>
|
||||
</select>
|
||||
<div class="status-info">
|
||||
⚠️ Perubahan status bersifat permanen dan akan tercatat dalam riwayat sistem.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-submit">Simpan Perubahan Status</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,329 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
.keg-wrap {
|
||||
padding: 2rem 2.5rem 3rem;
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
}
|
||||
|
||||
/* ── Header ─── */
|
||||
.keg-topbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
.keg-title { font-size: 22px; font-weight: 700; color: #0D215C; }
|
||||
.keg-sub { font-size: 12.5px; color: #94a3b8; margin-top: 4px; }
|
||||
|
||||
.keg-btn-back {
|
||||
padding: 8px 18px;
|
||||
border-radius: 10px;
|
||||
background: #eef2ff;
|
||||
color: #3730a3;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all .2s;
|
||||
}
|
||||
.keg-btn-back:hover { background: #dbeafe; color: #1d4ed8; }
|
||||
|
||||
/* ── Stats Strip ─── */
|
||||
.keg-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3,1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.kstat {
|
||||
background: #fff;
|
||||
border: 1px solid #edf1f7;
|
||||
border-radius: 16px;
|
||||
padding: 1.2rem 1.4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
.kstat-icon {
|
||||
width: 42px; height: 42px;
|
||||
border-radius: 12px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.kstat-icon.blue { background: #eff6ff; color: #3b82f6; }
|
||||
.kstat-icon.green { background: #f0fdf4; color: #16a34a; }
|
||||
.kstat-icon.yellow { background: #fffbeb; color: #d97706; }
|
||||
.kstat-num { font-size: 28px; font-weight: 700; color: #0f172a; line-height: 1; }
|
||||
.kstat-label { font-size: 12px; color: #94a3b8; margin-top: 3px; font-weight: 500; }
|
||||
|
||||
/* ── Search + Filter ─── */
|
||||
.keg-filter-bar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
margin-bottom: 1.2rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.keg-search {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
padding: 9px 14px;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
border-radius: 10px;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
transition: border .2s;
|
||||
}
|
||||
.keg-search:focus { border-color: #3b82f6; }
|
||||
.keg-select {
|
||||
padding: 9px 14px;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
border-radius: 10px;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.keg-filter-btn {
|
||||
padding: 9px 20px;
|
||||
background: #0D215C;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
}
|
||||
.keg-filter-btn:hover { background: #1e3a8a; }
|
||||
|
||||
/* ── Table Card ─── */
|
||||
.keg-card {
|
||||
background: #fff;
|
||||
border: 1px solid #edf1f7;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 12px rgba(13,33,92,.04);
|
||||
}
|
||||
.keg-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
}
|
||||
.keg-table thead { background: #f8fafc; }
|
||||
.keg-table thead th {
|
||||
padding: 14px 18px;
|
||||
text-align: left;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #94a3b8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
.keg-table tbody td {
|
||||
padding: 14px 18px;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
vertical-align: middle;
|
||||
color: #334155;
|
||||
}
|
||||
.keg-table tbody tr:hover { background: #f8fafc; }
|
||||
|
||||
.pill {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
padding: 4px 12px;
|
||||
border-radius: 50px;
|
||||
letter-spacing: .3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.pill-ok { background: #dcfce7; color: #15803d; }
|
||||
.pill-run { background: #dbeafe; color: #1d4ed8; }
|
||||
.pill-rev { background: #fef9c3; color: #92400e; }
|
||||
.pill-del { background: #fee2e2; color: #b91c1c; }
|
||||
|
||||
.act-btn {
|
||||
padding: 6px 14px;
|
||||
border-radius: 8px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: .15s;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.btn-view { background: #eff6ff; color: #2563eb; }
|
||||
.btn-view:hover { background: #dbeafe; }
|
||||
.btn-edit-k { background: #f0fdf4; color: #15803d; }
|
||||
.btn-edit-k:hover { background: #dcfce7; }
|
||||
.btn-del-k { background: #fff1f2; color: #be123c; }
|
||||
.btn-del-k:hover { background: #fee2e2; }
|
||||
|
||||
.pg-wrap { padding: 16px 18px; border-top: 1px solid #f1f5f9; }
|
||||
|
||||
.empty-row td {
|
||||
text-align: center;
|
||||
padding: 3rem;
|
||||
color: #94a3b8;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ── Responsive ─── */
|
||||
@media (max-width: 768px) {
|
||||
.keg-wrap { padding: 1rem; }
|
||||
.keg-topbar { flex-direction: column; align-items: flex-start; gap: 12px; }
|
||||
.keg-stats { grid-template-columns: 1fr; gap: 12px; }
|
||||
.keg-filter-bar { flex-direction: column; align-items: stretch; }
|
||||
.keg-search, .keg-select, .keg-filter-btn { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="keg-wrap">
|
||||
|
||||
{{-- ALERTS --}}
|
||||
@if(session('success'))
|
||||
<div style="background:#dcfce7;color:#166534;padding:12px 18px;border-radius:12px;margin-bottom:1.2rem;font-size:13px;font-weight:600;">
|
||||
✓ {{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
@if(session('error'))
|
||||
<div style="background:#fee2e2;color:#b91c1c;padding:12px 18px;border-radius:12px;margin-bottom:1.2rem;font-size:13px;font-weight:600;">
|
||||
✗ {{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- TOPBAR --}}
|
||||
<div class="keg-topbar">
|
||||
<div>
|
||||
<div class="keg-title">Daftar Kegiatan</div>
|
||||
<div class="keg-sub">Monitor dan kelola seluruh kegiatan lapangan</div>
|
||||
</div>
|
||||
<a href="{{ route('admin.dashboard') }}" class="keg-btn-back">← Kembali ke Dashboard</a>
|
||||
</div>
|
||||
|
||||
{{-- STATS --}}
|
||||
@php
|
||||
$totalAll = $allItems->count();
|
||||
$totalSelesai = $allItems->where('status','selesai')->count();
|
||||
$totalProses = $allItems->where('status','on_progres')->count();
|
||||
@endphp
|
||||
<div class="keg-stats">
|
||||
<div class="kstat">
|
||||
<div class="kstat-icon blue">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="kstat-num">{{ $totalAll }}</div>
|
||||
<div class="kstat-label">Total Kegiatan</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kstat">
|
||||
<div class="kstat-icon green">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="kstat-num">{{ $totalSelesai }}</div>
|
||||
<div class="kstat-label">Selesai</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kstat">
|
||||
<div class="kstat-icon yellow">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="kstat-num">{{ $totalProses }}</div>
|
||||
<div class="kstat-label">Sedang Berjalan</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- FILTER BAR --}}
|
||||
<form method="GET" action="{{ route('admin.kegiatan.index') }}" class="keg-filter-bar">
|
||||
<input type="text" name="search" class="keg-search" placeholder="Cari nama kegiatan / penanggung jawab..." value="{{ request('search') }}">
|
||||
<select name="status" class="keg-select">
|
||||
<option value="semua" {{ request('status','semua')=='semua' ? 'selected':'' }}>Semua Status</option>
|
||||
<option value="on_progres" {{ request('status')=='on_progres' ? 'selected':'' }}>Sedang Berjalan</option>
|
||||
<option value="selesai" {{ request('status')=='selesai' ? 'selected':'' }}>Selesai</option>
|
||||
<option value="telah_ditinjau" {{ request('status')=='telah_ditinjau' ? 'selected':'' }}>Telah Ditinjau</option>
|
||||
</select>
|
||||
<button type="submit" class="keg-filter-btn">Cari</button>
|
||||
@if(request('search') || request('status'))
|
||||
<a href="{{ route('admin.kegiatan.index') }}" class="keg-btn-back" style="padding:9px 16px;font-size:12px;">Reset</a>
|
||||
@endif
|
||||
</form>
|
||||
|
||||
{{-- TABLE --}}
|
||||
<div class="keg-card">
|
||||
<div style="overflow-x: auto; width: 100%;">
|
||||
<table class="keg-table" style="min-width: 700px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Nama Kegiatan</th>
|
||||
<th>Penanggung Jawab</th>
|
||||
<th>Tanggal</th>
|
||||
<th>Status</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($activities as $i => $item)
|
||||
@php
|
||||
$namaUser = optional($item->user)->name ?? 'User Tidak Ada';
|
||||
$inisial = collect(explode(' ', $namaUser))
|
||||
->take(2)
|
||||
->map(fn($w) => strtoupper(substr($w,0,1)))
|
||||
->join('');
|
||||
$pillMap = [
|
||||
'selesai' => ['pill-ok', 'Selesai'],
|
||||
'on_progres' => ['pill-run', 'Berjalan'],
|
||||
'telah_ditinjau' => ['pill-rev', 'Ditinjau'],
|
||||
'dibatalkan' => ['pill-del', 'Dibatalkan'],
|
||||
];
|
||||
$pc = $pillMap[$item->status] ?? ['pill-run', ucfirst($item->status)];
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $activities->firstItem() + $i }}</td>
|
||||
<td><strong>{{ $item->nama_kegiatan }}</strong></td>
|
||||
<td>
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span style="background:#e0e7ff;color:#3730a3;width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;">{{ $inisial }}</span>
|
||||
{{ $namaUser }}
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ \Carbon\Carbon::parse($item->tanggal)->format('d M Y') }}</td>
|
||||
<td><span class="pill {{ $pc[0] }}">{{ $pc[1] }}</span></td>
|
||||
<td>
|
||||
<div style="display:flex;gap:6px;">
|
||||
<a href="{{ route('admin.kegiatan.show', $item->id) }}" class="act-btn btn-view">Lihat</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr class="empty-row">
|
||||
<td colspan="6">
|
||||
<div style="display:flex;flex-direction:column;align-items:center;gap:8px;color:#94a3b8;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>
|
||||
Tidak ada data kegiatan yang ditemukan.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pg-wrap">{{ $activities->links() }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard Admin – Disnaker Prov. Kalimantan Barat</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
background: #F2F5FB;
|
||||
color: #334155;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
main {
|
||||
min-height: 100vh;
|
||||
}
|
||||
::-webkit-scrollbar { width: 5px; }
|
||||
::-webkit-scrollbar-track { background: #f1f5f9; }
|
||||
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@include('admin.layouts.navbar')
|
||||
|
||||
<main class="pt-10 px-4">
|
||||
{{-- Yield inilah panggung untuk konten kamu --}}
|
||||
@yield('content')
|
||||
</main>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('[onclick^="return confirm"]').forEach(function(btn) {
|
||||
const match = btn.getAttribute('onclick').match(/confirm\('([^']+)'\)/);
|
||||
if (match) {
|
||||
const message = match[1];
|
||||
btn.removeAttribute('onclick');
|
||||
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
const form = btn.closest('form');
|
||||
|
||||
Swal.fire({
|
||||
title: 'Konfirmasi',
|
||||
text: message,
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3b82f6',
|
||||
cancelButtonColor: '#64748b',
|
||||
confirmButtonText: 'Ya, Lanjutkan',
|
||||
cancelButtonText: 'Batal',
|
||||
reverseButtons: true,
|
||||
customClass: {
|
||||
confirmButton: 'rounded-xl',
|
||||
cancelButton: 'rounded-xl mr-2'
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
if (form) {
|
||||
form.submit();
|
||||
} else if(btn.getAttribute('href')) {
|
||||
window.location.href = btn.getAttribute('href');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,146 @@
|
||||
@php
|
||||
$role = session('user')['role'] ?? '';
|
||||
$dashboardRoute = $role === 'superadmin' ? route('admin.superadmin.dashboard') : route('admin.dashboard');
|
||||
$usersRoute = $role === 'superadmin' ? route('admin.superadmin.user.index') : route('admin.users');
|
||||
$penugasanRoute = $role === 'superadmin' ? route('admin.superadmin.kegiatan.create') : route('admin.kegiatan.index');
|
||||
|
||||
$isDashboard = request()->routeIs('*.dashboard');
|
||||
$isUsers = request()->routeIs('*.user*') || request()->routeIs('*.users*');
|
||||
$isPenugasan = request()->routeIs('*.kegiatan.*');
|
||||
|
||||
$activeStyle = "bg-[#0D215C] text-white";
|
||||
$inactiveStyle = "text-slate-500 bg-transparent hover:bg-slate-100 hover:text-[#0D215C]";
|
||||
|
||||
$roleVal = session('user')['role'] ?? 'Administrator';
|
||||
if ($roleVal === 'admin') {
|
||||
$roleVal = 'Administrator';
|
||||
} elseif ($roleVal === 'superadmin') {
|
||||
$roleVal = 'Super Admin';
|
||||
} else {
|
||||
$roleVal = 'Petugas';
|
||||
}
|
||||
@endphp
|
||||
<nav class="bg-white border-b border-slate-200 shadow-[0_1px_12px_rgba(13,33,92,0.06)] sticky top-0 z-50">
|
||||
<div class="max-w-[1440px] mx-auto px-4 md:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center h-[66px]">
|
||||
{{-- Logo & Brand --}}
|
||||
<div class="flex items-center gap-2 md:gap-3">
|
||||
<img src="{{ asset('Kalimantan-Barat-Logo-Vector.png') }}"
|
||||
alt="Logo Kalbar"
|
||||
class="w-9 md:w-[46px] h-auto object-contain">
|
||||
<div class="border-l-2 border-slate-200 pl-2 md:pl-3">
|
||||
<p class="text-[11px] md:text-[13.5px] font-bold text-[#0D215C] tracking-tight leading-tight m-0">
|
||||
Dinas Tenaga Kerja dan Transmigrasi
|
||||
</p>
|
||||
<p class="text-[8px] md:text-[10px] font-medium text-slate-400 tracking-[1.8px] uppercase mt-0.5 m-0">
|
||||
Provinsi Kalimantan Barat
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hamburger Button (Mobile) -->
|
||||
<div class="flex md:hidden">
|
||||
<button type="button" id="admin-menu-btn" class="text-slate-500 hover:text-[#0D215C] focus:outline-none p-2 rounded-md hover:bg-slate-100 transition-colors">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{-- Nav + User (Desktop) --}}
|
||||
<div class="hidden md:flex items-center gap-2">
|
||||
<div class="flex items-center gap-1 mr-2">
|
||||
<a href="{{ $dashboardRoute }}" class="text-[11.5px] font-semibold tracking-[0.4px] px-[18px] py-2 rounded-lg flex items-center gap-[7px] transition-all duration-200 {{ $isDashboard ? $activeStyle : $inactiveStyle }}">
|
||||
<i data-lucide="layout-dashboard" class="w-3.5 h-3.5"></i> Dashboard
|
||||
</a>
|
||||
<a href="{{ $usersRoute }}" class="text-[11.5px] font-semibold tracking-[0.4px] px-[18px] py-2 rounded-lg flex items-center gap-[7px] transition-all duration-200 {{ $isUsers ? $activeStyle : $inactiveStyle }}">
|
||||
<i data-lucide="users" class="w-3.5 h-3.5"></i> Kelola Pengguna
|
||||
</a>
|
||||
<a href="{{ $penugasanRoute }}" class="text-[11.5px] font-semibold tracking-[0.4px] px-[18px] py-2 rounded-lg flex items-center gap-[7px] transition-all duration-200 {{ $isPenugasan ? $activeStyle : $inactiveStyle }}">
|
||||
<i data-lucide="clipboard-list" class="w-3.5 h-3.5"></i> Penugasan
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="w-px h-7 bg-slate-200 mx-1"></div>
|
||||
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="text-right">
|
||||
<p class="text-[13px] font-semibold text-slate-900 leading-none m-0">
|
||||
{{ session('user')['name'] ?? 'User' }}
|
||||
</p>
|
||||
<p class="text-[10px] font-medium text-slate-400 uppercase tracking-[1.2px] mt-1 m-0">
|
||||
{{ $roleVal }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="w-9 h-9 rounded-lg bg-gradient-to-br from-[#0D215C] to-blue-800 text-white flex items-center justify-center font-bold text-xs tracking-[0.5px]">
|
||||
{{ strtoupper(substr(session('user')['name'] ?? 'US',0,2)) }}
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('logout') }}" class="m-0">
|
||||
@csrf
|
||||
<button type="submit" class="w-9 h-9 rounded-lg bg-slate-50 text-slate-400 border border-slate-200 cursor-pointer flex items-center justify-center transition-all duration-200 hover:bg-rose-50 hover:text-rose-500 hover:border-rose-200" title="Keluar dari Sistem">
|
||||
<i data-lucide="log-out" class="w-3.5 h-3.5"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu Panel -->
|
||||
<div id="admin-mobile-menu" class="hidden md:hidden bg-white border-t border-slate-100 shadow-xl absolute w-full left-0 pb-4">
|
||||
<div class="px-4 py-3 flex flex-col gap-2">
|
||||
<a href="{{ $dashboardRoute }}" class="text-[13px] font-semibold tracking-[0.4px] px-4 py-3 rounded-lg flex items-center gap-3 transition-all duration-200 {{ $isDashboard ? $activeStyle : $inactiveStyle }}">
|
||||
<i data-lucide="layout-dashboard" class="w-4 h-4"></i> Dashboard
|
||||
</a>
|
||||
<a href="{{ $usersRoute }}" class="text-[13px] font-semibold tracking-[0.4px] px-4 py-3 rounded-lg flex items-center gap-3 transition-all duration-200 {{ $isUsers ? $activeStyle : $inactiveStyle }}">
|
||||
<i data-lucide="users" class="w-4 h-4"></i> Kelola Pengguna
|
||||
</a>
|
||||
<a href="{{ $penugasanRoute }}" class="text-[13px] font-semibold tracking-[0.4px] px-4 py-3 rounded-lg flex items-center gap-3 transition-all duration-200 {{ $isPenugasan ? $activeStyle : $inactiveStyle }}">
|
||||
<i data-lucide="clipboard-list" class="w-4 h-4"></i> Penugasan
|
||||
</a>
|
||||
|
||||
<div class="h-px w-full bg-slate-100 my-1"></div>
|
||||
|
||||
<div class="flex items-center justify-between px-2 py-2">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-9 h-9 rounded-lg bg-gradient-to-br from-[#0D215C] to-blue-800 text-white flex items-center justify-center font-bold text-xs tracking-[0.5px]">
|
||||
{{ strtoupper(substr(session('user')['name'] ?? 'US',0,2)) }}
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-[13px] font-semibold text-slate-900 leading-none m-0">
|
||||
{{ session('user')['name'] ?? 'User' }}
|
||||
</p>
|
||||
<p class="text-[10px] font-medium text-slate-400 uppercase tracking-[1.2px] mt-1 m-0">
|
||||
{{ $roleVal }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<form method="POST" action="{{ route('logout') }}" class="m-0">
|
||||
@csrf
|
||||
<button type="submit" class="w-9 h-9 rounded-lg bg-slate-50 text-slate-400 border border-slate-200 cursor-pointer flex items-center justify-center transition-all duration-200 hover:bg-rose-50 hover:text-rose-500 hover:border-rose-200" title="Keluar dari Sistem">
|
||||
<i data-lucide="log-out" class="w-4 h-4"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const btn = document.getElementById('admin-menu-btn');
|
||||
const menu = document.getElementById('admin-mobile-menu');
|
||||
if(btn && menu) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
menu.classList.toggle('hidden');
|
||||
lucide.createIcons();
|
||||
});
|
||||
document.addEventListener('click', function(e) {
|
||||
if(!menu.contains(e.target) && !btn.contains(e.target)) {
|
||||
menu.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,268 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
body, * { font-family: 'Plus Jakarta Sans', sans-serif; }
|
||||
|
||||
.user-wrap { padding: 2rem 2.5rem 3rem; max-width: 1200px; margin: 0 auto; }
|
||||
|
||||
/* ALERTS */
|
||||
.alert { padding: 12px 18px; border-radius: 12px; margin-bottom: 1.2rem; font-size: 13px; font-weight: 600; }
|
||||
.alert-success { background: #dcfce7; color: #166534; }
|
||||
.alert-error { background: #fee2e2; color: #b91c1c; }
|
||||
|
||||
/* HEADER */
|
||||
.user-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.user-title h2 { font-size: 26px; font-weight: 800; color: #0f172a; margin: 0; }
|
||||
.user-title p { font-size: 13px; color: #94a3b8; margin-top: 5px; }
|
||||
|
||||
.top-btn { display: flex; gap: 12px; }
|
||||
.btn-ui {
|
||||
border: none;
|
||||
padding: 10px 18px;
|
||||
border-radius: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
transition: .2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-dashboard { background: #eef2ff; color: #3730a3; }
|
||||
.btn-dashboard:hover { background: #dbeafe; transform: translateY(-2px); }
|
||||
.btn-add { background: #0D215C; color: #fff; box-shadow: 0 4px 14px rgba(13,33,92,.2); }
|
||||
.btn-add:hover { background: #1e3a8a; transform: translateY(-2px); }
|
||||
|
||||
/* STATS */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.stat-card {
|
||||
background: #fff;
|
||||
border-radius: 18px;
|
||||
padding: 1.2rem 1.4rem;
|
||||
border: 1px solid #edf1f7;
|
||||
transition: .25s;
|
||||
cursor: default;
|
||||
box-shadow: 0 2px 8px rgba(13,33,92,.04);
|
||||
}
|
||||
.stat-card:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(13,33,92,.1); }
|
||||
.stat-label { font-size: 11px; font-weight: 700; color: #94a3b8; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 8px; }
|
||||
.stat-number { font-size: 34px; font-weight: 800; color: #0f172a; }
|
||||
|
||||
/* TABLE */
|
||||
.user-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
border: 1px solid #edf1f7;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 12px rgba(13,33,92,.04);
|
||||
}
|
||||
.user-card-header {
|
||||
padding: 1.2rem 1.5rem;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
background: #f8fafc;
|
||||
}
|
||||
.user-card-header h3 { font-size: 15px; font-weight: 700; color: #0D215C; margin: 0; }
|
||||
|
||||
.table-wrap { overflow-x: auto; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
thead { background: #f8fafc; }
|
||||
thead th {
|
||||
padding: 14px 18px;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
color: #94a3b8;
|
||||
text-align: left;
|
||||
font-weight: 700;
|
||||
letter-spacing: .5px;
|
||||
}
|
||||
tbody td {
|
||||
padding: 15px 18px;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
vertical-align: middle;
|
||||
font-size: 13px;
|
||||
color: #334155;
|
||||
}
|
||||
tbody tr:hover { background: #f8fafc; }
|
||||
|
||||
.user-info { display: flex; align-items: center; gap: 12px; }
|
||||
.avatar {
|
||||
width: 40px; height: 40px;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, #0D215C, #2563eb);
|
||||
color: #fff;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.user-name { font-weight: 700; color: #0f172a; font-size: 14px; }
|
||||
.user-id { font-size: 11px; color: #94a3b8; margin-top: 2px; }
|
||||
|
||||
.role-badge {
|
||||
padding: 5px 14px;
|
||||
border-radius: 50px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .3px;
|
||||
}
|
||||
.role-superadmin { background: #fef3c7; color: #92400e; }
|
||||
.role-admin { background: #dbeafe; color: #1d4ed8; }
|
||||
.role-user { background: #dcfce7; color: #166534; }
|
||||
|
||||
.action-group { display: flex; gap: 8px; }
|
||||
.action-btn {
|
||||
border: none;
|
||||
padding: 7px 14px;
|
||||
border-radius: 10px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: .15s;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.btn-edit { background: #dbeafe; color: #2563eb; }
|
||||
.btn-edit:hover { background: #bfdbfe; }
|
||||
.btn-delete { background: #fee2e2; color: #dc2626; }
|
||||
.btn-delete:hover { background: #fecaca; }
|
||||
|
||||
/* RESPONSIVE */
|
||||
@media (max-width: 768px) {
|
||||
.user-wrap { padding: 1rem 0.5rem; }
|
||||
.user-header { flex-direction: column; align-items: flex-start; gap: 16px; margin-bottom: 1.5rem; }
|
||||
.top-btn { flex-wrap: wrap; width: 100%; }
|
||||
.top-btn .btn-ui { flex: 1; justify-content: center; text-align: center; }
|
||||
.stats-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 1.5rem; }
|
||||
.user-card-header { padding: 1rem; }
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.stats-grid { grid-template-columns: 1fr; }
|
||||
.user-title h2 { font-size: 22px; }
|
||||
.user-card { border-radius: 16px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="user-wrap">
|
||||
|
||||
{{-- ALERTS --}}
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success">✓ {{ session('success') }}</div>
|
||||
@endif
|
||||
@if(session('error'))
|
||||
<div class="alert alert-error">✗ {{ session('error') }}</div>
|
||||
@endif
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="user-header">
|
||||
<div class="user-title">
|
||||
<h2>Manajemen Pengguna</h2>
|
||||
<p>Kelola seluruh akun dan hak akses pengguna sistem</p>
|
||||
</div>
|
||||
<div class="top-btn">
|
||||
<a href="{{ route('admin.dashboard') }}" class="btn-ui btn-dashboard">← Dashboard</a>
|
||||
<a href="{{ route('admin.users.create') }}" class="btn-ui btn-add">+ Tambah Pengguna</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- STATS --}}
|
||||
@php
|
||||
$usersCol = collect($users);
|
||||
$totalUsers = $usersCol->count();
|
||||
$totalAdmin = $usersCol->where('role', 'admin')->count();
|
||||
$totalPetugas = $usersCol->where('role', 'user')->count();
|
||||
@endphp
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Total Pengguna</div>
|
||||
<div class="stat-number">{{ $totalUsers }}</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Administrator</div>
|
||||
<div class="stat-number">{{ $totalAdmin }}</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Petugas Lapangan</div>
|
||||
<div class="stat-number">{{ $totalPetugas }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- TABLE --}}
|
||||
<div class="user-card">
|
||||
<div class="user-card-header">
|
||||
<h3>Daftar Pengguna Sistem</h3>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Pengguna</th>
|
||||
<th>Username</th>
|
||||
<th>Jabatan</th>
|
||||
<th>Role</th>
|
||||
<th>Terdaftar</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($users as $user)
|
||||
@php $u = is_array($user) ? (object)$user : $user; @endphp
|
||||
<tr>
|
||||
<td>
|
||||
<div class="user-info">
|
||||
<div class="avatar">{{ strtoupper(substr($u->name ?? '-', 0, 2)) }}</div>
|
||||
<div>
|
||||
<div class="user-name">{{ $u->name ?? '-' }}</div>
|
||||
<div class="user-id">ID #{{ $u->id ?? '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ $u->username ?? '-' }}</td>
|
||||
<td>{{ $u->jabatan ?? '-' }}</td>
|
||||
<td>
|
||||
@if(($u->role ?? '') == 'superadmin')
|
||||
<span class="role-badge role-superadmin">Super Admin</span>
|
||||
@elseif(($u->role ?? '') == 'admin')
|
||||
<span class="role-badge role-admin">Administrator</span>
|
||||
@else
|
||||
<span class="role-badge role-user">Petugas</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if(!empty($u->created_at))
|
||||
{{ \Carbon\Carbon::parse($u->created_at)->format('d M Y') }}
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="5" style="text-align:center;padding:2.5rem;color:#94a3b8;font-size:13px;">
|
||||
Belum ada data pengguna.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,253 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login - Disnaker Kalbar</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
:root{
|
||||
--primary:#2b3f8f;
|
||||
--primary-dark:#1f2f6b;
|
||||
--bg:#f4f6fb;
|
||||
--muted:#6b7280;
|
||||
--border:#e5e7eb;
|
||||
}
|
||||
|
||||
*{margin:0;padding:0;box-sizing:border-box;font-family:'Inter',sans-serif;}
|
||||
body{height:100vh;display:flex;}
|
||||
|
||||
.left{
|
||||
width:50%;
|
||||
background:
|
||||
linear-gradient(rgba(0,0,0,0.6), rgba(0,0,0,0.8)),
|
||||
url("{{ asset('bg-login.jpeg') }}");
|
||||
background-size:cover;
|
||||
background-position:center;
|
||||
color:white;
|
||||
padding:70px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
justify-content:space-between;
|
||||
}
|
||||
|
||||
.brand{display:flex;align-items:center;gap:15px;}
|
||||
.brand img{height:100px;}
|
||||
|
||||
.brand-text{font-size:15px;font-weight:700;}
|
||||
|
||||
.hero{margin-top:-20px;max-width:520px;}
|
||||
|
||||
.hero h1{
|
||||
font-size:52px;
|
||||
font-weight:800;
|
||||
line-height:1.3;
|
||||
}
|
||||
|
||||
.hero h1::after{
|
||||
content:"";
|
||||
display:block;
|
||||
width:80px;
|
||||
height:4px;
|
||||
background:#60a5fa;
|
||||
margin-top:15px;
|
||||
border-radius:10px;
|
||||
}
|
||||
|
||||
.hero p{
|
||||
margin-top:20px;
|
||||
color:#dbeafe;
|
||||
line-height:1.8;
|
||||
}
|
||||
|
||||
.footer{
|
||||
font-size:12px;
|
||||
letter-spacing:2px;
|
||||
}
|
||||
|
||||
.right{
|
||||
width:50%;
|
||||
background:var(--bg);
|
||||
display:flex;
|
||||
justify-content:center;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.card{
|
||||
width:100%;
|
||||
max-width:420px;
|
||||
}
|
||||
|
||||
.card h2{
|
||||
font-size:34px;
|
||||
margin-bottom:8px;
|
||||
}
|
||||
|
||||
.card p{
|
||||
color:var(--muted);
|
||||
margin-bottom:25px;
|
||||
}
|
||||
|
||||
.input-group{margin-bottom:18px;}
|
||||
|
||||
.input-group label{
|
||||
font-size:12px;
|
||||
color:var(--muted);
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
.input-box{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
border:1px solid var(--border);
|
||||
border-radius:12px;
|
||||
padding:14px;
|
||||
margin-top:6px;
|
||||
background:white;
|
||||
}
|
||||
|
||||
.input-box i{
|
||||
margin-right:10px;
|
||||
color:#9ca3af;
|
||||
}
|
||||
|
||||
.input-box input{
|
||||
border:none;
|
||||
outline:none;
|
||||
width:100%;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.btn{
|
||||
width:100%;
|
||||
padding:14px;
|
||||
background:var(--primary);
|
||||
color:white;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.btn:hover{background:var(--primary-dark);}
|
||||
|
||||
.error{
|
||||
background:#fee2e2;
|
||||
color:#991b1b;
|
||||
padding:10px;
|
||||
border-radius:8px;
|
||||
margin-bottom:15px;
|
||||
font-size:13px;
|
||||
}
|
||||
|
||||
.copy{
|
||||
text-align:center;
|
||||
font-size:12px;
|
||||
margin-top:25px;
|
||||
color:#9ca3af;
|
||||
}
|
||||
|
||||
.toggle-password{cursor:pointer;}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
flex-direction: column;
|
||||
height: auto;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.left {
|
||||
width: 100%;
|
||||
padding: 40px 20px;
|
||||
min-height: 350px;
|
||||
gap: 30px;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 36px;
|
||||
}
|
||||
.right {
|
||||
width: 100%;
|
||||
padding: 40px 20px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="left">
|
||||
<div class="brand">
|
||||
<img src="{{ asset('Kalimantan-Barat-Logo-Vector.png') }}">
|
||||
<div class="brand-text">
|
||||
DINAS TENAGA KERJA DAN TRANSMIGRASI<br>
|
||||
<span style="font-weight:400;font-size:12px;">PROVINSI KALIMANTAN BARAT</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<h1>Sistem Monitoring<br>Aktivitas Pegawai</h1>
|
||||
<p>
|
||||
Platform terintegrasi untuk pelaporan aktivitas, pemantauan kinerja pegawai,
|
||||
serta tata kelola administrasi yang transparan, akuntabel, dan profesional.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
TRANSPARANSI • AKUNTABILITAS • INTEGRITAS
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<div class="card">
|
||||
|
||||
<h2>Selamat Datang</h2>
|
||||
<p>Silakan masuk untuk mengakses panel monitoring pegawai.</p>
|
||||
|
||||
@if(session('error'))
|
||||
<div class="error">{{ session('error') }}</div>
|
||||
@endif
|
||||
|
||||
<!-- 🔥 FIX UTAMA DI SINI -->
|
||||
<form method="POST" action="{{ route('login.user') }}">
|
||||
@csrf
|
||||
|
||||
<div class="input-group">
|
||||
<label>USERNAME</label>
|
||||
<div class="input-box">
|
||||
<i class="fas fa-user"></i>
|
||||
<input type="text" name="username" value="{{ old('username') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<label>KATA SANDI</label>
|
||||
<div class="input-box">
|
||||
<i class="fas fa-lock"></i>
|
||||
<input type="password" name="password" id="password" required>
|
||||
<i class="fas fa-eye toggle-password" onclick="togglePassword()"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn">Masuk ke Sistem →</button>
|
||||
</form>
|
||||
|
||||
<div class="copy">
|
||||
© 2026 DINAS TENAGA KERJA DAN TRANSMIGRASI <br>
|
||||
PROVINSI KALIMANTAN BARAT
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function togglePassword() {
|
||||
const input = document.getElementById('password');
|
||||
input.type = input.type === 'password' ? 'text' : 'password';
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,334 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
{{-- STYLES --}}
|
||||
<style>
|
||||
/* Reset & Base */
|
||||
:root {
|
||||
--bg-main: #f4f7fb;
|
||||
--card-bg: #ffffff;
|
||||
--text-primary: #0f172a;
|
||||
--text-secondary: #475569;
|
||||
--text-muted: #94a3b8;
|
||||
--text-faint: #cbd5e1;
|
||||
--border-color: #e2e8f0;
|
||||
|
||||
--blue-dark: #0D215C;
|
||||
--blue-mid: #2563eb;
|
||||
--blue-pale: #bfdbfe;
|
||||
--blue-ultra: #eff6ff;
|
||||
|
||||
--green: #10b981;
|
||||
--red: #ef4444;
|
||||
--amber: #f59e0b;
|
||||
}
|
||||
|
||||
.sa-container {
|
||||
padding: 30px;
|
||||
background: var(--bg-main);
|
||||
min-height: calc(100vh - 70px);
|
||||
font-family: 'Outfit', 'Segoe UI', sans-serif;
|
||||
}
|
||||
|
||||
.sa-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.sa-title-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sa-title-wrap h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -1px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.sa-title-wrap h1::after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: 4px;
|
||||
background: #000;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.btn-back {
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
color: var(--blue-mid);
|
||||
font-weight: 600;
|
||||
background: #fff;
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-back:hover {
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Cards Grid */
|
||||
.news-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.news-card {
|
||||
background: var(--card-bg);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.04);
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid rgba(226,232,240,0.6);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.news-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 12px 30px rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
.news-card a:hover .news-title {
|
||||
color: var(--blue-mid);
|
||||
}
|
||||
|
||||
.news-image {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
object-fit: cover;
|
||||
background-color: #e2e8f0;
|
||||
}
|
||||
|
||||
.news-content {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.news-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.news-meta svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.news-title {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.4;
|
||||
margin: 0 0 12px 0;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.news-footer {
|
||||
margin-top: auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
padding: 4px 10px;
|
||||
border-radius: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.status-badge.selesai { background: #ecfdf5; color: #059669; }
|
||||
.status-badge.proses { background: #eff6ff; color: #2563eb; }
|
||||
.status-badge.batal { background: #fef2f2; color: #dc2626; }
|
||||
|
||||
.btn-restore {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--blue-mid);
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-restore:hover {
|
||||
background: var(--blue-ultra);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
border: 1px dashed var(--border-color);
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sa-container {
|
||||
padding: 15px;
|
||||
}
|
||||
.sa-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 15px;
|
||||
}
|
||||
.btn-back {
|
||||
align-self: flex-start;
|
||||
}
|
||||
.news-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{{-- ICONS --}}
|
||||
<svg width="0" height="0" style="position:absolute; display:none;">
|
||||
<symbol id="ic-calendar" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
|
||||
<line x1="16" y1="2" x2="16" y2="6"></line>
|
||||
<line x1="8" y1="2" x2="8" y2="6"></line>
|
||||
<line x1="3" y1="10" x2="21" y2="10"></line>
|
||||
</symbol>
|
||||
<symbol id="ic-eye" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
</symbol>
|
||||
<symbol id="ic-restore" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
|
||||
<path d="M3 3v5h5"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<div class="sa-container">
|
||||
<div class="sa-header">
|
||||
<div class="sa-title-wrap">
|
||||
<h1>Arsip Laporan</h1>
|
||||
</div>
|
||||
<a href="{{ route('admin.superadmin.dashboard') }}" class="btn-back">← Kembali ke Dashboard</a>
|
||||
</div>
|
||||
|
||||
@if(session('success'))
|
||||
<div style="padding:14px 18px; background:#ecfdf5; border:1px solid #a7f3d0; border-radius:12px; color:#047857; font-size:14px; font-weight:600; margin-bottom:24px; display:flex; align-items:center; gap:10px;">
|
||||
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"></path></svg>
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
@if(session('error'))
|
||||
<div style="padding:14px 18px; background:#fef2f2; border:1px solid #fecaca; border-radius:12px; color:#dc2626; font-size:14px; font-weight:600; margin-bottom:24px; display:flex; align-items:center; gap:10px;">
|
||||
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg>
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="news-grid">
|
||||
@forelse($activities as $act)
|
||||
@php
|
||||
// Generate a consistent dummy views count based on ID
|
||||
$views = ($act->id * 17) % 1000 + 50;
|
||||
|
||||
// Array of default placeholder images for variety
|
||||
$placeholders = [
|
||||
'https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?q=80&w=600&auto=format&fit=crop', // office/planning
|
||||
'https://images.unsplash.com/photo-1517048676732-d65bc937f952?q=80&w=600&auto=format&fit=crop', // teamwork
|
||||
'https://images.unsplash.com/photo-1552664730-d307ca884978?q=80&w=600&auto=format&fit=crop', // meeting
|
||||
'https://images.unsplash.com/photo-1507537297725-24a1c029d3ca?q=80&w=600&auto=format&fit=crop', // paper/desk
|
||||
'https://images.unsplash.com/photo-1581091226825-a6a2a5aee158?q=80&w=600&auto=format&fit=crop' // tech/research
|
||||
];
|
||||
$imgSrc = $placeholders[$act->id % count($placeholders)];
|
||||
@endphp
|
||||
<div class="news-card">
|
||||
<a href="{{ route('admin.superadmin.kegiatan.show', $act->id) }}" style="text-decoration: none; color: inherit; display: flex; flex-direction: column; flex-grow: 1;">
|
||||
<img src="{{ $imgSrc }}" alt="Laporan Image" class="news-image" loading="lazy">
|
||||
<div class="news-content" style="padding-bottom: 0; flex-grow: 1;">
|
||||
<div class="news-meta">
|
||||
<div class="meta-item">
|
||||
<svg><use href="#ic-calendar"/></svg>
|
||||
<span>{{ \Carbon\Carbon::parse($act->tanggal)->translatedFormat('d M Y') }}</span>
|
||||
</div>
|
||||
<span>•</span>
|
||||
<div class="meta-item">
|
||||
<svg><use href="#ic-eye"/></svg>
|
||||
<span>{{ $views }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="news-title" title="{{ $act->nama_kegiatan }}">{{ $act->nama_kegiatan }}</h3>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="news-content" style="padding-top: 10px; flex-grow: 0;">
|
||||
<div class="news-footer">
|
||||
<span class="status-badge {{ $act->status == 'selesai' ? 'selesai' : ($act->status == 'dibatalkan' ? 'batal' : 'proses') }}">
|
||||
{{ strtoupper(str_replace('_', ' ', $act->status)) }}
|
||||
</span>
|
||||
|
||||
<form action="{{ route('admin.superadmin.kegiatan.archive', $act->id) }}" method="POST" style="margin: 0;">
|
||||
@csrf
|
||||
<button type="submit" class="btn-restore" title="Kembalikan Laporan">
|
||||
<svg width="16" height="16"><use href="#ic-restore"/></svg>
|
||||
Restore
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="empty-state">
|
||||
<svg width="64" height="64" style="color:var(--text-faint); margin-bottom:15px;" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 002-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path></svg>
|
||||
<h3>Belum ada arsip laporan</h3>
|
||||
<p>Laporan yang diarsipkan akan muncul di sini.</p>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
@if($activities->hasPages())
|
||||
<div style="margin-top:40px; display:flex; justify-content:center;">
|
||||
{{ $activities->links('pagination::bootstrap-4') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endsection
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,125 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-container { padding: 40px 20px; background: #f4f7fb; min-height: calc(100vh - 70px); font-family: 'Outfit', 'Segoe UI', sans-serif; display: flex; flex-direction: column; align-items: center; }
|
||||
.form-card { background: #fff; border-radius: 24px; box-shadow: 0 10px 40px rgba(0,0,0,0.03); width: 100%; max-width: 600px; padding: 35px 40px; box-sizing: border-box; }
|
||||
.date-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 35px; }
|
||||
.page-title { font-size: 28px; font-weight: 800; color: #0f172a; margin: 0 0 8px; letter-spacing: -0.5px; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-container { padding: 20px 15px !important; }
|
||||
.form-card { padding: 25px 20px !important; border-radius: 16px !important; }
|
||||
.date-grid { grid-template-columns: 1fr !important; gap: 15px !important; margin-bottom: 25px !important; }
|
||||
.page-title { font-size: 24px !important; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="page-container">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div style="text-align:center; margin-bottom:30px;">
|
||||
<h1 class="page-title">Buat Penugasan Baru</h1>
|
||||
<p style="margin:0; color:#64748b; font-size:15px; font-weight:500;">Berikan instruksi tugas kepada pegawai lapangan</p>
|
||||
</div>
|
||||
|
||||
@if(session('error'))
|
||||
<div style="width:100%; max-width:600px; margin-bottom:20px; padding:14px 18px; background:#fff1f2; border:1px solid #fecdd3; border-radius:12px; color:#be123c; font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px;">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- FORM CARD --}}
|
||||
<div class="form-card">
|
||||
<form action="{{ route('admin.superadmin.kegiatan.store') }}" method="POST">
|
||||
@csrf
|
||||
|
||||
@if ($errors->any())
|
||||
<div style="margin-bottom:20px; padding:14px 18px; background:#fff1f2; border:1px solid #fecdd3; border-radius:12px;">
|
||||
<p style="font-weight:700; color:#be123c; margin:0 0 8px; font-size:13px;">Terdapat kesalahan input:</p>
|
||||
<ul style="margin:0; padding-left:18px; color:#be123c; font-size:13px;">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div style="margin-bottom:24px;">
|
||||
<label style="display:block; font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1.5px; margin-bottom:8px; text-transform:uppercase;">
|
||||
Nomor Surat
|
||||
</label>
|
||||
<input type="text" name="nomor_surat" value="{{ old('nomor_surat') }}"
|
||||
style="width:100%; padding:14px 16px; background:#f8fafc; border:2px solid transparent; border-radius:12px; font-size:15px; color:#0f172a; outline:none; box-sizing:border-box; transition:all 0.2s; font-family:inherit; font-weight:500;"
|
||||
onfocus="this.style.borderColor='#e0e7ff'; this.style.background='#fff'" onblur="this.style.borderColor='transparent'; this.style.background='#f8fafc'"
|
||||
placeholder="Contoh: 001/ST/V/2026" required>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom:24px;">
|
||||
<label style="display:block; font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1.5px; margin-bottom:8px; text-transform:uppercase;">
|
||||
Nama Kegiatan
|
||||
</label>
|
||||
<input type="text" name="kegiatan" value="{{ old('kegiatan') }}"
|
||||
style="width:100%; padding:14px 16px; background:#f8fafc; border:2px solid transparent; border-radius:12px; font-size:15px; color:#0f172a; outline:none; box-sizing:border-box; transition:all 0.2s; font-family:inherit; font-weight:500;"
|
||||
onfocus="this.style.borderColor='#e0e7ff'; this.style.background='#fff'" onblur="this.style.borderColor='transparent'; this.style.background='#f8fafc'"
|
||||
placeholder="Contoh: Monitoring Jaringan Dishub" required>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom:24px;">
|
||||
<label style="display:block; font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1.5px; margin-bottom:8px; text-transform:uppercase;">
|
||||
Pilih Petugas (Multiple)
|
||||
</label>
|
||||
<select name="pegawai_ids[]" multiple required
|
||||
style="width:100%; padding:14px 16px; background:#f8fafc; border:2px solid transparent; border-radius:12px; font-size:14px; color:#334155; outline:none; box-sizing:border-box; transition:all 0.2s; font-family:inherit; font-weight:500; height:140px; line-height:1.5;"
|
||||
onfocus="this.style.borderColor='#e0e7ff'; this.style.background='#fff'" onblur="this.style.borderColor='transparent'; this.style.background='#f8fafc'">
|
||||
@foreach($users as $user)
|
||||
<option value="{{ $user['id'] }}" style="padding:6px 0; border-bottom:1px solid #f1f5f9;">
|
||||
{{ $user['name'] }} - {{ $user['jabatan'] ?? 'Pegawai' }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<p style="font-size:11px; color:#94a3b8; margin-top:8px; font-weight:500;">* Tahan Ctrl/Cmd untuk memilih lebih dari 1 orang</p>
|
||||
</div>
|
||||
|
||||
<div class="date-grid">
|
||||
<div>
|
||||
<label style="display:block; font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1.5px; margin-bottom:8px; text-transform:uppercase;">
|
||||
Tanggal Mulai
|
||||
</label>
|
||||
<input type="date" name="tanggal_mulai" value="{{ old('tanggal_mulai') }}"
|
||||
style="width:100%; padding:14px 16px; background:#f8fafc; border:2px solid transparent; border-radius:12px; font-size:14px; color:#334155; outline:none; box-sizing:border-box; transition:all 0.2s; font-family:inherit; font-weight:500; color-scheme:light;"
|
||||
onfocus="this.style.borderColor='#e0e7ff'; this.style.background='#fff'" onblur="this.style.borderColor='transparent'; this.style.background='#f8fafc'" required>
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block; font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1.5px; margin-bottom:8px; text-transform:uppercase;">
|
||||
Tanggal Selesai
|
||||
</label>
|
||||
<input type="date" name="tanggal_selesai" value="{{ old('tanggal_selesai') }}"
|
||||
style="width:100%; padding:14px 16px; background:#f8fafc; border:2px solid transparent; border-radius:12px; font-size:14px; color:#334155; outline:none; box-sizing:border-box; transition:all 0.2s; font-family:inherit; font-weight:500; color-scheme:light;"
|
||||
onfocus="this.style.borderColor='#e0e7ff'; this.style.background='#fff'" onblur="this.style.borderColor='transparent'; this.style.background='#f8fafc'">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
style="width:100%; padding:16px; background:#0D215C; color:#fff; border:none; border-radius:12px; font-size:15px; font-weight:800; cursor:pointer; font-family:inherit; transition:all 0.2s;"
|
||||
onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 8px 20px rgba(13,33,92,0.2)'"
|
||||
onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='none'">
|
||||
Konfirmasi & Kirim Tugas
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- KEMBALI LINK --}}
|
||||
<div style="margin-top:30px;">
|
||||
<a href="{{ route('admin.superadmin.dashboard') }}"
|
||||
style="font-size:13px; font-weight:700; color:#64748b; letter-spacing:1px; text-decoration:none; text-transform:uppercase; transition:color 0.2s;"
|
||||
onmouseover="this.style.color='#0D215C'" onmouseout="this.style.color='#64748b'">
|
||||
Kembali Ke Dashboard
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,202 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
<style>
|
||||
.page-container { padding: 40px 20px; background: #f4f7fb; min-height: calc(100vh - 70px); font-family: 'Outfit', 'Segoe UI', sans-serif; display: flex; flex-direction: column; align-items: center; box-sizing: border-box; }
|
||||
.detail-card { background: #fff; border-radius: 24px; box-shadow: 0 10px 40px rgba(0,0,0,0.03); width: 100%; max-width: 700px; overflow: hidden; box-sizing: border-box; }
|
||||
.card-header { padding: 30px 40px; border-bottom: 1px solid #f1f5f9; display: flex; justify-content: space-between; align-items: flex-start; }
|
||||
.info-grid { padding: 30px 40px; display: flex; gap: 30px; border-top: 1px solid #f1f5f9; }
|
||||
.section-padding { padding: 30px 40px; }
|
||||
.action-card { margin-top: 20px; background: white; padding: 24px 30px; border-radius: 16px; border: 1px solid #e2e8f0; box-shadow: 0 4px 6px rgba(0,0,0,0.02); width: 100%; max-width: 700px; box-sizing: border-box; }
|
||||
.action-flex { display: flex; gap: 16px; flex-wrap: wrap; }
|
||||
.revision-form { display: flex; gap: 10px; flex: 1; min-width: 300px; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-container { padding: 20px 15px !important; }
|
||||
.detail-card { border-radius: 16px !important; }
|
||||
.card-header { flex-direction: column !important; gap: 20px !important; padding: 20px 20px !important; }
|
||||
.card-header > div:last-child { text-align: left !important; }
|
||||
.info-grid { flex-direction: column !important; gap: 20px !important; padding: 20px 20px !important; }
|
||||
.section-padding { padding: 20px 20px !important; }
|
||||
.action-card { padding: 20px !important; }
|
||||
.revision-form { flex-direction: column !important; min-width: 100% !important; }
|
||||
.revision-form button { width: 100% !important; }
|
||||
}
|
||||
</style>
|
||||
<div class="page-container">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div style="text-align:center; margin-bottom:30px;">
|
||||
<h1 style="font-size:28px; font-weight:800; color:#0f172a; margin:0 0 8px; letter-spacing:-0.5px;">Detail Penugasan</h1>
|
||||
<p style="margin:0; color:#64748b; font-size:15px; font-weight:500;">Tinjauan lengkap tentang kegiatan dan petugas yang ditugaskan</p>
|
||||
</div>
|
||||
|
||||
@if(session('success'))
|
||||
<div style="width:100%; max-width:700px; margin-bottom:20px; padding:14px 18px; background:#ecfdf5; border:1px solid #a7f3d0; border-radius:12px; color:#047857; font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px;">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- DETAIL CARD --}}
|
||||
<div class="detail-card">
|
||||
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<span style="display:inline-block; padding:6px 12px; border-radius:20px; font-size:11px; font-weight:800; letter-spacing:1px; text-transform:uppercase; margin-bottom:12px;
|
||||
{{ $activity->status == 'selesai' ? 'background:#ecfdf5; color:#059669;' :
|
||||
($activity->status == 'dibatalkan' ? 'background:#fef2f2; color:#dc2626;' : 'background:#eff6ff; color:#2563eb;') }}">
|
||||
{{ str_replace('_', ' ', $activity->status) }}
|
||||
</span>
|
||||
<h2 style="margin:0 0 5px; font-size:22px; font-weight:800; color:#0f172a;">{{ $activity->nama_kegiatan }}</h2>
|
||||
<div style="color:#64748b; font-size:13px; font-weight:500;">Nomor Surat: {{ $activity->nomor_surat ?? '-' }}</div>
|
||||
</div>
|
||||
<div style="text-align:right;">
|
||||
<div style="font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1px; text-transform:uppercase; margin-bottom:4px;">Tanggal Mulai</div>
|
||||
<div style="font-size:15px; font-weight:700; color:#0f172a; margin-bottom:10px;">{{ \Carbon\Carbon::parse($activity->tanggal)->translatedFormat('d F Y') }}</div>
|
||||
|
||||
<div style="font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1px; text-transform:uppercase; margin-bottom:4px;">Tenggat Waktu</div>
|
||||
<div style="font-size:15px; font-weight:700; color:#0f172a;">
|
||||
@if($activity->tanggal_selesai)
|
||||
@php
|
||||
$isOverdue = \Carbon\Carbon::parse($activity->tanggal_selesai)->isPast() && $activity->status !== 'selesai' && $activity->status !== 'telah_ditinjau';
|
||||
@endphp
|
||||
<span style="{{ $isOverdue ? 'color:#dc2626; font-weight:800;' : '' }}">
|
||||
{{ \Carbon\Carbon::parse($activity->tanggal_selesai)->translatedFormat('d F Y') }}
|
||||
@if($isOverdue) <span style="font-size:11px; color:#ef4444; margin-left:4px;">(Terlambat)</span> @endif
|
||||
</span>
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-padding" style="background:#f8fafc;">
|
||||
<h3 style="font-size:13px; font-weight:800; color:#64748b; letter-spacing:1.5px; text-transform:uppercase; margin:0 0 16px;">Ditugaskan Kepada</h3>
|
||||
|
||||
<div style="display:flex; flex-direction:column; gap:12px;">
|
||||
@forelse($activity->petugas ?? [] as $petugas)
|
||||
<div style="display:flex; align-items:center; gap:15px; background:#fff; padding:12px 16px; border-radius:12px; border:1px solid #e2e8f0;">
|
||||
<div style="width:40px; height:40px; border-radius:50%; background:#e0e7ff; color:#3730a3; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:14px;">
|
||||
{{ strtoupper(substr($petugas['name'], 0, 2)) }}
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size:14px; font-weight:700; color:#0f172a; margin-bottom:2px;">{{ $petugas['name'] }}</div>
|
||||
<div style="font-size:12px; color:#64748b; font-weight:500;">{{ $petugas['jabatan'] ?? 'Petugas Lapangan' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div style="font-size:13px; color:#94a3b8; font-style:italic;">Belum ada petugas yang ditetapkan.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-grid">
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1px; text-transform:uppercase; margin-bottom:6px;">Lokasi Tugas</div>
|
||||
<div style="font-size:14px; font-weight:600; color:#0f172a;">{{ $activity->lokasi ?? '-' }}</div>
|
||||
</div>
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1px; text-transform:uppercase; margin-bottom:6px;">Deskripsi Tugas</div>
|
||||
<div style="font-size:14px; font-weight:500; color:#334155;">{{ $activity->deskripsi ?? '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(!empty($activity->status_note))
|
||||
<div class="section-padding" style="background:#eff6ff; border-top:1px solid #bfdbfe;">
|
||||
<div style="font-size:11px; font-weight:800; color:#2563eb; letter-spacing:1px; text-transform:uppercase; margin-bottom:8px;">Catatan Status Terakhir</div>
|
||||
<div style="font-size:14px; font-weight:500; color:#1e3a8a; line-height:1.6;">{{ $activity->status_note }}</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- TIMELINE PROGRESS MONITORING --}}
|
||||
<div class="section-padding" style="background:#ffffff; border-top:1px solid #f1f5f9;">
|
||||
<div style="font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1px; text-transform:uppercase; margin-bottom:20px;">Log Monitoring Progress</div>
|
||||
|
||||
@if(isset($activity->progress) && count($activity->progress) > 0)
|
||||
<div style="position:relative; border-left:2px solid #e0e7ff; margin-left:10px; padding-left:20px; display:flex; flex-direction:column; gap:24px;">
|
||||
@foreach($activity->progress as $prog)
|
||||
<div style="position:relative;">
|
||||
<div style="position:absolute; left:-27px; top:4px; width:12px; height:12px; background:#6366f1; border-radius:50%; border:2px solid #fff;"></div>
|
||||
<div style="font-size:12px; color:#64748b; margin-bottom:4px;">
|
||||
{{ \Carbon\Carbon::parse($prog['created_at'])->format('d M Y, H:i') }} •
|
||||
<span style="font-weight:700; color:#6366f1;">{{ $prog['user']['name'] ?? 'Pegawai' }}</span>
|
||||
</div>
|
||||
<div style="font-size:14px; color:#334155; background:#f8fafc; border:1px solid #f1f5f9; padding:12px 16px; border-radius:10px;">
|
||||
{{ $prog['note'] }}
|
||||
@if(!empty($prog['attachment']))
|
||||
<div style="margin-top:10px; padding-top:10px; border-top:1px solid #e2e8f0;">
|
||||
<a href="http://127.0.0.1:8000/{{ $prog['attachment'] }}" target="_blank"
|
||||
style="display:inline-block; font-size:12px; font-weight:600; color:#4f46e5; text-decoration:none; background:#e0e7ff; padding:4px 10px; border-radius:6px; border:1px solid #c7d2fe;">
|
||||
📎 Lihat Lampiran Bukti
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div style="font-size:13px; color:#64748b; background:#f8fafc; padding:20px; border-radius:10px; text-align:center; border:1px dashed #cbd5e1;">
|
||||
Belum ada log progress yang dicatat untuk kegiatan ini.
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="info-grid">
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1px; text-transform:uppercase; margin-bottom:6px;">Dibuat Oleh</div>
|
||||
<div style="font-size:14px; font-weight:600; color:#0f172a;">{{ $activity->user->name ?? 'System' }}</div>
|
||||
</div>
|
||||
<div style="flex:1;">
|
||||
<div style="font-size:11px; font-weight:800; color:#94a3b8; letter-spacing:1px; text-transform:uppercase; margin-bottom:6px;">Pembaruan Terakhir</div>
|
||||
<div style="font-size:14px; font-weight:600; color:#0f172a;">{{ $activity->updated_at->diffForHumans() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- TINDAKAN REVIEW (SUPERADMIN) --}}
|
||||
@if($activity->status == 'selesai')
|
||||
<div class="action-card">
|
||||
<h4 style="margin-top:0; margin-bottom:16px; font-size:16px; color:#1e293b;">Tindakan Review (Verifikasi)</h4>
|
||||
|
||||
<div class="action-flex">
|
||||
{{-- Setujui (Telah Ditinjau) --}}
|
||||
<form action="{{ route('admin.superadmin.kegiatan.approve', $activity->id) }}" method="POST">
|
||||
@csrf
|
||||
<button type="submit" onclick="return confirm('Setujui laporan ini?')"
|
||||
style="background:#16a34a; color:white; border:none; padding:10px 20px; border-radius:10px; font-weight:600; font-size:14px; cursor:pointer; transition:0.2s;"
|
||||
onmouseover="this.style.background='#15803d'" onmouseout="this.style.background='#16a34a'">
|
||||
✓ Setujui (Telah Ditinjau)
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{{-- Minta Revisi --}}
|
||||
<form action="{{ route('admin.superadmin.kegiatan.revision', $activity->id) }}" method="POST" class="revision-form">
|
||||
@csrf
|
||||
<input type="text" name="status_note" required placeholder="Catatan Revisi (misal: Mohon perbaiki foto)"
|
||||
style="flex:1; padding:10px 16px; border:1px solid #cbd5e1; border-radius:10px; font-size:14px; outline:none;"
|
||||
onfocus="this.style.borderColor='#3b82f6'" onblur="this.style.borderColor='#cbd5e1'">
|
||||
<button type="submit" onclick="return confirm('Kembalikan laporan ini ke pegawai untuk direvisi?')"
|
||||
style="background:#f59e0b; color:white; border:none; padding:10px 20px; border-radius:10px; font-weight:600; font-size:14px; cursor:pointer; transition:0.2s; white-space:nowrap;"
|
||||
onmouseover="this.style.background='#d97706'" onmouseout="this.style.background='#f59e0b'">
|
||||
⟲ Minta Revisi
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- KEMBALI LINK --}}
|
||||
<div style="margin-top:30px;">
|
||||
<a href="{{ route('admin.superadmin.dashboard') }}"
|
||||
style="font-size:13px; font-weight:700; color:#64748b; letter-spacing:1px; text-decoration:none; text-transform:uppercase; transition:color 0.2s;"
|
||||
onmouseover="this.style.color='#0D215C'" onmouseout="this.style.color='#64748b'">
|
||||
Kembali Ke Dashboard
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,222 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-container { padding: 28px 32px; background: #f1f5f9; min-height: 100vh; font-family: 'Figtree', 'Segoe UI', sans-serif; }
|
||||
.header-flex { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 28px; }
|
||||
.main-grid { display: grid; grid-template-columns: 1fr 300px; gap: 20px; align-items: flex-start; }
|
||||
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px; }
|
||||
.form-actions { border-top: 1px solid #f1f5f9; padding-top: 20px; display: flex; gap: 10px; justify-content: flex-end; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-container { padding: 16px 12px !important; }
|
||||
.header-flex { flex-direction: column !important; gap: 16px !important; }
|
||||
.main-grid { grid-template-columns: 1fr !important; }
|
||||
.form-grid { grid-template-columns: 1fr !important; gap: 15px !important; }
|
||||
.form-actions { flex-direction: column !important; }
|
||||
.form-actions a, .form-actions button { width: 100% !important; justify-content: center; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="page-container">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="header-flex">
|
||||
<div>
|
||||
<a href="{{ route('admin.superadmin.user.index') }}"
|
||||
style="font-size:12px; color:#64748b; text-decoration:none; display:inline-flex; align-items:center; gap:5px; margin-bottom:10px; font-weight:600;"
|
||||
onmouseover="this.style.color='#0D215C'" onmouseout="this.style.color='#64748b'">
|
||||
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
|
||||
<path d="M19 12H5M12 5l-7 7 7 7"/>
|
||||
</svg>
|
||||
Kembali ke Manajemen Pengguna
|
||||
</a>
|
||||
<p style="font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:1.8px; margin:0 0 6px; text-transform:uppercase;">Panel Kendali Sistem</p>
|
||||
<h1 style="font-size:28px; font-weight:800; color:#0f172a; margin:0 0 4px;">Tambah Pengguna</h1>
|
||||
<p style="margin:0; color:#94a3b8; font-size:13px;">Buat akun baru untuk pegawai atau administrator sistem</p>
|
||||
</div>
|
||||
<div style="background:#eef2ff; color:#4338ca; padding:9px 14px; border-radius:10px; font-size:12px; font-weight:700; display:flex; align-items:center; gap:6px;">
|
||||
<div style="width:8px; height:8px; background:#4338ca; border-radius:50%;"></div>
|
||||
{{ strtoupper(session('user')['role'] ?? 'ADMINISTRATOR') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(session('error'))
|
||||
<div style="margin-bottom:20px; padding:14px 18px; background:#fff1f2; border:1px solid #fecdd3; border-radius:12px; color:#be123c; font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px;">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="main-grid">
|
||||
|
||||
{{-- FORM CARD --}}
|
||||
<div style="background:#fff; border-radius:16px; border:1px solid #e2e8f0; overflow:hidden;">
|
||||
<div style="padding:20px 24px; border-bottom:1px solid #f1f5f9; display:flex; align-items:center; gap:10px;">
|
||||
<div style="width:32px; height:32px; background:#eff6ff; border-radius:8px; display:flex; align-items:center; justify-content:center;">
|
||||
<svg width="16" height="16" fill="none" stroke="#2563eb" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<line x1="19" y1="8" x2="19" y2="14"/>
|
||||
<line x1="22" y1="11" x2="16" y2="11"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 style="margin:0; font-size:16px; font-weight:700; color:#0f172a;">Data Pengguna Baru</h3>
|
||||
</div>
|
||||
|
||||
<form action="{{ route('admin.superadmin.user.store') }}" method="POST" style="padding:28px 24px;">
|
||||
@csrf
|
||||
|
||||
@if ($errors->any())
|
||||
<div style="margin-bottom:20px; padding:14px 18px; background:#fff1f2; border:1px solid #fecdd3; border-radius:12px;">
|
||||
<p style="font-weight:700; color:#be123c; margin:0 0 8px; font-size:13px;">Terdapat kesalahan input:</p>
|
||||
<ul style="margin:0; padding-left:18px; color:#be123c; font-size:13px;">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="form-grid">
|
||||
{{-- NAMA --}}
|
||||
<div>
|
||||
<label style="display:block; font-size:13px; font-weight:700; color:#374151; margin-bottom:8px;">
|
||||
Nama Lengkap <span style="color:#ef4444;">*</span>
|
||||
</label>
|
||||
<input type="text" name="name" value="{{ old('name') }}"
|
||||
style="width:100%; padding:11px 14px; border:1.5px solid #e2e8f0; border-radius:10px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box;"
|
||||
onfocus="this.style.borderColor='#2563eb'" onblur="this.style.borderColor='#e2e8f0'"
|
||||
placeholder="Nama lengkap pegawai" required>
|
||||
</div>
|
||||
|
||||
{{-- USERNAME --}}
|
||||
<div>
|
||||
<label style="display:block; font-size:13px; font-weight:700; color:#374151; margin-bottom:8px;">
|
||||
Username <span style="color:#ef4444;">*</span>
|
||||
</label>
|
||||
<input type="text" name="username" value="{{ old('username') }}"
|
||||
style="width:100%; padding:11px 14px; border:1.5px solid #e2e8f0; border-radius:10px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box;"
|
||||
onfocus="this.style.borderColor='#2563eb'" onblur="this.style.borderColor='#e2e8f0'"
|
||||
placeholder="Username untuk login" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-grid">
|
||||
{{-- PASSWORD --}}
|
||||
<div>
|
||||
<label style="display:block; font-size:13px; font-weight:700; color:#374151; margin-bottom:8px;">
|
||||
Kata Sandi <span style="color:#ef4444;">*</span>
|
||||
</label>
|
||||
<div style="position:relative;">
|
||||
<input type="password" name="password" id="password_field"
|
||||
style="width:100%; padding:11px 40px 11px 14px; border:1.5px solid #e2e8f0; border-radius:10px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box;"
|
||||
onfocus="this.style.borderColor='#2563eb'" onblur="this.style.borderColor='#e2e8f0'"
|
||||
placeholder="Minimal 6 karakter" required>
|
||||
<button type="button" onclick="togglePassword('password_field', this)"
|
||||
style="position:absolute; right:12px; top:50%; transform:translateY(-50%); background:none; border:none; cursor:pointer; color:#94a3b8; padding:0; display:flex; align-items:center; justify-content:center;">
|
||||
<svg class="eye-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
</svg>
|
||||
<svg class="eye-off-icon" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="display:none;">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
|
||||
<line x1="1" y1="1" x2="23" y2="23"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ROLE --}}
|
||||
<div>
|
||||
<label style="display:block; font-size:13px; font-weight:700; color:#374151; margin-bottom:8px;">
|
||||
Hak Akses (Role) <span style="color:#ef4444;">*</span>
|
||||
</label>
|
||||
<select name="role"
|
||||
style="width:100%; padding:11px 14px; border:1.5px solid #e2e8f0; border-radius:10px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box; background:#fff;"
|
||||
onfocus="this.style.borderColor='#2563eb'" onblur="this.style.borderColor='#e2e8f0'">
|
||||
<option value="user" {{ old('role') == 'user' ? 'selected' : '' }}>Petugas (User)</option>
|
||||
<option value="admin" {{ old('role') == 'admin' ? 'selected' : '' }}>Admin (KASI)</option>
|
||||
<option value="superadmin" {{ old('role') == 'superadmin' ? 'selected' : '' }}>Super Admin</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="{{ route('admin.superadmin.user.index') }}"
|
||||
style="padding:10px 20px; border:1.5px solid #e2e8f0; border-radius:10px; font-size:13px; font-weight:700; color:#64748b; text-decoration:none; background:#f8fafc;"
|
||||
onmouseover="this.style.background='#e2e8f0'" onmouseout="this.style.background='#f8fafc'">
|
||||
Batal
|
||||
</a>
|
||||
<button type="submit"
|
||||
style="padding:10px 24px; background:#0D215C; color:#fff; border:none; border-radius:10px; font-size:13px; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:7px;"
|
||||
onmouseover="this.style.opacity='.85'" onmouseout="this.style.opacity='1'">
|
||||
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<line x1="19" y1="8" x2="19" y2="14"/>
|
||||
<line x1="22" y1="11" x2="16" y2="11"/>
|
||||
</svg>
|
||||
Tambah Pengguna
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- TIPS CARD --}}
|
||||
<div>
|
||||
<div style="background:#fff; border-radius:16px; border:1px solid #e2e8f0; padding:20px; margin-bottom:16px;">
|
||||
<div style="display:flex; align-items:center; gap:8px; margin-bottom:12px;">
|
||||
<div style="width:28px; height:28px; background:#f0fdf4; border-radius:8px; display:flex; align-items:center; justify-content:center;">
|
||||
<svg width="14" height="14" fill="none" stroke="#10b981" stroke-width="2" viewBox="0 0 24 24">
|
||||
<polyline points="20 6 9 17 4 12"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span style="font-size:14px; font-weight:700; color:#0f172a;">Panduan Pengisian</span>
|
||||
</div>
|
||||
<ul style="margin:0; padding-left:16px; font-size:12px; color:#64748b; line-height:1.9;">
|
||||
<li>Nama sesuai dengan dokumen resmi</li>
|
||||
<li>Username digunakan untuk login</li>
|
||||
|
||||
<li>Kata sandi minimal 6 karakter</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="background:#eff6ff; border-radius:16px; border:1px solid #bfdbfe; padding:18px 20px;">
|
||||
<div style="display:flex; align-items:center; gap:8px; margin-bottom:10px;">
|
||||
<svg width="16" height="16" fill="#2563eb" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
||||
<span style="font-size:13px; font-weight:700; color:#1d4ed8;">Panduan Role</span>
|
||||
</div>
|
||||
<ul style="margin:0; padding-left:16px; font-size:12px; color:#3b82f6; line-height:1.8;">
|
||||
<li><strong>Petugas</strong>: Input kegiatan harian</li>
|
||||
<li><strong>Admin</strong>: Monitor kegiatan & user</li>
|
||||
<li><strong>Super Admin</strong>: Akses penuh sistem</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
<script>
|
||||
function togglePassword(inputId, buttonElement) {
|
||||
const input = document.getElementById(inputId);
|
||||
const eyeIcon = buttonElement.querySelector('.eye-icon');
|
||||
const eyeOffIcon = buttonElement.querySelector('.eye-off-icon');
|
||||
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
eyeIcon.style.display = 'none';
|
||||
eyeOffIcon.style.display = 'block';
|
||||
buttonElement.style.color = '#2563eb';
|
||||
} else {
|
||||
input.type = 'password';
|
||||
eyeIcon.style.display = 'block';
|
||||
eyeOffIcon.style.display = 'none';
|
||||
buttonElement.style.color = '#94a3b8';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,346 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.page-container { padding: 28px 32px; background: #f1f5f9; min-height: 100vh; font-family: 'Figtree', 'Segoe UI', sans-serif; }
|
||||
.header-flex { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 28px; }
|
||||
.main-grid { display: grid; grid-template-columns: 1fr 300px; gap: 24px; align-items: flex-start; }
|
||||
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
|
||||
.form-actions { border-top: 1px solid #f1f5f9; padding-top: 24px; display: flex; justify-content: space-between; align-items: center; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-container { padding: 16px 12px !important; }
|
||||
.header-flex { flex-direction: column !important; gap: 16px !important; align-items: flex-start !important; }
|
||||
.main-grid { grid-template-columns: 1fr !important; }
|
||||
.form-grid { grid-template-columns: 1fr !important; gap: 15px !important; }
|
||||
.form-actions { flex-direction: column !important; gap: 16px !important; align-items: flex-start !important; }
|
||||
.form-actions a, .form-actions button { width: 100% !important; justify-content: center; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="page-container">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="header-flex">
|
||||
<div>
|
||||
<div style="display:flex; align-items:center; gap:8px; margin-bottom:8px;">
|
||||
<div style="width:24px; height:2px; background:#3b82f6;"></div>
|
||||
<p style="font-size:11px; font-weight:700; color:#3b82f6; letter-spacing:1px; margin:0; text-transform:uppercase;">
|
||||
Panel Kendali Sistem
|
||||
</p>
|
||||
</div>
|
||||
<h1 style="font-size:28px; font-weight:800; color:#0f172a; margin:0 0 4px;">
|
||||
Edit Pengguna
|
||||
</h1>
|
||||
<p style="margin:0; color:#64748b; font-size:13px;">
|
||||
Ubah informasi akun dan hak akses pengguna
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; align-items:center; gap:12px;">
|
||||
<a href="{{ route('admin.superadmin.user.index') }}"
|
||||
style="background:#fff; border:1px solid #e2e8f0; padding:8px 16px; border-radius:999px; font-size:12px; font-weight:600; color:#475569; text-decoration:none; display:flex; align-items:center; gap:6px;">
|
||||
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M19 12H5M12 5l-7 7 7 7"/>
|
||||
</svg>
|
||||
Kembali ke Daftar
|
||||
</a>
|
||||
<div style="background:#fef3c7; color:#b45309; border:1px solid #fde68a; padding:8px 16px; border-radius:999px; font-size:11px; font-weight:800; display:flex; align-items:center; gap:6px; letter-spacing:0.5px;">
|
||||
<svg width="12" height="12" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
||||
</svg>
|
||||
SUPER ADMIN
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(session('success'))
|
||||
<div style="margin-bottom:20px; padding:14px 18px; background:#f0fdf4; border:1px solid #bbf7d0; border-radius:12px; color:#15803d; font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px;">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
@if(session('error'))
|
||||
<div style="margin-bottom:20px; padding:14px 18px; background:#fff1f2; border:1px solid #fecdd3; border-radius:12px; color:#be123c; font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px;">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
@if ($errors->any())
|
||||
<div style="margin-bottom:20px; padding:14px 18px; background:#fff1f2; border:1px solid #fecdd3; border-radius:12px;">
|
||||
<p style="font-weight:700; color:#be123c; margin:0 0 8px; font-size:13px;">Terdapat kesalahan input:</p>
|
||||
<ul style="margin:0; padding-left:18px; color:#be123c; font-size:13px;">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="main-grid">
|
||||
|
||||
{{-- LEFT SIDEBAR --}}
|
||||
<div>
|
||||
{{-- Profile Card --}}
|
||||
<div style="background:#fff; border-radius:16px; border:1px solid #e2e8f0; overflow:hidden; margin-bottom:16px; box-shadow:0 4px 6px -1px rgba(0,0,0,0.05);">
|
||||
{{-- Gradient Top --}}
|
||||
<div style="background: linear-gradient(135deg, #2563eb 0%, #6366f1 100%); padding:32px 20px; text-align:center; position:relative;">
|
||||
|
||||
@php
|
||||
$initials = strtoupper(substr($user->name, 0, 2));
|
||||
@endphp
|
||||
<div style="width:72px; height:72px; background:rgba(255,255,255,0.2); border:2px solid rgba(255,255,255,0.4); border-radius:20px; color:#fff; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:24px; margin:0 auto 16px; box-shadow:0 4px 12px rgba(0,0,0,0.1); backdrop-filter:blur(4px);">
|
||||
{{ $initials }}
|
||||
</div>
|
||||
|
||||
<h2 style="margin:0 0 4px; color:#fff; font-size:18px; font-weight:700;">{{ $user->name }}</h2>
|
||||
<p style="margin:0 0 16px; color:#e0e7ff; font-size:12px;">{{ $user->email ?? $user->username }}</p>
|
||||
|
||||
<div style="display:inline-flex; align-items:center; gap:6px; background:rgba(255,255,255,0.2); padding:6px 14px; border-radius:999px; border:1px solid rgba(255,255,255,0.3); color:#fff; font-size:10px; font-weight:800; letter-spacing:0.5px;">
|
||||
<svg width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||||
{{ strtoupper($user->role) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Stats List --}}
|
||||
<div style="padding:16px;">
|
||||
<div style="display:flex; align-items:center; gap:12px; padding:12px; background:#f8fafc; border-radius:12px; border:1px solid #f1f5f9; margin-bottom:12px;">
|
||||
<div style="color:#64748b;"><svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg></div>
|
||||
<div>
|
||||
<div style="font-size:10px; font-weight:700; color:#94a3b8; text-transform:uppercase; letter-spacing:0.5px; margin-bottom:2px;">User ID</div>
|
||||
<div style="font-size:13px; font-weight:700; color:#0f172a;">#{{ $user->id }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; align-items:center; gap:12px; padding:12px; background:#f8fafc; border-radius:12px; border:1px solid #f1f5f9; margin-bottom:12px;">
|
||||
<div style="color:#10b981;"><svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg></div>
|
||||
<div>
|
||||
<div style="font-size:10px; font-weight:700; color:#94a3b8; text-transform:uppercase; letter-spacing:0.5px; margin-bottom:2px;">Total Aktivitas</div>
|
||||
<div style="font-size:13px; font-weight:700; color:#0f172a;">{{ $user->activities_count ?? 0 }} kegiatan</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; align-items:center; gap:12px; padding:12px; background:#f8fafc; border-radius:12px; border:1px solid #f1f5f9; margin-bottom:12px;">
|
||||
<div style="color:#8b5cf6;"><svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg></div>
|
||||
<div>
|
||||
<div style="font-size:10px; font-weight:700; color:#94a3b8; text-transform:uppercase; letter-spacing:0.5px; margin-bottom:2px;">Bergabung</div>
|
||||
<div style="font-size:13px; font-weight:700; color:#0f172a;">{{ \Carbon\Carbon::parse($user->created_at)->translatedFormat('d F Y') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex; align-items:center; gap:12px; padding:12px; background:#f8fafc; border-radius:12px; border:1px solid #f1f5f9;">
|
||||
<div style="color:#f59e0b;"><svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg></div>
|
||||
<div>
|
||||
<div style="font-size:10px; font-weight:700; color:#94a3b8; text-transform:uppercase; letter-spacing:0.5px; margin-bottom:2px;">Terakhir Diperbarui</div>
|
||||
<div style="font-size:13px; font-weight:700; color:#0f172a;">{{ \Carbon\Carbon::parse($user->updated_at ?? $user->created_at)->translatedFormat('d F Y') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Warning Box --}}
|
||||
<div style="margin:0 16px 16px; padding:14px; background:#fefce8; border:1px solid #fef08a; border-radius:12px; display:flex; gap:10px; align-items:flex-start;">
|
||||
<div style="color:#b45309; flex-shrink:0;">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
|
||||
<line x1="12" y1="9" x2="12" y2="13"/>
|
||||
<line x1="12" y1="17" x2="12.01" y2="17"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div style="font-size:11px; color:#b45309; line-height:1.5;">
|
||||
Perubahan data akan langsung berpengaruh pada akses sistem pengguna ini.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- FORM MAIN CONTENT --}}
|
||||
<div style="background:#fff; border-radius:16px; border:1px solid #e2e8f0; overflow:hidden; box-shadow:0 4px 6px -1px rgba(0,0,0,0.05);">
|
||||
<div style="padding:20px 28px; border-bottom:1px solid #f1f5f9; display:flex; align-items:center; gap:12px;">
|
||||
<div style="width:36px; height:36px; background:#eff6ff; border-radius:10px; display:flex; align-items:center; justify-content:center; color:#3b82f6;">
|
||||
<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="margin:0 0 4px; font-size:15px; font-weight:700; color:#0f172a;">Formulir Edit Pengguna</h3>
|
||||
<p style="margin:0; font-size:12px; color:#94a3b8;">Perbarui informasi akun pengguna di bawah ini</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="{{ route('admin.superadmin.user.update', $user->id) }}" method="POST" style="padding:28px;">
|
||||
@csrf
|
||||
|
||||
{{-- INFORMASI DASAR --}}
|
||||
<div style="margin-bottom:28px;">
|
||||
<div style="display:flex; align-items:center; gap:8px; margin-bottom:16px;">
|
||||
<div style="width:6px; height:6px; background:#3b82f6; border-radius:50%;"></div>
|
||||
<h4 style="margin:0; font-size:12px; font-weight:800; color:#3b82f6; letter-spacing:1px;">INFORMASI DASAR</h4>
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<div>
|
||||
<label style="display:block; font-size:12px; font-weight:600; color:#475569; margin-bottom:8px;">
|
||||
Nama Lengkap <span style="color:#ef4444;">*</span>
|
||||
</label>
|
||||
<input type="text" name="name" value="{{ old('name', $user->name) }}"
|
||||
style="width:100%; padding:10px 14px; border:1px solid #e2e8f0; border-radius:8px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box; background:#f8fafc;"
|
||||
onfocus="this.style.borderColor='#3b82f6'; this.style.background='#fff'"
|
||||
onblur="this.style.borderColor='#e2e8f0'; this.style.background='#f8fafc'" required>
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block; font-size:12px; font-weight:600; color:#475569; margin-bottom:8px;">
|
||||
Username <span style="color:#ef4444;">*</span>
|
||||
</label>
|
||||
<input type="text" name="username" value="{{ old('username', $user->username) }}"
|
||||
style="width:100%; padding:10px 14px; border:1px solid #e2e8f0; border-radius:8px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box; background:#f8fafc;"
|
||||
onfocus="this.style.borderColor='#3b82f6'; this.style.background='#fff'"
|
||||
onblur="this.style.borderColor='#e2e8f0'; this.style.background='#f8fafc'" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{{-- ROLE & HAK AKSES --}}
|
||||
<div style="margin-bottom:28px;">
|
||||
<div style="display:flex; align-items:center; gap:8px; margin-bottom:16px;">
|
||||
<div style="width:6px; height:6px; background:#3b82f6; border-radius:50%;"></div>
|
||||
<h4 style="margin:0; font-size:12px; font-weight:800; color:#3b82f6; letter-spacing:1px;">ROLE & HAK AKSES</h4>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style="display:block; font-size:12px; font-weight:600; color:#475569; margin-bottom:8px;">
|
||||
Role Pengguna <span style="color:#ef4444;">*</span>
|
||||
</label>
|
||||
<select name="role"
|
||||
style="width:100%; padding:10px 14px; border:1px solid #e2e8f0; border-radius:8px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box; background:#f8fafc; appearance:none;"
|
||||
onfocus="this.style.borderColor='#3b82f6'; this.style.background='#fff'"
|
||||
onblur="this.style.borderColor='#e2e8f0'; this.style.background='#f8fafc'" required>
|
||||
<option value="superadmin" {{ old('role', $user->role) == 'superadmin' ? 'selected' : '' }}>Super Admin</option>
|
||||
<option value="admin" {{ old('role', $user->role) == 'admin' ? 'selected' : '' }}>Administrator</option>
|
||||
<option value="user" {{ old('role', $user->role) == 'user' ? 'selected' : '' }}>User</option>
|
||||
</select>
|
||||
<p style="margin:6px 0 0; font-size:11px; color:#94a3b8; display:flex; align-items:center; gap:4px;">
|
||||
<svg width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
|
||||
Role menentukan level akses pengguna di dalam sistem
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- GANTI PASSWORD --}}
|
||||
<div style="margin-bottom:32px;">
|
||||
<div style="display:flex; align-items:center; gap:8px; margin-bottom:16px;">
|
||||
<div style="width:6px; height:6px; background:#3b82f6; border-radius:50%;"></div>
|
||||
<h4 style="margin:0; font-size:12px; font-weight:800; color:#3b82f6; letter-spacing:1px;">GANTI PASSWORD <span style="font-weight:500; color:#94a3b8; text-transform:none; letter-spacing:0;">(Kosongkan jika tidak ingin mengubah)</span></h4>
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<div>
|
||||
<div style="display:flex; align-items:center; gap:6px; margin-bottom:8px;">
|
||||
<label style="font-size:12px; font-weight:600; color:#475569;">
|
||||
Password Baru
|
||||
</label>
|
||||
<span style="background:#f1f5f9; color:#64748b; padding:2px 6px; border-radius:4px; font-size:10px;">Opsional</span>
|
||||
</div>
|
||||
<div style="position:relative;">
|
||||
<input type="password" name="password" id="edit_password"
|
||||
style="width:100%; padding:10px 40px 10px 14px; border:1px solid #e2e8f0; border-radius:8px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box; background:#f8fafc;"
|
||||
onfocus="this.style.borderColor='#3b82f6'; this.style.background='#fff'"
|
||||
onblur="this.style.borderColor='#e2e8f0'; this.style.background='#f8fafc'"
|
||||
placeholder="Min. 8 karakter">
|
||||
<button type="button" onclick="togglePassword('edit_password', this)"
|
||||
style="position:absolute; right:12px; top:50%; transform:translateY(-50%); background:none; border:none; cursor:pointer; color:#94a3b8; padding:0; display:flex; align-items:center; justify-content:center;">
|
||||
<svg class="eye-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
</svg>
|
||||
<svg class="eye-off-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="display:none;">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
|
||||
<line x1="1" y1="1" x2="23" y2="23"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="display:flex; align-items:center; gap:6px; margin-bottom:8px;">
|
||||
<label style="font-size:12px; font-weight:600; color:#475569;">
|
||||
Konfirmasi Password
|
||||
</label>
|
||||
<span style="background:#f1f5f9; color:#64748b; padding:2px 6px; border-radius:4px; font-size:10px;">Opsional</span>
|
||||
</div>
|
||||
<div style="position:relative;">
|
||||
<input type="password" name="password_confirmation" id="edit_password_confirmation"
|
||||
style="width:100%; padding:10px 40px 10px 14px; border:1px solid #e2e8f0; border-radius:8px; font-size:14px; color:#0f172a; outline:none; box-sizing:border-box; background:#f8fafc;"
|
||||
onfocus="this.style.borderColor='#3b82f6'; this.style.background='#fff'"
|
||||
onblur="this.style.borderColor='#e2e8f0'; this.style.background='#f8fafc'"
|
||||
placeholder="Ulangi password baru">
|
||||
<button type="button" onclick="togglePassword('edit_password_confirmation', this)"
|
||||
style="position:absolute; right:12px; top:50%; transform:translateY(-50%); background:none; border:none; cursor:pointer; color:#94a3b8; padding:0; display:flex; align-items:center; justify-content:center;">
|
||||
<svg class="eye-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
</svg>
|
||||
<svg class="eye-off-icon" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="display:none;">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
|
||||
<line x1="1" y1="1" x2="23" y2="23"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- FOOTER BUTTONS --}}
|
||||
<div class="form-actions">
|
||||
<div style="font-size:12px; color:#64748b; display:flex; align-items:center; gap:6px;">
|
||||
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
|
||||
Field bertanda <span style="color:#ef4444;">*</span> wajib diisi
|
||||
</div>
|
||||
<div style="display:flex; gap:12px;">
|
||||
<a href="{{ route('admin.superadmin.user.index') }}"
|
||||
style="padding:10px 24px; border:1px solid #e2e8f0; border-radius:8px; font-size:13px; font-weight:700; color:#475569; text-decoration:none; background:#fff; transition:all .2s;"
|
||||
onmouseover="this.style.background='#f8fafc'" onmouseout="this.style.background='#fff'">
|
||||
Batal
|
||||
</a>
|
||||
<button type="submit"
|
||||
style="padding:10px 24px; background:#2563eb; color:#fff; border:none; border-radius:8px; font-size:13px; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:8px; transition:opacity .2s;"
|
||||
onmouseover="this.style.opacity='.85'" onmouseout="this.style.opacity='1'">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
|
||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
|
||||
<polyline points="17 21 17 13 7 13 7 21"/>
|
||||
<polyline points="7 3 7 8 15 8"/>
|
||||
</svg>
|
||||
Simpan Perubahan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
<script>
|
||||
function togglePassword(inputId, buttonElement) {
|
||||
const input = document.getElementById(inputId);
|
||||
const eyeIcon = buttonElement.querySelector('.eye-icon');
|
||||
const eyeOffIcon = buttonElement.querySelector('.eye-off-icon');
|
||||
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
eyeIcon.style.display = 'none';
|
||||
eyeOffIcon.style.display = 'block';
|
||||
buttonElement.style.color = '#3b82f6';
|
||||
} else {
|
||||
input.type = 'password';
|
||||
eyeIcon.style.display = 'block';
|
||||
eyeOffIcon.style.display = 'none';
|
||||
buttonElement.style.color = '#94a3b8';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,328 @@
|
||||
@extends('admin.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="page-container" style="padding:28px 32px; background:#f1f5f9; min-height:100vh; font-family:'Figtree','Segoe UI',sans-serif;">
|
||||
<style>
|
||||
.hover-card {
|
||||
transition: all .3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hover-card:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow: 0 18px 35px rgba(15, 23, 42, .12);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.page-container { padding: 16px 12px !important; }
|
||||
.header-flex { flex-direction: column !important; gap: 16px !important; }
|
||||
.stats-grid { grid-template-columns: 1fr !important; }
|
||||
.toolbar-flex { flex-direction: column !important; align-items: stretch !important; gap: 16px !important; }
|
||||
.toolbar-right { flex-direction: column !important; align-items: stretch !important; }
|
||||
.search-input { width: 100% !important; }
|
||||
.btn-tambah { justify-content: center !important; }
|
||||
.header-badges { flex-wrap: wrap; }
|
||||
.table-wrap table { min-width: 800px !important; }
|
||||
}
|
||||
</style>
|
||||
{{-- HEADER --}}
|
||||
<div class="header-flex" style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:24px;">
|
||||
<div>
|
||||
<p style="font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:1.8px; margin:0 0 6px; text-transform:uppercase;">
|
||||
Panel Kendali Sistem
|
||||
</p>
|
||||
<h1 style="font-size:30px; font-weight:800; color:#0f172a; margin:0 0 4px;">
|
||||
Manajemen Pengguna
|
||||
</h1>
|
||||
<p style="margin:0; color:#94a3b8; font-size:13px;">
|
||||
Kelola seluruh akun dan hak akses pengguna sistem
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="header-badges" style="display:flex; align-items:center; gap:10px;">
|
||||
<div style="background:#fff; border:1px solid #e2e8f0; padding:9px 14px; border-radius:10px; font-size:13px; color:#64748b; display:flex; align-items:center; gap:6px;">
|
||||
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" />
|
||||
<line x1="16" y1="2" x2="16" y2="6" />
|
||||
<line x1="8" y1="2" x2="8" y2="6" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
</svg>
|
||||
{{ now()->translatedFormat('l, d F Y') }}
|
||||
</div>
|
||||
<div style="background:#eef2ff; color:#4338ca; padding:9px 14px; border-radius:10px; font-size:12px; font-weight:700; display:flex; align-items:center; gap:6px;">
|
||||
<div style="width:8px; height:8px; background:#4338ca; border-radius:50%;"></div>
|
||||
{{ strtoupper(session('user')['role'] ?? 'ADMINISTRATOR') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- STATISTIC CARDS --}}
|
||||
<div class="stats-grid" style="display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-bottom:24px;">
|
||||
|
||||
{{-- Card 1 --}}
|
||||
<a href="{{ route('admin.superadmin.user.index') }}"
|
||||
class="hover-card"
|
||||
style="text-decoration:none; display:block; background:#fff; border-radius:16px; padding:22px 24px; border:1px solid #e2e8f0; position:relative; overflow:hidden;">
|
||||
<div style="position:absolute; top:0; left:0; right:0; height:3px; background:#3b82f6;"></div>
|
||||
<div style="display:flex; justify-content:space-between; align-items:flex-start;">
|
||||
<div>
|
||||
<p style="font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:1.2px; margin:0 0 10px; text-transform:uppercase;">
|
||||
Total Pengguna
|
||||
</p>
|
||||
<h2 style="font-size:36px; font-weight:800; margin:0 0 4px; color:#0f172a;">
|
||||
{{ $stats['total'] }}
|
||||
</h2>
|
||||
<p style="font-size:12px; color:#94a3b8; margin:0;">Seluruh akun terdaftar</p>
|
||||
</div>
|
||||
<div style="width:44px; height:44px; background:#eff6ff; border-radius:12px; display:flex; align-items:center; justify-content:center;">
|
||||
<svg width="20" height="20" fill="none" stroke="#3b82f6" stroke-width="2" viewBox="0 0 24 24">
|
||||
<circle cx="12" cy="8" r="4" />
|
||||
<path d="M4 20c0-4 3.6-7 8-7s8 3 8 7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{-- Card 2 --}}
|
||||
<a href="{{ route('admin.superadmin.user.index') }}"
|
||||
class="hover-card"
|
||||
style="text-decoration:none; display:block; background:#fff; border-radius:16px; padding:22px 24px; border:1px solid #e2e8f0; position:relative; overflow:hidden;">
|
||||
<div style="position:absolute; top:0; left:0; right:0; height:3px; background:#10b981;"></div>
|
||||
<div style="display:flex; justify-content:space-between; align-items:flex-start;">
|
||||
<div>
|
||||
<p style="font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:1.2px; margin:0 0 10px; text-transform:uppercase;">
|
||||
Pengguna Aktif
|
||||
</p>
|
||||
<h2 style="font-size:36px; font-weight:800; margin:0 0 4px; color:#0f172a;">
|
||||
{{ $stats['active'] }}
|
||||
</h2>
|
||||
<p style="font-size:12px; color:#94a3b8; margin:0;">Memiliki aktivitas tercatat</p>
|
||||
</div>
|
||||
<div style="width:44px; height:44px; background:#f0fdf4; border-radius:12px; display:flex; align-items:center; justify-content:center;">
|
||||
<svg width="20" height="20" fill="none" stroke="#10b981" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
|
||||
<polyline points="22 4 12 14.01 9 11.01" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{-- Card 3 --}}
|
||||
<div class="hover-card" style="background:#fff; border-radius:16px; padding:22px 24px; border:1px solid #e2e8f0; position:relative; overflow:hidden;">
|
||||
<div style="position:absolute; top:0; left:0; right:0; height:3px; background:#8b5cf6;"></div>
|
||||
<div style="display:flex; justify-content:space-between; align-items:flex-start;">
|
||||
<div>
|
||||
<p style="font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:1.2px; margin:0 0 10px; text-transform:uppercase;">
|
||||
Total Aktivitas
|
||||
</p>
|
||||
<h2 style="font-size:36px; font-weight:800; margin:0 0 4px; color:#0f172a;">
|
||||
{{ $stats['activities'] }}
|
||||
</h2>
|
||||
<p style="font-size:12px; color:#94a3b8; margin:0;">Dari seluruh pengguna</p>
|
||||
</div>
|
||||
<div style="width:44px; height:44px; background:#f5f3ff; border-radius:12px; display:flex; align-items:center; justify-content:center;">
|
||||
<svg width="20" height="20" fill="none" stroke="#8b5cf6" stroke-width="2" viewBox="0 0 24 24">
|
||||
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- TABLE CARD --}}
|
||||
<div style="background:#fff; border-radius:16px; border:1px solid #e2e8f0; overflow:hidden;">
|
||||
|
||||
{{-- TABLE TOOLBAR --}}
|
||||
<div class="toolbar-flex" style="padding:18px 24px; border-bottom:1px solid #f1f5f9; display:flex; justify-content:space-between; align-items:center; gap:12px;">
|
||||
|
||||
<div style="display:flex; align-items:center; gap:10px;">
|
||||
<div style="width:32px; height:32px; background:#eff6ff; border-radius:8px; display:flex; align-items:center; justify-content:center;">
|
||||
<svg width="16" height="16" fill="none" stroke="#2563eb" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="margin:0; font-size:15px; font-weight:700; color:#0f172a;">Daftar Pengguna Sistem</h3>
|
||||
</div>
|
||||
<span style="background:#eff6ff; color:#2563eb; padding:4px 10px; border-radius:999px; font-size:12px; font-weight:700;">
|
||||
Total: {{ $stats['total'] }} Pengguna
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-right" style="display:flex; align-items:center; gap:10px;">
|
||||
{{-- SEARCH --}}
|
||||
<div style="position:relative; flex:1;">
|
||||
<svg style="position:absolute; left:10px; top:50%; transform:translateY(-50%); color:#94a3b8;" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
||||
</svg>
|
||||
<input type="text" placeholder="Cari nama atau username..." class="search-input"
|
||||
style="padding:9px 12px 9px 32px; border:1px solid #e2e8f0; border-radius:10px; font-size:13px; color:#475569; outline:none; width:220px; background:#f8fafc; box-sizing:border-box;">
|
||||
</div>
|
||||
|
||||
{{-- TAMBAH --}}
|
||||
<a href="{{ route('admin.superadmin.user.create') }}" class="btn-tambah"
|
||||
style="background:#2563eb; color:#fff; text-decoration:none; padding:9px 16px; border-radius:10px; font-size:13px; font-weight:700; display:flex; align-items:center; gap:6px; white-space:nowrap; box-sizing:border-box;">
|
||||
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
Tambah Pengguna
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- TABLE --}}
|
||||
<div class="table-wrap" style="overflow-x:auto;">
|
||||
<table style="width:100%; border-collapse:collapse; min-width:800px;">
|
||||
<thead>
|
||||
<tr style="background:#f8fafc;">
|
||||
<th style="padding:13px 16px; text-align:left; font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:.8px; width:40px;">#</th>
|
||||
<th style="padding:13px 16px; text-align:left; font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:.8px;">PENGGUNA</th>
|
||||
<th style="padding:13px 16px; text-align:left; font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:.8px;">USERNAME</th>
|
||||
<th style="padding:13px 16px; text-align:left; font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:.8px;">ROLE</th>
|
||||
<th style="padding:13px 16px; text-align:left; font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:.8px;">KEGIATAN</th>
|
||||
<th style="padding:13px 16px; text-align:left; font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:.8px;">TERDAFTAR</th>
|
||||
<th style="padding:13px 16px; text-align:center; font-size:11px; font-weight:700; color:#94a3b8; letter-spacing:.8px;">AKSI</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($users as $index => $user)
|
||||
<tr style="border-top:1px solid #f1f5f9; transition:background .15s;" onmouseover="this.style.background='#fafbff'" onmouseout="this.style.background='transparent'">
|
||||
|
||||
{{-- NO --}}
|
||||
<td style="padding:16px; color:#94a3b8; font-size:13px; font-weight:600;">
|
||||
{{ $loop->iteration }}
|
||||
</td>
|
||||
|
||||
{{-- USER --}}
|
||||
<td style="padding:16px;">
|
||||
<div style="display:flex; align-items:center; gap:11px;">
|
||||
@php
|
||||
$colors = ['#2563eb','#7c3aed','#059669','#dc2626','#d97706'];
|
||||
$color = $colors[$user->id % count($colors)];
|
||||
$initials = strtoupper(substr($user->name, 0, 2));
|
||||
@endphp
|
||||
<div style="width:38px; height:38px; border-radius:10px; background:{{ $color }}; color:#fff; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:13px; flex-shrink:0;">
|
||||
{{ $initials }}
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight:700; color:#0f172a; font-size:14px;">{{ $user->name }}</div>
|
||||
<div style="font-size:12px; color:#94a3b8;">ID #{{ $user->id }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{{-- USERNAME --}}
|
||||
<td style="padding:16px; color:#475569; font-size:13px;">{{ $user->username }}</td>
|
||||
|
||||
{{-- ROLE --}}
|
||||
<td style="padding:16px;">
|
||||
@if($user->role == 'superadmin')
|
||||
<span style="background:#fef9c3; color:#854d0e; padding:5px 12px; border-radius:999px; font-size:12px; font-weight:700;">Super Admin</span>
|
||||
@elseif($user->role == 'admin')
|
||||
<span style="background:#dbeafe; color:#1d4ed8; padding:5px 12px; border-radius:999px; font-size:12px; font-weight:700;">Administrator</span>
|
||||
@else
|
||||
<span style="background:#dcfce7; color:#15803d; padding:5px 12px; border-radius:999px; font-size:12px; font-weight:700;">Petugas</span>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
{{-- ACTIVITY --}}
|
||||
<td style="padding:16px;">
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="font-weight:700; color:#0f172a; font-size:14px;">{{ $user->activities_count }}</span>
|
||||
<div style="height:4px; width:40px; background:#f1f5f9; border-radius:4px; overflow:hidden;">
|
||||
@php $maxAct = max($stats['max_activities'] ?? 1, 1); @endphp
|
||||
<div style="height:100%; background:#3b82f6; border-radius:4px; width:{{ min(($user->activities_count / $maxAct) * 100, 100) }}%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{{-- CREATED --}}
|
||||
<td style="padding:16px; color:#64748b; font-size:13px;">
|
||||
{{ $user->created_at->translatedFormat('d M Y') }}
|
||||
</td>
|
||||
|
||||
{{-- ACTION --}}
|
||||
<td style="padding:16px; text-align:center;">
|
||||
<div style="display:flex; justify-content:center; gap:6px;">
|
||||
@php
|
||||
$editRoute = (session('user')['role'] ?? '') === 'superadmin' ? route('admin.superadmin.user.edit', $user->id) : route('admin.users.edit', $user->id);
|
||||
@endphp
|
||||
<a href="{{ $editRoute }}"
|
||||
style="background:#eff6ff; color:#2563eb; padding:7px 14px; border-radius:8px; text-decoration:none; font-size:12px; font-weight:700; display:inline-flex; align-items:center; gap:4px;">
|
||||
<svg width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
|
||||
</svg>
|
||||
Edit
|
||||
</a>
|
||||
|
||||
@if($user->role !== 'superadmin')
|
||||
<form action="{{ route('admin.superadmin.user.destroy', $user->id) }}" method="POST"
|
||||
onsubmit="return confirm('Yakin ingin menghapus pengguna ini?')" style="margin:0;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit"
|
||||
style="background:#fef2f2; color:#dc2626; padding:7px 14px; border:none; border-radius:8px; font-size:12px; font-weight:700; cursor:pointer; display:inline-flex; align-items:center; gap:4px;">
|
||||
<svg width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
|
||||
<path d="M10 11v6" />
|
||||
<path d="M14 11v6" />
|
||||
<path d="M9 6V4h6v2" />
|
||||
</svg>
|
||||
Hapus
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" style="padding:48px; text-align:center; color:#94a3b8; font-size:14px;">
|
||||
<div style="display:flex; flex-direction:column; align-items:center; gap:8px;">
|
||||
<svg width="36" height="36" fill="none" stroke="#cbd5e1" stroke-width="1.5" viewBox="0 0 24 24">
|
||||
<circle cx="12" cy="8" r="4" />
|
||||
<path d="M4 20c0-4 3.6-7 8-7s8 3 8 7" />
|
||||
</svg>
|
||||
Belum ada pengguna terdaftar.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- FOOTER / PAGINATION --}}
|
||||
<div style="padding:14px 24px; border-top:1px solid #f1f5f9; display:flex; justify-content:space-between; align-items:center;">
|
||||
<p style="font-size:13px; color:#94a3b8; margin:0;">
|
||||
Menampilkan 1–{{ $users->count() }} dari {{ $users->count() }} pengguna
|
||||
</p>
|
||||
|
||||
{{-- Pagination (if using paginate()) --}}
|
||||
@if(method_exists($users, 'links'))
|
||||
<div>{{ $users->links() }}</div>
|
||||
@else
|
||||
<div style="display:flex; gap:4px;">
|
||||
<button style="width:32px; height:32px; border:1px solid #e2e8f0; background:#fff; border-radius:8px; font-size:13px; color:#94a3b8; cursor:pointer;"><</button>
|
||||
<button style="width:32px; height:32px; border:1px solid #2563eb; background:#2563eb; border-radius:8px; font-size:13px; color:#fff; font-weight:700; cursor:pointer;">1</button>
|
||||
<button style="width:32px; height:32px; border:1px solid #e2e8f0; background:#fff; border-radius:8px; font-size:13px; color:#94a3b8; cursor:pointer;">></button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,263 @@
|
||||
@extends('user.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
// Logika status agar sinkron dengan database
|
||||
$status = $activity->status ?? 'on_progres';
|
||||
|
||||
$statusLabel = match($status) {
|
||||
'selesai' => 'DISETUJUI',
|
||||
'on_progres' => 'ON PROGRES',
|
||||
'review' => 'REVIEW',
|
||||
default => strtoupper($status),
|
||||
};
|
||||
|
||||
$statusColor = match($status) {
|
||||
'selesai' => 'bg-green-100 text-green-700',
|
||||
'on_progres' => 'bg-blue-100 text-blue-700',
|
||||
'review' => 'bg-yellow-100 text-yellow-700',
|
||||
default => 'bg-gray-100 text-gray-700',
|
||||
};
|
||||
|
||||
$fileName = $activity->lampiran ? basename($activity->lampiran) : null;
|
||||
$shortName = $fileName && strlen($fileName) > 30
|
||||
? substr($fileName, 0, 30) . '...'
|
||||
: $fileName;
|
||||
@endphp
|
||||
|
||||
<div class="max-w-6xl mx-auto mt-10 px-4 pb-16">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="mb-8">
|
||||
<div class="flex gap-3 items-center mb-3">
|
||||
<span class="{{ $statusColor }} text-xs px-4 py-1.5 rounded-full font-semibold">
|
||||
{{ $statusLabel }}
|
||||
</span>
|
||||
<span class="text-sm text-slate-400">
|
||||
Terakhir diperbarui:
|
||||
{{ $activity->updated_at ? \Carbon\Carbon::parse($activity->updated_at)->translatedFormat('d M Y') : '-' }}
|
||||
</span>
|
||||
</div>
|
||||
<h1 class="text-3xl font-bold text-[#0D215C]">{{ $activity->nama_kegiatan }}</h1>
|
||||
<p class="text-sm text-slate-400">Informasi lengkap aktivitas pegawai</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
|
||||
{{-- KIRI: KONTEN UTAMA --}}
|
||||
<div class="lg:col-span-2 bg-white p-7 rounded-2xl shadow-sm border border-slate-100">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 mb-8">
|
||||
<div>
|
||||
<p class="text-xs text-slate-400 uppercase tracking-wide mb-1">Nama Pegawai</p>
|
||||
<p class="font-semibold text-lg text-slate-800">{{ $activity->user->name ?? 'User Tidak Ditemukan' }}</p>
|
||||
<p class="text-sm text-slate-400">Username: {{ $activity->user->username ?? '-' }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-xs text-slate-400 uppercase tracking-wide mb-1">Lokasi</p>
|
||||
<p class="font-semibold text-slate-800 flex items-center gap-2">
|
||||
<i data-lucide="map-pin" class="w-4 h-4 text-slate-400"></i>
|
||||
{{ $activity->lokasi ?? '-' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-xs text-slate-400 uppercase tracking-wide mb-1">Tanggal Mulai</p>
|
||||
<p class="font-semibold text-slate-800 flex items-center gap-2">
|
||||
<i data-lucide="calendar" class="w-4 h-4 text-slate-400"></i>
|
||||
{{ $activity->tanggal ? \Carbon\Carbon::parse($activity->tanggal)->translatedFormat('d F Y') : '-' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-xs text-slate-400 uppercase tracking-wide mb-1">Tenggat Waktu</p>
|
||||
<p class="font-semibold text-slate-800 flex items-center gap-2">
|
||||
<i data-lucide="clock" class="w-4 h-4 text-slate-400"></i>
|
||||
@if($activity->tanggal_selesai)
|
||||
@php
|
||||
$isOverdue = \Carbon\Carbon::parse($activity->tanggal_selesai)->isPast() && $activity->status !== 'selesai' && $activity->status !== 'telah_ditinjau';
|
||||
@endphp
|
||||
<span class="{{ $isOverdue ? 'text-red-600 font-bold' : '' }}">
|
||||
{{ \Carbon\Carbon::parse($activity->tanggal_selesai)->translatedFormat('d F Y') }}
|
||||
@if($isOverdue) (Terlambat) @endif
|
||||
</span>
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="mb-6 border-slate-100">
|
||||
|
||||
<div class="mb-8">
|
||||
<p class="text-xs text-slate-400 uppercase tracking-wide mb-2">Deskripsi Detail</p>
|
||||
<div class="text-sm text-slate-600 leading-relaxed text-justify">
|
||||
{{ $activity->deskripsi ?? 'Tidak ada deskripsi tambahan.' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(!empty($activity->status_note))
|
||||
<div class="mb-8 p-4 bg-blue-50 border border-blue-100 rounded-xl">
|
||||
<p class="text-xs text-blue-500 uppercase tracking-wide mb-2 font-semibold">Catatan Status Terakhir</p>
|
||||
<div class="text-sm text-blue-900 leading-relaxed text-justify">
|
||||
{{ $activity->status_note }}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- 📝 TIMELINE PROGRESS MONITORING --}}
|
||||
<div class="mb-8">
|
||||
<p class="text-xs text-slate-400 uppercase tracking-wide mb-4">Log Monitoring Progress</p>
|
||||
|
||||
@if(isset($activity->progress) && count($activity->progress) > 0)
|
||||
<div class="relative border-l-2 border-indigo-100 ml-3 pl-5 space-y-6">
|
||||
@foreach($activity->progress as $prog)
|
||||
<div class="relative">
|
||||
<div class="absolute -left-[27px] bg-indigo-500 h-3 w-3 rounded-full border-2 border-white top-1"></div>
|
||||
<div class="text-xs text-slate-400 mb-1">
|
||||
{{ \Carbon\Carbon::parse($prog['created_at'])->format('d M Y, H:i') }} •
|
||||
<span class="font-semibold text-indigo-500">{{ $prog['user']['name'] ?? 'Pegawai' }}</span>
|
||||
</div>
|
||||
<div class="text-sm text-slate-700 bg-slate-50 border border-slate-100 p-3 rounded-lg shadow-sm">
|
||||
{{ $prog['note'] }}
|
||||
@if(!empty($prog['attachment']))
|
||||
<div class="mt-3 pt-3 border-t border-slate-200">
|
||||
<a href="http://127.0.0.1:8000/{{ $prog['attachment'] }}" target="_blank"
|
||||
class="inline-flex items-center gap-2 px-3 py-1.5 bg-indigo-50 text-indigo-600 text-xs font-semibold rounded-lg hover:bg-indigo-100 transition-colors border border-indigo-100">
|
||||
<i data-lucide="paperclip" class="w-3.5 h-3.5"></i> Lihat Lampiran Bukti
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="text-sm text-slate-500 bg-slate-50 p-4 rounded-xl border border-dashed border-slate-200 text-center">
|
||||
Belum ada log progress yang dicatat untuk kegiatan ini.
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@php
|
||||
$isPetugas = false;
|
||||
if(isset($activity->petugas)) {
|
||||
foreach($activity->petugas as $p) {
|
||||
if($p['id'] == session('user_id')) {
|
||||
$isPetugas = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
|
||||
@if($status !== 'selesai' && $isPetugas)
|
||||
<div class="mt-6 border-t border-slate-100 pt-5">
|
||||
<form action="{{ route('activity.progress', $activity->id) }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<label class="block text-sm font-semibold text-slate-700 mb-2">Tambahkan Log Progress</label>
|
||||
<div class="flex flex-col gap-3">
|
||||
<textarea name="note" required rows="3" placeholder="Contoh: Tim sudah sampai di lokasi survei..." class="w-full bg-slate-50 border border-slate-200 text-slate-800 rounded-xl px-4 py-3 text-sm focus:ring-2 focus:ring-indigo-500/20 focus:border-indigo-500 transition-all shadow-sm resize-y"></textarea>
|
||||
|
||||
<div class="flex justify-end gap-3 flex-wrap">
|
||||
<label class="cursor-pointer bg-slate-50 border border-slate-200 text-slate-500 hover:text-indigo-600 hover:border-indigo-300 px-5 py-2.5 rounded-xl text-sm font-medium transition-all shadow-sm flex items-center gap-2 whitespace-nowrap">
|
||||
<i data-lucide="image" class="w-4 h-4"></i> Bukti Foto
|
||||
<input type="file" name="attachment" accept="image/*,.pdf" class="hidden" onchange="this.parentElement.querySelector('span').innerText = this.files[0].name.substring(0,15) + '...'">
|
||||
<span class="text-xs text-slate-400"></span>
|
||||
</label>
|
||||
|
||||
<button type="submit" class="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-2.5 rounded-xl text-sm font-medium shadow-sm shadow-indigo-200 transition-all flex items-center justify-center gap-2 whitespace-nowrap">
|
||||
<i data-lucide="send" class="w-4 h-4"></i> Kirim Log
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- ACTION BUTTONS --}}
|
||||
<div class="flex gap-3 flex-wrap border-t pt-6">
|
||||
@if($status !== 'selesai' && $isPetugas)
|
||||
<a href="{{ route('activity.edit', $activity->id) }}"
|
||||
class="inline-flex items-center gap-2 bg-yellow-500 hover:bg-yellow-600 text-white px-5 py-2.5 rounded-lg text-sm font-medium transition">
|
||||
<i data-lucide="pencil" class="w-4 h-4"></i> Edit Laporan
|
||||
</a>
|
||||
|
||||
<form action="{{ route('activity.selesai', $activity->id) }}" method="POST">
|
||||
@csrf
|
||||
<button type="submit" onclick="return confirm('Tandai kegiatan ini sebagai selesai?')"
|
||||
class="inline-flex items-center gap-2 bg-green-500 hover:bg-green-600 text-white px-5 py-2.5 rounded-lg text-sm font-medium transition">
|
||||
<i data-lucide="check" class="w-4 h-4"></i> Selesaikan Kegiatan
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- KANAN: SIDEBAR DETAIL --}}
|
||||
<div class="space-y-4">
|
||||
{{-- Lampiran --}}
|
||||
<div class="bg-white p-6 rounded-2xl shadow-sm border border-slate-100">
|
||||
<h4 class="font-semibold mb-4 flex items-center gap-2 text-[#0D215C]">
|
||||
<i data-lucide="paperclip" class="w-4 h-4"></i> Lampiran
|
||||
</h4>
|
||||
|
||||
@if($activity->lampiran)
|
||||
<div class="flex items-center gap-3 bg-red-50 border border-red-100 rounded-xl px-4 py-3 mb-4">
|
||||
<div class="w-10 h-10 rounded-lg bg-red-100 flex items-center justify-center">
|
||||
<i data-lucide="image" class="w-5 h-5 text-red-500"></i>
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<p class="text-sm font-medium text-slate-700 truncate">{{ $shortName }}</p>
|
||||
<p class="text-xs text-slate-400">File Lampiran</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<a href="{{ rtrim(env('BACKEND_API_URL', 'http://127.0.0.1:8000'), '/api') . '/storage/' . $activity->lampiran }}" target="_blank"
|
||||
class="flex items-center justify-center gap-2 border border-slate-200 hover:bg-slate-50 text-slate-700 py-2 rounded-lg text-sm transition">
|
||||
<i data-lucide="eye" class="w-4 h-4"></i> Lihat
|
||||
</a>
|
||||
<a href="{{ rtrim(env('BACKEND_API_URL', 'http://127.0.0.1:8000'), '/api') . '/storage/' . $activity->lampiran }}" download
|
||||
class="flex items-center justify-center gap-2 border border-slate-200 hover:bg-slate-50 text-slate-700 py-2 rounded-lg text-sm transition">
|
||||
<i data-lucide="download" class="w-4 h-4"></i> Unduh
|
||||
</a>
|
||||
</div>
|
||||
@else
|
||||
<div class="text-center py-4 border-2 border-dashed border-slate-100 rounded-xl">
|
||||
<p class="text-sm text-slate-400 italic">Tidak ada lampiran</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Metadata --}}
|
||||
<div class="bg-white p-6 rounded-2xl shadow-sm border border-slate-100">
|
||||
<h4 class="font-semibold mb-4 text-[#0D215C]">Meta Data</h4>
|
||||
<div class="space-y-3 text-sm">
|
||||
<div class="flex justify-between text-slate-600">
|
||||
<span>ID Laporan</span>
|
||||
<span class="font-mono text-xs">#ACT-{{ str_pad($activity->id, 5, '0', STR_PAD_LEFT) }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-slate-600">
|
||||
<span>Metode</span>
|
||||
<span>{{ $activity->metode ?? 'Luring' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="{{ route('activity.list') }}" class="block text-center text-sm text-blue-600 hover:text-blue-800 transition py-2">
|
||||
← Kembali ke Daftar Laporan
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
@@ -0,0 +1,94 @@
|
||||
@extends('user.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="max-w-3xl mx-auto mt-10 px-4 pb-20">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="mb-8">
|
||||
<a href="{{ route('activity.detail', $activity->id) }}" class="text-sm text-blue-600 flex items-center gap-2 mb-4 no-underline hover:underline">
|
||||
<i data-lucide="arrow-left" class="w-4 h-4"></i> Kembali ke Detail
|
||||
</a>
|
||||
<h2 class="text-2xl font-bold text-[#0D215C]">
|
||||
Edit Laporan Kegiatan
|
||||
</h2>
|
||||
<p class="text-sm text-slate-400">Perbarui informasi laporan kegiatan Anda di bawah ini.</p>
|
||||
</div>
|
||||
|
||||
{{-- FORM CARD --}}
|
||||
<div class="bg-white p-8 rounded-2xl shadow-sm border border-slate-100">
|
||||
<form action="{{ route('activity.update', $activity->id) }}" method="POST" class="space-y-6">
|
||||
@csrf
|
||||
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Nama Kegiatan</label>
|
||||
<div class="relative">
|
||||
<input type="text" name="nama_kegiatan"
|
||||
value="{{ old('nama_kegiatan', $activity->nama_kegiatan) }}"
|
||||
placeholder="Masukkan nama kegiatan..."
|
||||
class="w-full p-3 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition" required>
|
||||
</div>
|
||||
@error('nama_kegiatan') <span class="text-red-500 text-xs mt-1">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Tanggal Pelaksanaan</label>
|
||||
<input type="date" name="tanggal"
|
||||
value="{{ old('tanggal', $activity->tanggal) }}"
|
||||
class="w-full p-3 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition" required>
|
||||
@error('tanggal') <span class="text-red-500 text-xs mt-1">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Lokasi</label>
|
||||
<input type="text" name="lokasi"
|
||||
value="{{ old('lokasi', $activity->lokasi) }}"
|
||||
placeholder="Contoh: Kantor Dinas..."
|
||||
class="w-full p-3 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition" required>
|
||||
@error('lokasi') <span class="text-red-500 text-xs mt-1">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Deskripsi Kegiatan</label>
|
||||
<textarea name="deskripsi" rows="5"
|
||||
placeholder="Jelaskan detail kegiatan yang dilakukan..."
|
||||
class="w-full p-3 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition">{{ old('deskripsi', $activity->deskripsi) }}</textarea>
|
||||
@error('deskripsi') <span class="text-red-500 text-xs mt-1">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Catatan Status Laporan (Node Petugas)</label>
|
||||
<textarea name="status_note" rows="3"
|
||||
placeholder="Contoh: Tugas ini sedang berjalan di desa darit..."
|
||||
class="w-full p-3 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition">{{ old('status_note', $activity->status_note ?? '') }}</textarea>
|
||||
@error('status_note') <span class="text-red-500 text-xs mt-1">{{ $message }}</span> @enderror
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-4 pt-4 border-t border-slate-100">
|
||||
<button type="submit"
|
||||
class="bg-[#0D215C] hover:bg-[#0a1a47] text-white px-8 py-3 rounded-xl font-bold transition shadow-lg shadow-blue-900/10 flex items-center gap-2">
|
||||
<i data-lucide="save" class="w-4 h-4"></i> Simpan Perubahan
|
||||
</button>
|
||||
|
||||
<a href="{{ route('activity.detail', $activity->id) }}"
|
||||
class="px-8 py-3 border border-slate-200 text-slate-600 rounded-xl font-semibold hover:bg-slate-50 transition">
|
||||
Batal
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,113 @@
|
||||
@extends('user.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
{{-- PAGE TITLE --}}
|
||||
<div style="margin-bottom:28px; display: flex; justify-content: space-between; align-items: flex-end; padding: 0 4px; flex-wrap: wrap; gap: 16px;">
|
||||
<div>
|
||||
<div style="font-size:26px; font-weight:700; color:#0D215C; font-family:'Outfit', sans-serif;">
|
||||
Riwayat Aktivitas
|
||||
</div>
|
||||
<div style="font-size:14px; color:#6b7280; margin-top:6px; font-family:'Outfit', sans-serif;">
|
||||
Daftar seluruh laporan kegiatan yang telah Anda kirimkan.
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ route('input.activity') }}"
|
||||
style="text-decoration:none; background:#1d4ed8; color:white; padding:10px 24px; border-radius:10px; font-size:13px; font-weight:600; transition:.2s; display: flex; align-items: center; gap: 8px;">
|
||||
<i data-lucide="plus" style="width: 16px; height: 16px;"></i>
|
||||
Input Baru
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- LIST CONTAINER --}}
|
||||
<div style="display: flex; flex-direction: column; gap: 16px;">
|
||||
|
||||
@forelse($activities as $item)
|
||||
<div class="card" style="padding: 20px; background: white; border-radius: 16px; border: 1px solid #f1f5f9; box-shadow: 0 1px 3px rgba(0,0,0,0.05); transition: .2s;"
|
||||
onmouseover="this.style.borderColor='#1d4ed8'; this.style.transform='translateY(-2px)'"
|
||||
onmouseout="this.style.borderColor='#f1f5f9'; this.style.transform='translateY(0)'">
|
||||
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px;">
|
||||
|
||||
<div style="display: flex; gap: 16px; align-items: center;">
|
||||
{{-- Icon Box --}}
|
||||
<div style="width: 52px; height: 52px; background: #eff6ff; border-radius: 14px; display: flex; align-items: center; justify-content: center; color: #1d4ed8; flex-shrink: 0;">
|
||||
<i data-lucide="clipboard-list" style="width: 26px; height: 26px;"></i>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div style="font-size: 17px; font-weight: 700; color: #1e293b; margin-bottom: 6px;">
|
||||
{{ $item->nama_kegiatan }}
|
||||
</div>
|
||||
<div style="display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
|
||||
<span style="font-size: 13px; color: #64748b; display: flex; align-items: center; gap: 6px;">
|
||||
<i data-lucide="user" style="width: 14px; height: 14px;"></i>
|
||||
<strong style="color: #475569;">{{ $item->user->name ?? 'Pegawai' }}</strong>
|
||||
</span>
|
||||
<span style="font-size: 13px; color: #64748b; display: flex; align-items: center; gap: 6px;">
|
||||
<i data-lucide="calendar" style="width: 14px; height: 14px;"></i>
|
||||
{{ $item->tanggal ? \Carbon\Carbon::parse($item->tanggal)->translatedFormat('d M Y') : '-' }}
|
||||
@if(!empty($item->tanggal_selesai))
|
||||
- {{ \Carbon\Carbon::parse($item->tanggal_selesai)->translatedFormat('d M Y') }}
|
||||
@endif
|
||||
</span>
|
||||
<span style="font-size: 13px; color: #64748b; display: flex; align-items: center; gap: 6px;">
|
||||
<i data-lucide="map-pin" style="width: 14px; height: 14px;"></i>
|
||||
{{ $item->lokasi ?? '-' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 20px;">
|
||||
{{-- Badge Status --}}
|
||||
@php
|
||||
$status = $item->status ?? 'on_progres';
|
||||
$isSelesai = $status === 'selesai';
|
||||
$isOverdue = !empty($item->tanggal_selesai) && \Carbon\Carbon::parse($item->tanggal_selesai)->isPast() && !$isSelesai && $status !== 'telah_ditinjau';
|
||||
@endphp
|
||||
<span style="padding: 6px 14px; border-radius: 99px; font-size: 11px; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase;
|
||||
{{ $isSelesai ? 'background:#dcfce7; color:#15803d;' : ($isOverdue ? 'background:#fef2f2; color:#dc2626; border:1px solid #fecaca;' : 'background:#eff6ff; color:#1d4ed8;') }}">
|
||||
{{ $isSelesai ? 'Selesai' : ($isOverdue ? 'Terlambat' : 'On Progres') }}
|
||||
</span>
|
||||
|
||||
{{-- Action Button --}}
|
||||
<a href="{{ route('activity.detail', $item->id) }}"
|
||||
style="text-decoration: none; color: #1d4ed8; font-weight: 600; font-size: 14px; display: flex; align-items: center; gap: 4px; padding: 8px 12px; border-radius: 8px; transition: .2s;"
|
||||
onmouseover="this.style.background='#eff6ff'"
|
||||
onmouseout="this.style.background='transparent'">
|
||||
Detail
|
||||
<i data-lucide="chevron-right" style="width: 18px; height: 18px;"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
{{-- EMPTY STATE --}}
|
||||
<div style="text-align: center; padding: 80px 20px; background: white; border-radius: 20px; border: 2px dashed #e2e8f0;">
|
||||
<div style="background: #f8fafc; width: 72px; height: 72px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px;">
|
||||
<i data-lucide="inbox" style="width: 36px; height: 36px; color: #cbd5e1;"></i>
|
||||
</div>
|
||||
<div style="font-size: 18px; font-weight: 700; color: #475569;">Belum Ada Aktivitas</div>
|
||||
<div style="font-size: 14px; color: #94a3b8; margin-top: 6px; max-width: 300px; margin-left: auto; margin-right: auto;">
|
||||
Laporan kegiatan yang Anda kirimkan nantinya akan muncul di daftar ini.
|
||||
</div>
|
||||
<a href="{{ route('input.activity') }}" style="display: inline-block; margin-top: 24px; color: #1d4ed8; font-weight: 600; font-size: 14px; text-decoration: none;">
|
||||
Mulai buat laporan pertama →
|
||||
</a>
|
||||
</div>
|
||||
@endforelse
|
||||
|
||||
</div>
|
||||
|
||||
{{-- Script untuk memastikan icon Lucide muncul --}}
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,897 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard User</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary: #1d4ed8;
|
||||
--primary-soft: #e0e7ff;
|
||||
--bg: #f4f6fb;
|
||||
--card: #ffffff;
|
||||
--border: #e5e7eb;
|
||||
--text: #111827;
|
||||
--muted: #6b7280;
|
||||
--danger: #dc2626;
|
||||
--success: #16a34a;
|
||||
--warning: #f59e0b;
|
||||
--info: #2563eb;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--bg);
|
||||
display: flex
|
||||
}
|
||||
|
||||
/* ─── SIDEBAR ─── */
|
||||
.sidebar {
|
||||
width: 280px;
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
padding: 24px 18px;
|
||||
border-right: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
margin-bottom: 18px
|
||||
}
|
||||
|
||||
.logo img {
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
object-fit: contain
|
||||
}
|
||||
|
||||
.logo-text .top,
|
||||
.logo-text .mid {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
color: #111827
|
||||
}
|
||||
|
||||
.logo-text .bot {
|
||||
font-size: 11px;
|
||||
color: var(--muted);
|
||||
margin-top: 2px
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: var(--border);
|
||||
margin: 14px 0
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px
|
||||
}
|
||||
|
||||
.menu a {
|
||||
padding: 11px 13px;
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
color: #374151;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 14px;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
background: #f3f4f6
|
||||
}
|
||||
|
||||
.menu a.active {
|
||||
background: var(--primary-soft);
|
||||
color: var(--primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.menu a svg {
|
||||
flex-shrink: 0;
|
||||
opacity: .7
|
||||
}
|
||||
|
||||
.menu a.active svg {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
padding: 11px 13px;
|
||||
color: #374151;
|
||||
text-decoration: none;
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.menu-item:hover {
|
||||
background: #f3f4f6
|
||||
}
|
||||
|
||||
.menu-item svg {
|
||||
opacity: .7
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
width: 100%;
|
||||
padding: 11px 13px;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--danger);
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
background: #fef2f2
|
||||
}
|
||||
|
||||
/* ─── MAIN ─── */
|
||||
.main {
|
||||
flex: 1;
|
||||
padding: 28px 32px;
|
||||
overflow-y: auto;
|
||||
height: 100vh
|
||||
}
|
||||
|
||||
/* ─── HEADER ─── */
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.search-wrap {
|
||||
position: relative;
|
||||
width: 340px
|
||||
}
|
||||
|
||||
.search-wrap svg {
|
||||
position: absolute;
|
||||
left: 13px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
pointer-events: none;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.search {
|
||||
width: 100%;
|
||||
padding: 10px 14px 10px 40px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
transition: .2s;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.search:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(29, 78, 216, .08);
|
||||
}
|
||||
|
||||
/* ─── USER ─── */
|
||||
.user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: #1e3a8a;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ─── NOTIF ─── */
|
||||
.notif {
|
||||
position: relative;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.notif-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.notif-btn:hover {
|
||||
background: #f3f4f6
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: -5px;
|
||||
background: #ef4444;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
border-radius: 999px;
|
||||
padding: 2px 6px;
|
||||
font-weight: 600;
|
||||
min-width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50px;
|
||||
width: 320px;
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, .1);
|
||||
display: none;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.dropdown.show {
|
||||
display: block
|
||||
}
|
||||
|
||||
.dropdown-header {
|
||||
padding: 13px 16px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dropdown-header a {
|
||||
font-size: 12px;
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: 13px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.dropdown-item:last-child {
|
||||
border-bottom: none
|
||||
}
|
||||
|
||||
.dropdown-item.unread {
|
||||
background: #eef2ff
|
||||
}
|
||||
|
||||
.dropdown-empty {
|
||||
padding: 24px;
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
font-size: 13px
|
||||
}
|
||||
|
||||
/* ─── PAGE TITLE ─── */
|
||||
.page-title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 4px;
|
||||
color: var(--text)
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
color: var(--muted);
|
||||
font-size: 14px;
|
||||
margin-bottom: 22px
|
||||
}
|
||||
|
||||
/* ─── CARDS ─── */
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 24px
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #fff;
|
||||
padding: 20px 22px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--border);
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, .06)
|
||||
}
|
||||
|
||||
.card h4 {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: .05em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 32px;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.card.total h4,
|
||||
.card.total h2 {
|
||||
color: var(--info)
|
||||
}
|
||||
|
||||
.card.proses h4,
|
||||
.card.proses h2 {
|
||||
color: var(--warning)
|
||||
}
|
||||
|
||||
.card.selesai h4,
|
||||
.card.selesai h2 {
|
||||
color: var(--success)
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.card.total .card-icon {
|
||||
background: #dbeafe
|
||||
}
|
||||
|
||||
.card.proses .card-icon {
|
||||
background: #fef3c7
|
||||
}
|
||||
|
||||
.card.selesai .card-icon {
|
||||
background: #dcfce7
|
||||
}
|
||||
|
||||
/* ─── LIST ─── */
|
||||
.list {
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
border: 1px solid var(--border);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-header {
|
||||
padding: 16px 20px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.list-header a {
|
||||
font-size: 13px;
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.list-header a:hover {
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.item:last-child {
|
||||
border-bottom: none
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background: #f9fafb
|
||||
}
|
||||
|
||||
.item-left strong {
|
||||
display: block;
|
||||
margin-bottom: 3px;
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.item-left small {
|
||||
color: var(--muted);
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.badge-status {
|
||||
padding: 5px 12px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.badge-success {
|
||||
background: #dcfce7;
|
||||
color: var(--success)
|
||||
}
|
||||
|
||||
.badge-warning {
|
||||
background: #fef3c7;
|
||||
color: #b45309
|
||||
}
|
||||
|
||||
.badge-info {
|
||||
background: #dbeafe;
|
||||
color: #1d4ed8
|
||||
}
|
||||
|
||||
.badge-danger {
|
||||
background: #fee2e2;
|
||||
color: #dc2626
|
||||
}
|
||||
|
||||
/* ─── EMPTY STATE ─── */
|
||||
.empty-state {
|
||||
padding: 48px 20px;
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.empty-state svg {
|
||||
margin: 0 auto 12px;
|
||||
display: block;
|
||||
opacity: .35
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
/* ─── NO RESULT ─── */
|
||||
.no-result {
|
||||
display: none;
|
||||
padding: 32px 20px;
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* ─── RESPONSIVE ─── */
|
||||
@media (max-width: 1024px) {
|
||||
.cards { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body { flex-direction: column; }
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
position: relative;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 16px;
|
||||
flex-direction: column;
|
||||
}
|
||||
.logo {
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.divider { display: none; }
|
||||
.menu {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
overflow-x: visible;
|
||||
gap: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.menu a { white-space: nowrap; justify-content: center; flex: 1 1 calc(50% - 8px); text-align: center; font-size: 13px; padding: 10px; }
|
||||
.bottom {
|
||||
flex-direction: row;
|
||||
margin-top: 8px;
|
||||
gap: 8px;
|
||||
border-top: 1px solid var(--border);
|
||||
padding-top: 12px;
|
||||
}
|
||||
.bottom a, .bottom button { white-space: nowrap; justify-content: center; flex: 1 1 calc(50% - 8px); font-size: 13px; padding: 10px; }
|
||||
|
||||
.main { padding: 20px 16px; height: auto; }
|
||||
.header { flex-direction: column-reverse; align-items: flex-start; gap: 20px; margin-bottom: 20px; }
|
||||
.search-wrap { width: 100%; }
|
||||
.user { width: 100%; justify-content: space-between; }
|
||||
.dropdown { width: 300px; left: -10px; right: auto; top: 55px; max-width: calc(100vw - 32px); }
|
||||
|
||||
.cards { grid-template-columns: 1fr; gap: 12px; }
|
||||
.item { flex-direction: column; align-items: flex-start; gap: 12px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- ═══ SIDEBAR ═══ -->
|
||||
<div class="sidebar">
|
||||
|
||||
<div class="logo">
|
||||
<img src="{{ asset('Kalimantan-Barat-Logo-Vector.png') }}" alt="Logo">
|
||||
<div class="logo-text">
|
||||
<div class="top">DINAS TENAGA KERJA</div>
|
||||
<div class="mid">DAN TRANSMIGRASI</div>
|
||||
<div class="bot">PROVINSI KALIMANTAN BARAT</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="menu">
|
||||
|
||||
<a href="{{ route('user.dashboard') }}"
|
||||
class="{{ request()->routeIs('user.dashboard') ? 'active' : '' }}">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2">
|
||||
<rect x="3" y="3" width="7" height="7" rx="1" />
|
||||
<rect x="13" y="3" width="8" height="7" rx="1" />
|
||||
<rect x="13" y="13" width="8" height="8" rx="1" />
|
||||
<rect x="3" y="13" width="7" height="8" rx="1" />
|
||||
</svg>
|
||||
Dashboard
|
||||
</a>
|
||||
|
||||
<a href="{{ route('input.activity') }}"
|
||||
class="{{ request()->routeIs('input.activity') ? 'active' : '' }}">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2">
|
||||
<path d="M11 5H6a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2v-5" />
|
||||
<path d="M17.5 3.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 8.5-8.5z" />
|
||||
</svg>
|
||||
Input Aktivitas
|
||||
</a>
|
||||
|
||||
<a href="{{ route('activity.list') }}"
|
||||
class="{{ request()->routeIs('activity.list') ? 'active' : '' }}">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2">
|
||||
<path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2" />
|
||||
<rect x="9" y="3" width="6" height="4" rx="1" />
|
||||
<path d="M9 12h6M9 16h4" />
|
||||
</svg>
|
||||
Daftar Aktivitas
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="bottom">
|
||||
<a href="{{ route('settings') }}" class="menu-item">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
|
||||
</svg>
|
||||
Pengaturan
|
||||
</a>
|
||||
|
||||
<form method="POST" action="{{ route('logout') }}">
|
||||
@csrf
|
||||
<button class="logout-btn" type="submit">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
|
||||
<polyline points="16 17 21 12 16 7" />
|
||||
<line x1="21" y1="12" x2="9" y2="12" />
|
||||
</svg>
|
||||
Logout
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ═══ MAIN ═══ -->
|
||||
<div class="main">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header">
|
||||
|
||||
<div class="search-wrap">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2">
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<path d="m21 21-4.35-4.35" />
|
||||
</svg>
|
||||
<input type="text" class="search" placeholder="Cari aktivitas..."
|
||||
oninput="filterAktivitas(this.value)">
|
||||
</div>
|
||||
|
||||
<div class="user">
|
||||
|
||||
<!-- NOTIF -->
|
||||
<div class="notif">
|
||||
<div class="notif-btn" onclick="toggleNotif()">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" />
|
||||
<path d="M13.73 21a2 2 0 0 1-3.46 0" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@if($unreadCount > 0)
|
||||
<div class="badge">{{ $unreadCount }}</div>
|
||||
@endif
|
||||
|
||||
<div class="dropdown" id="notifDropdown">
|
||||
<div class="dropdown-header">
|
||||
Notifikasi
|
||||
@if(count($notifications) > 0)
|
||||
<a href="#" onclick="markAllAsRead(event)">Tandai semua dibaca</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div id="notifListContainer">
|
||||
@forelse($notifications as $n)
|
||||
<div class="dropdown-item {{ !$n['read_at'] ? 'unread' : '' }}">
|
||||
{{ $n['data']['message'] ?? 'Ada notifikasi baru' }}
|
||||
<br><small style="color:var(--muted); font-size:11px;">{{ \Carbon\Carbon::parse($n['created_at'])->diffForHumans() }}</small>
|
||||
</div>
|
||||
@empty
|
||||
<div class="dropdown-empty">Tidak ada notifikasi</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- USER INFO -->
|
||||
<div>
|
||||
<strong style="font-size:14px">
|
||||
{{ session('user')['name'] ?? 'User' }}
|
||||
</strong><br>
|
||||
|
||||
<small style="color:var(--muted);font-size:12px">Pegawai</small>
|
||||
</div>
|
||||
|
||||
<div class="avatar">
|
||||
{{ strtoupper(substr(session('user')['name'] ?? 'U', 0, 1)) }}
|
||||
</div>
|
||||
|
||||
</div>{{-- end .user --}}
|
||||
|
||||
</div>{{-- end .header --}}
|
||||
|
||||
<!-- PAGE TITLE -->
|
||||
<div class="page-title">Dashboard Monitoring</div>
|
||||
<div class="page-subtitle">Pantau aktivitas kamu</div>
|
||||
|
||||
<!-- CARDS -->
|
||||
<div class="cards">
|
||||
<div class="card total">
|
||||
<div class="card-icon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="#2563eb" stroke-width="2">
|
||||
<rect x="3" y="3" width="7" height="7" rx="1" />
|
||||
<rect x="13" y="3" width="8" height="7" rx="1" />
|
||||
<rect x="13" y="13" width="8" height="8" rx="1" />
|
||||
<rect x="3" y="13" width="7" height="8" rx="1" />
|
||||
</svg>
|
||||
</div>
|
||||
<h4>TOTAL</h4>
|
||||
<h2>{{ $activities->count() }}</h2>
|
||||
</div>
|
||||
<div class="card proses">
|
||||
<div class="card-icon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="#f59e0b" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
</div>
|
||||
<h4>ON PROGRESS</h4>
|
||||
<h2>{{ $onProgres }}</h2>
|
||||
</div>
|
||||
<div class="card selesai">
|
||||
<div class="card-icon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="#16a34a" stroke-width="2">
|
||||
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
|
||||
<polyline points="22 4 12 14.01 9 11.01" />
|
||||
</svg>
|
||||
</div>
|
||||
<h4>SELESAI</h4>
|
||||
<h2>{{ $selesai }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RECENT ACTIVITIES -->
|
||||
<div class="list">
|
||||
<div class="list-header">
|
||||
<span>Recent Activities</span>
|
||||
<a href="{{ route('activity.list') }}">Lihat Semua →</a>
|
||||
</div>
|
||||
|
||||
<div id="activity-list">
|
||||
@forelse($activities->take(5) as $item)
|
||||
<div class="item" data-name="{{ strtolower($item->nama_kegiatan) }}">
|
||||
<div class="item-left">
|
||||
<strong>{{ $item->nama_kegiatan }}</strong>
|
||||
<small>
|
||||
{{ $item->user->name ?? 'Pegawai' }}
|
||||
·
|
||||
{{ \Carbon\Carbon::parse($item->tanggal ?? $item->created_at)->translatedFormat('d M Y') }}
|
||||
@if(!empty($item->tanggal_selesai))
|
||||
- {{ \Carbon\Carbon::parse($item->tanggal_selesai)->translatedFormat('d M Y') }}
|
||||
@endif
|
||||
|
||||
@if(!empty($item->lokasi))
|
||||
· {{ $item->lokasi }}
|
||||
@endif
|
||||
</small>
|
||||
</div>
|
||||
<div>
|
||||
@php
|
||||
$isOverdue = !empty($item->tanggal_selesai) && \Carbon\Carbon::parse($item->tanggal_selesai)->isPast() && $item->status !== 'selesai' && $item->status !== 'telah_ditinjau';
|
||||
@endphp
|
||||
@if($item->status == 'selesai')
|
||||
<span class="badge-status badge-success">Selesai</span>
|
||||
@elseif(!empty($item->reviewed_at) || $item->status == 'ditinjau' || $item->status == 'telah_ditinjau')
|
||||
<span class="badge-status badge-info">Ditinjau</span>
|
||||
@elseif($item->status == 'ditolak')
|
||||
<span class="badge-status badge-danger">Ditolak</span>
|
||||
@elseif($isOverdue)
|
||||
<span class="badge-status badge-danger" style="background:#fef2f2; color:#dc2626; border-color:#fecaca;">Terlambat</span>
|
||||
@else
|
||||
<span class="badge-status badge-warning">On Progress</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="empty-state">
|
||||
<svg width="44" height="44" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2" />
|
||||
<rect x="9" y="3" width="6" height="4" rx="1" />
|
||||
<path d="M9 12h6M9 16h4" />
|
||||
</svg>
|
||||
<p>Belum ada aktivitas yang diinput.</p>
|
||||
<a href="{{ route('input.activity') }}"
|
||||
style="display:inline-block;margin-top:12px;padding:8px 18px;
|
||||
background:var(--primary);color:#fff;border-radius:8px;
|
||||
text-decoration:none;font-size:13px;font-weight:500">
|
||||
+ Input Aktivitas
|
||||
</a>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<!-- No result saat search -->
|
||||
<div class="no-result" id="no-result">
|
||||
Tidak ada aktivitas yang cocok dengan pencarian.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>{{-- end .list --}}
|
||||
|
||||
</div>{{-- end .main --}}
|
||||
|
||||
<script>
|
||||
// ─── TOGGLE NOTIF ───
|
||||
function toggleNotif() {
|
||||
document.getElementById("notifDropdown").classList.toggle("show");
|
||||
}
|
||||
document.addEventListener('click', function(e) {
|
||||
const notif = document.querySelector('.notif');
|
||||
if (notif && !notif.contains(e.target)) {
|
||||
document.getElementById('notifDropdown').classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
async function markAllAsRead(e) {
|
||||
e.preventDefault();
|
||||
try {
|
||||
await fetch('/user/notifications-api/read', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
// Hapus badge dan ganti class unread
|
||||
const badge = document.querySelector('.badge');
|
||||
if (badge) badge.style.display = 'none';
|
||||
document.querySelectorAll('.dropdown-item.unread').forEach(el => {
|
||||
el.classList.remove('unread');
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── FILTER SEARCH ───
|
||||
function filterAktivitas(keyword) {
|
||||
const items = document.querySelectorAll('#activity-list .item');
|
||||
const noResult = document.getElementById('no-result');
|
||||
keyword = keyword.toLowerCase().trim();
|
||||
let visibleCount = 0;
|
||||
|
||||
items.forEach(item => {
|
||||
const name = item.getAttribute('data-name') || '';
|
||||
if (name.includes(keyword)) {
|
||||
item.style.display = 'flex';
|
||||
visibleCount++;
|
||||
} else {
|
||||
item.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
if (visibleCount === 0 && items.length > 0) {
|
||||
noResult.style.display = 'block';
|
||||
} else {
|
||||
noResult.style.display = 'none';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,123 @@
|
||||
@extends('user.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
{{-- PAGE TITLE --}}
|
||||
<div style="margin-bottom:28px;">
|
||||
<div style="font-size:26px; font-weight:700; color:#111827; font-family:'Outfit', sans-serif;">
|
||||
Input Laporan Kegiatan
|
||||
</div>
|
||||
<div style="font-size:14px; color:#6b7280; margin-top:6px; font-family:'Outfit', sans-serif;">
|
||||
Pastikan data yang dimasukkan sudah sesuai dengan dokumentasi lapangan.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($errors->any())
|
||||
<div style="background-color: #fee2e2; border-left: 4px solid #ef4444; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
|
||||
<div style="color: #b91c1c; font-weight: 600; margin-bottom: 8px;">Terdapat kesalahan pada input Anda:</div>
|
||||
<ul style="color: #b91c1c; font-size: 14px; margin: 0; padding-left: 20px;">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('activities.store') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
{{-- DATA PEGAWAI --}}
|
||||
<div class="card">
|
||||
|
||||
<div style="font-size:13px; font-weight:600; color:#1d4ed8; margin-bottom:16px;
|
||||
padding-bottom:12px; border-bottom:1px solid #e5e7eb; letter-spacing:0.04em;">
|
||||
DATA PEGAWAI
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<div>
|
||||
<label class="label">Nama Pegawai</label>
|
||||
<input type="text" value="{{ session('user')['name'] ?? 'Guest' }}" class="input readonly" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label">Username</label>
|
||||
<input type="text" value="{{ session('user')['username'] ?? '-' }}" class="input readonly" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- DETAIL KEGIATAN --}}
|
||||
<div class="card">
|
||||
|
||||
<div style="font-size:13px; font-weight:600; color:#1d4ed8; margin-bottom:16px;
|
||||
padding-bottom:12px; border-bottom:1px solid #e5e7eb; letter-spacing:0.04em;">
|
||||
DETAIL KEGIATAN
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="label">Judul Kegiatan</label>
|
||||
<input type="text" name="nama_kegiatan" class="input" placeholder="Monitoring perusahaan..." required>
|
||||
</div>
|
||||
|
||||
<div class="form-grid" style="margin-top:16px;">
|
||||
<div>
|
||||
<label class="label">Tanggal</label>
|
||||
<input type="date" name="tanggal" class="input" required>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label">Lokasi</label>
|
||||
<input type="text" name="lokasi" class="input" placeholder="Kota / Alamat" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:16px;">
|
||||
<label class="label">Detail Kegiatan</label>
|
||||
<textarea name="deskripsi" class="textarea" placeholder="Tulis laporan lengkap di sini..." required></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- UPLOAD --}}
|
||||
<div class="card">
|
||||
|
||||
<div style="font-size:13px; font-weight:600; color:#1d4ed8; margin-bottom:16px;
|
||||
padding-bottom:12px; border-bottom:1px solid #e5e7eb; letter-spacing:0.04em;">
|
||||
LAMPIRAN DOKUMENTASI
|
||||
</div>
|
||||
|
||||
<label class="upload-box" id="upload-label">
|
||||
<input type="file" name="image" id="file-input" accept=".pdf,.jpg,.jpeg,.png" hidden>
|
||||
|
||||
{{-- Icon Upload --}}
|
||||
<svg width="36" height="36" viewBox="0 0 24 24" fill="none"
|
||||
stroke="#9ca3af" stroke-width="1.5" style="margin:0 auto 10px;">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="17 8 12 3 7 8"/>
|
||||
<line x1="12" y1="3" x2="12" y2="15"/>
|
||||
</svg>
|
||||
|
||||
<p style="font-weight:600; font-size:14px; color:#374151; margin-bottom:4px;" id="file-name">
|
||||
Klik untuk upload file
|
||||
</p>
|
||||
<small style="color:#9ca3af; font-size:12px;">PDF / JPG / PNG · Maksimal 2MB</small>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
{{-- SUBMIT --}}
|
||||
<button class="btn" type="submit">
|
||||
Kirim Laporan
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
{{-- Script: tampilkan nama file setelah dipilih --}}
|
||||
<script>
|
||||
document.getElementById('file-input').addEventListener('change', function() {
|
||||
const fileName = this.files[0] ? this.files[0].name : 'Klik untuk upload file';
|
||||
document.getElementById('file-name').textContent = fileName;
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,215 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Panel Petugas – Disnakertrans Prov. Kalbar</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
/* ─── RESET + FONT ─── */
|
||||
*, *::before, *::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #F2F5FB;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
/* ─── SCROLLBAR ─── */
|
||||
::-webkit-scrollbar { width: 6px; }
|
||||
::-webkit-scrollbar-track { background: #f1f5f9; }
|
||||
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
|
||||
|
||||
/* ─── VARIABLES ─── */
|
||||
:root {
|
||||
--primary: #1d4ed8;
|
||||
--primary-soft: #e0e7ff;
|
||||
--border: #e5e7eb;
|
||||
--text: #111827;
|
||||
--muted: #6b7280;
|
||||
}
|
||||
|
||||
/* ─── CARD ─── */
|
||||
.card {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 28px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* ─── FORM GRID ─── */
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* ─── LABEL ─── */
|
||||
.label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--muted);
|
||||
margin-bottom: 6px;
|
||||
display: block;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
/* ─── INPUT ─── */
|
||||
.input {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
background: #fff;
|
||||
color: var(--text);
|
||||
transition: .2s;
|
||||
}
|
||||
.input:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(29,78,216,.1);
|
||||
}
|
||||
.readonly {
|
||||
background: #f3f4f6;
|
||||
color: #6b7280;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* ─── TEXTAREA ─── */
|
||||
.textarea {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
color: var(--text);
|
||||
min-height: 140px;
|
||||
resize: vertical;
|
||||
transition: .2s;
|
||||
}
|
||||
.textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(29,78,216,.1);
|
||||
}
|
||||
|
||||
/* ─── UPLOAD BOX ─── */
|
||||
.upload-box {
|
||||
border: 2px dashed var(--border);
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
border-radius: 14px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
transition: .2s;
|
||||
}
|
||||
.upload-box:hover {
|
||||
background: #f9fafb;
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
/* ─── BUTTON ─── */
|
||||
.btn {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
background: var(--primary);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.btn:hover {
|
||||
background: #1e40af;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(29,78,216,.3);
|
||||
}
|
||||
.btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ─── RESPONSIVE ─── */
|
||||
@media (max-width: 768px) {
|
||||
.form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
main {
|
||||
padding: 20px 0 !important;
|
||||
}
|
||||
.card {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@include('user.layouts.navbar')
|
||||
|
||||
<main style="padding: 40px 0;">
|
||||
<div style="max-width: 860px; margin: auto; padding: 0 24px;">
|
||||
@yield('content')
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('[onclick^="return confirm"]').forEach(function(btn) {
|
||||
const match = btn.getAttribute('onclick').match(/confirm\('([^']+)'\)/);
|
||||
if (match) {
|
||||
const message = match[1];
|
||||
btn.removeAttribute('onclick');
|
||||
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
const form = btn.closest('form');
|
||||
|
||||
Swal.fire({
|
||||
title: 'Konfirmasi',
|
||||
text: message,
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3b82f6',
|
||||
cancelButtonColor: '#64748b',
|
||||
confirmButtonText: 'Ya, Lanjutkan',
|
||||
cancelButtonText: 'Batal',
|
||||
reverseButtons: true,
|
||||
customClass: {
|
||||
confirmButton: 'rounded-xl',
|
||||
cancelButton: 'rounded-xl mr-2'
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
if (form) {
|
||||
form.submit();
|
||||
} else if(btn.getAttribute('href')) {
|
||||
window.location.href = btn.getAttribute('href');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,136 @@
|
||||
<nav class="bg-[#f8fafc] border-b border-slate-200 font-['Outfit'] sticky top-0 z-50 shadow-sm">
|
||||
<div class="max-w-[1200px] mx-auto px-4 md:px-6 lg:px-10">
|
||||
<div class="flex items-center justify-between h-[70px]">
|
||||
<!-- LEFT: LOGO -->
|
||||
<div class="flex items-center gap-2 md:gap-3">
|
||||
<img src="{{ asset('Kalimantan-Barat-Logo-Vector.png') }}" class="h-9 md:h-[42px] w-auto object-contain" alt="Logo Kalbar">
|
||||
<div class="leading-[1.2] border-l-2 border-slate-200 pl-2 md:pl-3">
|
||||
<div class="font-bold text-[11px] md:text-[14px] text-blue-900 tracking-[0.02em]">
|
||||
DINAS TENAGA KERJA DAN TRANSMIGRASI
|
||||
</div>
|
||||
<div class="text-[8px] md:text-[11px] text-slate-500 font-medium">
|
||||
PROVINSI KALIMANTAN BARAT
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hamburger Button (Mobile) -->
|
||||
<div class="flex md:hidden">
|
||||
<button type="button" id="user-menu-btn" class="text-slate-500 hover:text-blue-900 focus:outline-none p-2 rounded-md hover:bg-slate-200 transition-colors">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- CENTER & RIGHT: NAVIGATION (Desktop) -->
|
||||
<div class="hidden md:flex items-center gap-6">
|
||||
<div class="flex items-center gap-2 text-[14px]">
|
||||
<a href="{{ route('user.dashboard') }}"
|
||||
class="flex items-center gap-1.5 px-4 py-2 rounded-lg transition-all duration-200 {{ request()->routeIs('user.dashboard') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-500 font-medium hover:bg-slate-100 hover:text-blue-800' }}">
|
||||
<i data-lucide="layout-dashboard" class="w-4 h-4"></i> Dashboard
|
||||
</a>
|
||||
<a href="{{ route('input.activity') }}"
|
||||
class="flex items-center gap-1.5 px-4 py-2 rounded-lg transition-all duration-200 {{ request()->routeIs('input.activity') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-500 font-medium hover:bg-slate-100 hover:text-blue-800' }}">
|
||||
<i data-lucide="edit" class="w-4 h-4"></i> Input Kegiatan
|
||||
</a>
|
||||
<a href="{{ route('activity.list') }}"
|
||||
class="flex items-center gap-1.5 px-4 py-2 rounded-lg transition-all duration-200 {{ request()->routeIs('activity.list') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-500 font-medium hover:bg-slate-100 hover:text-blue-800' }}">
|
||||
<i data-lucide="folder" class="w-4 h-4"></i> Kegiatan Saya
|
||||
</a>
|
||||
<a href="{{ route('settings') ?? '#' }}"
|
||||
class="flex items-center gap-1.5 px-4 py-2 rounded-lg transition-all duration-200 {{ request()->routeIs('settings') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-500 font-medium hover:bg-slate-100 hover:text-blue-800' }}">
|
||||
<i data-lucide="settings" class="w-4 h-4"></i> Pengaturan
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="w-px h-8 bg-slate-300"></div>
|
||||
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="w-[38px] h-[38px] rounded-full bg-blue-900 text-white flex items-center justify-center font-bold text-[16px]">
|
||||
{{ strtoupper(substr(session('user')['name'] ?? 'U', 0, 1)) }}
|
||||
</div>
|
||||
<div class="leading-[1.2]">
|
||||
<div class="font-semibold text-[14px] text-slate-900">
|
||||
{{ session('user')['name'] ?? 'User' }}
|
||||
</div>
|
||||
<div class="text-[11px] text-slate-500 font-medium">
|
||||
USER
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('logout') }}" class="ml-2 m-0">
|
||||
@csrf
|
||||
<button type="submit" class="bg-transparent border-none cursor-pointer text-red-500 p-1.5 rounded-md hover:bg-red-50 transition-colors" title="Logout">
|
||||
<i data-lucide="log-out" class="w-[18px] h-[18px]"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu Panel -->
|
||||
<div id="user-mobile-menu" class="hidden md:hidden bg-[#f8fafc] border-t border-slate-200 shadow-xl absolute w-full left-0 pb-4">
|
||||
<div class="px-4 py-3 flex flex-col gap-2">
|
||||
<a href="{{ route('user.dashboard') }}"
|
||||
class="flex items-center gap-3 px-4 py-3 rounded-lg transition-all duration-200 {{ request()->routeIs('user.dashboard') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-600 font-medium hover:bg-slate-200' }}">
|
||||
<i data-lucide="layout-dashboard" class="w-4 h-4"></i> Dashboard
|
||||
</a>
|
||||
<a href="{{ route('input.activity') }}"
|
||||
class="flex items-center gap-3 px-4 py-3 rounded-lg transition-all duration-200 {{ request()->routeIs('input.activity') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-600 font-medium hover:bg-slate-200' }}">
|
||||
<i data-lucide="edit" class="w-4 h-4"></i> Input Kegiatan
|
||||
</a>
|
||||
<a href="{{ route('activity.list') }}"
|
||||
class="flex items-center gap-3 px-4 py-3 rounded-lg transition-all duration-200 {{ request()->routeIs('activity.list') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-600 font-medium hover:bg-slate-200' }}">
|
||||
<i data-lucide="folder" class="w-4 h-4"></i> Kegiatan Saya
|
||||
</a>
|
||||
<a href="{{ route('settings') ?? '#' }}"
|
||||
class="flex items-center gap-3 px-4 py-3 rounded-lg transition-all duration-200 {{ request()->routeIs('settings') ? 'text-blue-800 bg-indigo-50 font-semibold' : 'text-slate-600 font-medium hover:bg-slate-200' }}">
|
||||
<i data-lucide="settings" class="w-4 h-4"></i> Pengaturan
|
||||
</a>
|
||||
|
||||
<div class="h-px w-full bg-slate-200 my-2"></div>
|
||||
|
||||
<div class="flex items-center justify-between px-2">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-[38px] h-[38px] rounded-full bg-blue-900 text-white flex items-center justify-center font-bold text-[16px]">
|
||||
{{ strtoupper(substr(session('user')['name'] ?? 'U', 0, 1)) }}
|
||||
</div>
|
||||
<div class="leading-[1.2]">
|
||||
<div class="font-semibold text-[14px] text-slate-900">
|
||||
{{ session('user')['name'] ?? 'User' }}
|
||||
</div>
|
||||
<div class="text-[11px] text-slate-500 font-medium">
|
||||
USER
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('logout') }}" class="m-0">
|
||||
@csrf
|
||||
<button type="submit" class="bg-transparent border-none cursor-pointer text-red-500 p-2 rounded-md hover:bg-red-50 transition-colors flex items-center gap-2" title="Logout">
|
||||
<i data-lucide="log-out" class="w-5 h-5"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const btn = document.getElementById('user-menu-btn');
|
||||
const menu = document.getElementById('user-mobile-menu');
|
||||
if(btn && menu) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
menu.classList.toggle('hidden');
|
||||
lucide.createIcons();
|
||||
});
|
||||
document.addEventListener('click', function(e) {
|
||||
if(!menu.contains(e.target) && !btn.contains(e.target)) {
|
||||
menu.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,173 @@
|
||||
@php
|
||||
$role = session('user')['role'] ?? 'user';
|
||||
$layout = in_array($role, ['admin', 'superadmin']) ? 'admin.layouts.app' : 'user.layouts.app';
|
||||
|
||||
if ($role === 'superadmin') {
|
||||
$dashboardRoute = route('admin.superadmin.dashboard');
|
||||
} elseif ($role === 'admin') {
|
||||
$dashboardRoute = route('admin.dashboard');
|
||||
} else {
|
||||
$dashboardRoute = route('user.dashboard');
|
||||
}
|
||||
@endphp
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="max-w-4xl mx-auto mt-10 px-4 pb-20">
|
||||
|
||||
{{-- HEADER --}}
|
||||
<div class="mb-8">
|
||||
<a href="{{ $dashboardRoute }}" class="inline-flex items-center gap-2 text-sm text-slate-500 hover:text-[#0D215C] font-semibold mb-4 transition">
|
||||
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>
|
||||
Kembali ke Dashboard
|
||||
</a>
|
||||
<h2 class="text-2xl font-bold text-[#0D215C]">
|
||||
Pengaturan Profil
|
||||
</h2>
|
||||
<p class="text-sm text-slate-400">Kelola informasi akun dan kata sandi Anda.</p>
|
||||
</div>
|
||||
|
||||
@if(session('success'))
|
||||
<div class="mb-6 p-4 bg-green-100 border border-green-200 text-green-700 rounded-xl text-sm font-medium">
|
||||
{{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
<div class="mb-6 p-4 bg-red-100 border border-red-200 text-red-700 rounded-xl text-sm font-medium">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($errors->any())
|
||||
<div class="mb-6 p-4 bg-red-100 border border-red-200 text-red-700 rounded-xl text-sm font-medium">
|
||||
<ul class="list-disc list-inside">
|
||||
@foreach($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="grid grid-cols-1 gap-8">
|
||||
|
||||
{{-- FORM INFORMASI PROFIL --}}
|
||||
<div class="bg-white p-8 rounded-2xl shadow-sm border border-slate-100">
|
||||
<h4 class="text-lg font-bold text-[#0D215C] mb-6 flex items-center gap-2">
|
||||
<i data-lucide="user" class="w-5 h-5"></i> Informasi Pribadi
|
||||
</h4>
|
||||
|
||||
<form action="{{ route('settings.update') }}" method="POST" class="space-y-5">
|
||||
@csrf
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Nama Lengkap</label>
|
||||
<input type="text" name="name" value="{{ session('user')['name'] ?? '' }}"
|
||||
class="w-full p-3 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Username <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="username" value="{{ session('user')['username'] ?? '' }}"
|
||||
class="w-full p-3 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="pt-4">
|
||||
<button type="submit" class="bg-[#0D215C] hover:bg-[#0a1a47] text-white px-8 py-3 rounded-xl font-bold transition shadow-lg shadow-blue-900/10">
|
||||
Simpan Perubahan
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@if($role !== 'user')
|
||||
{{-- FORM GANTI PASSWORD --}}
|
||||
<div class="bg-white p-8 rounded-2xl shadow-sm border border-slate-100">
|
||||
<h4 class="text-lg font-bold text-[#0D215C] mb-6 flex items-center gap-2">
|
||||
<i data-lucide="lock" class="w-5 h-5"></i> Keamanan Akun
|
||||
</h4>
|
||||
|
||||
<form action="{{ route('settings.update') }}" method="POST" class="space-y-5">
|
||||
@csrf
|
||||
<input type="hidden" name="username" value="{{ session('user')['username'] ?? '' }}">
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Kata Sandi Saat Ini</label>
|
||||
<div class="relative">
|
||||
<input type="password" name="current_password" id="current_password" autocomplete="off"
|
||||
class="w-full p-3 pr-10 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition">
|
||||
<button type="button" onclick="togglePassword('current_password', this)" class="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-blue-500 focus:outline-none">
|
||||
<i data-lucide="eye" class="w-5 h-5 eye-icon"></i>
|
||||
<i data-lucide="eye-off" class="w-5 h-5 eye-off-icon hidden"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Kata Sandi Baru</label>
|
||||
<div class="relative">
|
||||
<input type="password" name="password" id="password"
|
||||
class="w-full p-3 pr-10 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition">
|
||||
<button type="button" onclick="togglePassword('password', this)" class="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-blue-500 focus:outline-none">
|
||||
<i data-lucide="eye" class="w-5 h-5 eye-icon"></i>
|
||||
<i data-lucide="eye-off" class="w-5 h-5 eye-off-icon hidden"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm font-semibold text-slate-700 block mb-2">Konfirmasi Kata Sandi</label>
|
||||
<div class="relative">
|
||||
<input type="password" name="password_confirmation" id="password_confirmation"
|
||||
class="w-full p-3 pr-10 rounded-xl bg-slate-50 border border-slate-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100 outline-none transition">
|
||||
<button type="button" onclick="togglePassword('password_confirmation', this)" class="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-blue-500 focus:outline-none">
|
||||
<i data-lucide="eye" class="w-5 h-5 eye-icon"></i>
|
||||
<i data-lucide="eye-off" class="w-5 h-5 eye-off-icon hidden"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-4">
|
||||
<button type="submit" class="bg-white border border-slate-200 hover:bg-slate-50 text-[#0D215C] px-8 py-3 rounded-xl font-bold transition">
|
||||
Perbarui Kata Sandi
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
});
|
||||
|
||||
function togglePassword(inputId, btn) {
|
||||
const input = document.getElementById(inputId);
|
||||
const eye = btn.querySelector('.eye-icon');
|
||||
const eyeOff = btn.querySelector('.eye-off-icon');
|
||||
|
||||
if (input.type === 'password') {
|
||||
input.type = 'text';
|
||||
eye.classList.add('hidden');
|
||||
eyeOff.classList.remove('hidden');
|
||||
btn.classList.add('text-blue-500');
|
||||
btn.classList.remove('text-slate-400');
|
||||
} else {
|
||||
input.type = 'password';
|
||||
eye.classList.remove('hidden');
|
||||
eyeOff.classList.add('hidden');
|
||||
btn.classList.remove('text-blue-500');
|
||||
btn.classList.add('text-slate-400');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user