295 lines
No EOL
18 KiB
PHP
295 lines
No EOL
18 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>FKI 자산관리 시스템 | Dashboard</title>
|
|
<!-- Zero-Mojibake Protocol: UTF-8 and Meta tag included -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Pretendard:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
body {
|
|
font-family: 'Pretendard', sans-serif;
|
|
}
|
|
|
|
[x-cloak] {
|
|
display: none !important;
|
|
}
|
|
|
|
.glass {
|
|
background: rgba(255, 255, 255, 0.7);
|
|
backdrop-filter: blur(10px);
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
}
|
|
|
|
.gradient-bg {
|
|
background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body class="bg-[#f8fafc] text-slate-800" x-data="dashboard()">
|
|
|
|
<!-- Side Navigation -->
|
|
<aside class="fixed inset-y-0 left-0 w-64 gradient-bg text-white hidden lg:flex flex-col shadow-2xl z-50">
|
|
<div class="p-6">
|
|
<h1 class="text-2xl font-bold tracking-tight">FKI <span class="text-blue-400">ASSET</span></h1>
|
|
<p class="text-xs text-slate-400 mt-1 uppercase tracking-widest font-semibold">Corporate Resource V2</p>
|
|
</div>
|
|
<nav class="mt-6 flex-1 px-4 space-y-2">
|
|
<a href="index.php"
|
|
class="flex items-center space-x-3 bg-blue-600/20 text-blue-400 p-3 rounded-xl transition-all border border-blue-500/20">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
|
</svg>
|
|
<span class="font-medium">대시보드</span>
|
|
</a>
|
|
<a href="users.php"
|
|
class="flex items-center space-x-3 text-slate-400 hover:bg-slate-700/50 hover:text-white p-3 rounded-xl transition-all">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
|
|
</svg>
|
|
<span class="font-medium">직원 마스터</span>
|
|
</a>
|
|
<a href="laptops.php"
|
|
class="flex items-center space-x-3 text-slate-400 hover:bg-slate-700/50 hover:text-white p-3 rounded-xl transition-all">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
|
</svg>
|
|
<span class="font-medium">노트북 자산</span>
|
|
</a>
|
|
</nav>
|
|
<div class="p-6 border-t border-slate-700">
|
|
<div class="bg-slate-800 rounded-xl p-4 flex items-center space-x-3">
|
|
<div class="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center text-sm font-bold">AD
|
|
</div>
|
|
<div>
|
|
<p class="text-sm font-semibold">Admin</p>
|
|
<p class="text-xs text-slate-400">System Architect</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Main Content -->
|
|
<main class="lg:ml-64 p-8">
|
|
<header class="flex justify-between items-center mb-10">
|
|
<div>
|
|
<h2 class="text-3xl font-extrabold text-slate-900 tracking-tight">System Statistics</h2>
|
|
<p class="text-slate-500 mt-1">실시간 자산 배정 현황 및 가동률을 확인하세요.</p>
|
|
</div>
|
|
<div class="flex items-center space-x-4">
|
|
<button @click="init()"
|
|
class="bg-white border border-slate-200 p-2.5 rounded-xl shadow-sm hover:bg-slate-50 transition-all">
|
|
<svg class="w-5 h-5 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
</svg>
|
|
</button>
|
|
<div class="h-8 w-[1px] bg-slate-200"></div>
|
|
<span class="text-sm font-bold text-blue-600 bg-blue-50 px-4 py-2 rounded-full">LIVE</span>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Stats Grid -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-8">
|
|
|
|
<!-- Laptop Card -->
|
|
<div
|
|
class="bg-white p-7 rounded-3xl shadow-sm border border-slate-100 hover:shadow-xl hover:-translate-y-1 transition-all duration-300">
|
|
<div class="flex justify-between items-start mb-6">
|
|
<div class="p-4 bg-blue-50 rounded-2xl text-blue-600">
|
|
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
|
</svg>
|
|
</div>
|
|
<span class="text-xs font-bold text-blue-500 bg-blue-50 px-2.5 py-1 rounded-lg"
|
|
x-text="calcPercent(stats.laptops) + '%'"></span>
|
|
</div>
|
|
<h3 class="text-slate-500 font-bold uppercase tracking-wider text-xs mb-1">Laptop Mobility</h3>
|
|
<div class="flex items-baseline space-x-2 mb-4">
|
|
<span class="text-4xl font-black text-slate-900" x-text="stats.laptops.assigned">0</span>
|
|
<span class="text-slate-400 font-medium tracking-tighter">/ <span
|
|
x-text="stats.laptops.total">0</span> total</span>
|
|
</div>
|
|
<div class="w-full bg-slate-100 h-2.5 rounded-full overflow-hidden">
|
|
<div class="h-full bg-blue-500 rounded-full transition-all duration-1000"
|
|
:style="'width: ' + calcPercent(stats.laptops) + '%'"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Access Cards -->
|
|
<div
|
|
class="bg-white p-7 rounded-3xl shadow-sm border border-slate-100 hover:shadow-xl hover:-translate-y-1 transition-all duration-300">
|
|
<div class="flex justify-between items-start mb-6">
|
|
<div class="p-4 bg-emerald-50 rounded-2xl text-emerald-600">
|
|
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
|
|
</svg>
|
|
</div>
|
|
<span
|
|
class="text-xs font-bold text-emerald-500 bg-emerald-50 px-2.5 py-1 rounded-lg">Security</span>
|
|
</div>
|
|
<h3 class="text-slate-500 font-bold uppercase tracking-wider text-xs mb-1">Access Cards</h3>
|
|
<div class="flex items-baseline space-x-2 mb-4">
|
|
<span class="text-4xl font-black text-slate-900" x-text="stats.cards.assigned">0</span>
|
|
<span class="text-slate-400 font-medium tracking-tighter">/ <span
|
|
x-text="stats.cards.total">0</span> units</span>
|
|
</div>
|
|
<p class="text-slate-400 text-xs italic">임시 출입증 총 대여 현황</p>
|
|
</div>
|
|
|
|
<!-- MFP Card -->
|
|
<div
|
|
class="bg-white p-7 rounded-3xl shadow-sm border border-slate-100 hover:shadow-xl hover:-translate-y-1 transition-all duration-300">
|
|
<div class="flex justify-between items-start mb-6">
|
|
<div class="p-4 bg-amber-50 rounded-2xl text-amber-600">
|
|
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
|
|
</svg>
|
|
</div>
|
|
<span class="text-xs font-bold text-amber-500 bg-amber-50 px-2.5 py-1 rounded-lg"
|
|
x-text="calcPercent(stats.mfp) + '%'"></span>
|
|
</div>
|
|
<h3 class="text-slate-500 font-bold uppercase tracking-wider text-xs mb-1">MFP Accounts</h3>
|
|
<div class="flex items-baseline space-x-2 mb-4">
|
|
<span class="text-4xl font-black text-slate-900" x-text="stats.mfp.assigned">0</span>
|
|
<span class="text-slate-400 font-medium tracking-tighter">/ <span x-text="stats.mfp.total">0</span>
|
|
active</span>
|
|
</div>
|
|
<div class="w-full bg-slate-100 h-2.5 rounded-full overflow-hidden">
|
|
<div class="h-full bg-amber-500 rounded-full transition-all duration-1000"
|
|
:style="'width: ' + calcPercent(stats.mfp) + '%'"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Employee Card -->
|
|
<div
|
|
class="bg-white p-7 rounded-3xl shadow-sm border border-slate-100 hover:shadow-xl hover:-translate-y-1 transition-all duration-300">
|
|
<div class="flex justify-between items-start mb-6">
|
|
<div class="p-4 bg-indigo-50 rounded-2xl text-indigo-600">
|
|
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
|
</svg>
|
|
</div>
|
|
<span
|
|
class="text-xs font-bold text-indigo-500 bg-indigo-50 px-2.5 py-1 rounded-lg">Accounting</span>
|
|
</div>
|
|
<h3 class="text-slate-500 font-bold uppercase tracking-wider text-xs mb-1">Account Division</h3>
|
|
<div class="space-y-3 mt-4">
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-sm font-semibold text-slate-600">일반회계</span>
|
|
<span class="text-lg font-black text-slate-900" x-text="stats.users.general">0</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-sm font-semibold text-slate-600">특별회계</span>
|
|
<span class="text-lg font-black text-slate-900" x-text="stats.users.special">0</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Quick Links -->
|
|
<section class="mt-16">
|
|
<h3 class="text-xl font-bold text-slate-900 mb-6 flex items-center">
|
|
<svg class="w-6 h-6 mr-2 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M13 10V3L4 14h7v7l9-11h-7z" />
|
|
</svg>
|
|
퀵 네비게이션
|
|
</h3>
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
<a href="users.php"
|
|
class="group bg-white p-6 rounded-2xl border border-slate-200 hover:border-blue-500 transition-all flex items-center space-x-4">
|
|
<div class="bg-slate-50 p-3 rounded-xl group-hover:bg-blue-50 transition-colors">
|
|
<svg class="w-6 h-6 text-slate-400 group-hover:text-blue-500" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="font-black text-slate-900 group-hover:text-blue-600 transition-colors">직원 DB 관리</p>
|
|
<p class="text-xs text-slate-400">사번/부서/연락처</p>
|
|
</div>
|
|
</a>
|
|
<a href="laptops.php"
|
|
class="group bg-white p-6 rounded-2xl border border-slate-200 hover:border-blue-500 transition-all flex items-center space-x-4">
|
|
<div class="bg-slate-50 p-3 rounded-xl group-hover:bg-blue-50 transition-colors">
|
|
<svg class="w-6 h-6 text-slate-400 group-hover:text-blue-500" fill="none" stroke="currentColor"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="font-black text-slate-900 group-hover:text-blue-600 transition-colors">노트북 실사</p>
|
|
<p class="text-xs text-slate-400">자산태그/배정현황</p>
|
|
</div>
|
|
</a>
|
|
<div
|
|
class="opacity-50 cursor-not-allowed bg-slate-50 p-6 rounded-2xl border border-slate-100 flex items-center space-x-4">
|
|
<div class="bg-slate-100 p-3 rounded-xl">
|
|
<svg class="w-6 h-6 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="font-black text-slate-500">보안실 연동</p>
|
|
<p class="text-xs text-slate-400 italic">준비 중</p>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="opacity-50 cursor-not-allowed bg-slate-50 p-6 rounded-2xl border border-slate-100 flex items-center space-x-4">
|
|
<div class="bg-slate-100 p-3 rounded-xl">
|
|
<svg class="w-6 h-6 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="font-black text-slate-500">환경 설정</p>
|
|
<p class="text-xs text-slate-400 italic">준비 중</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<script>
|
|
function dashboard() {
|
|
return {
|
|
stats: { laptops: {}, cards: {}, mfp: {}, users: {} },
|
|
init() {
|
|
fetch('api.php?action=get_dashboard_stats')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
this.stats = data;
|
|
})
|
|
.catch(err => console.error("Stats Fetch Error:", err));
|
|
},
|
|
calcPercent(obj) {
|
|
if (!obj || !obj.total || obj.total == 0) return 0;
|
|
return Math.round((obj.assigned / obj.total) * 100);
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
|
|
</html> |