<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Employee Dashboard — Soft Pastel</title>

<style>
  :root{
    --bg: #f7f6fb;
    --card: #ffffff;
    --muted: #8b8892;
    --glass: rgba(255,255,255,0.6);
    --accent-1: #A3E4DB; /* mint */
    --accent-2: #FFD6A5; /* peach */
    --accent-3: #C6B6FF; /* lavender */
    --accent-4: #FFB3C6; /* pink */
    --accent-5: #FFF6A5; /* yellow */
    --shadow: 0 6px 18px rgba(41, 44, 63, 0.08);
    --radius: 12px;
  }

  *{box-sizing:border-box}
  body{
    margin:0;
    font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
    background: linear-gradient(180deg,var(--bg) 0%, #fbfbff 100%);
    color: #222;
    -webkit-font-smoothing:antialiased;
    -moz-osx-font-smoothing:grayscale;
    padding-bottom: 60px;
  }

  /* NAVBAR */
  .navbar{
    display:flex;
    align-items:center;
    justify-content:space-between;
    padding:20px 28px;
    gap:16px;
    position:sticky;
    top:0;
    background: linear-gradient(90deg, rgba(255,255,255,0.6), rgba(255,255,255,0.4));
    backdrop-filter: blur(6px);
    border-bottom: 1px solid rgba(0,0,0,0.04);
    z-index:50;
  }
  .brand {
    display:flex;
    align-items:center;
    gap:12px;
  }
  .logo {
    width:44px;
    height:44px;
    border-radius:10px;
    background: linear-gradient(135deg,var(--accent-3),var(--accent-1));
    box-shadow: 0 6px 14px rgba(163, 228, 219, 0.25);
    display:flex;
    align-items:center;
    justify-content:center;
    color:white;
    font-weight:700;
    font-size:18px;
  }
  .brand h1{
    margin:0;
    font-size:16px;
    letter-spacing:-0.2px;
  }
  .nav-actions{
    display:flex;
    align-items:center;
    gap:10px;
  }
  .search {
    display:flex;
    align-items:center;
    gap:8px;
    background:var(--card);
    padding:8px 12px;
    border-radius:999px;
    box-shadow: var(--shadow);
    min-width:260px;
  }
  .search input{
    border:0;
    outline:0;
    font-size:14px;
    background:transparent;
    width:100%;
  }
  .add-btn{
    display:inline-flex;
    align-items:center;
    gap:10px;
    background: linear-gradient(90deg,var(--accent-2),var(--accent-4));
    border:none;
    color:#2a2a2a;
    padding:10px 14px;
    border-radius:10px;
    font-weight:600;
    cursor:pointer;
    box-shadow: var(--shadow);
    transition:transform .12s ease, box-shadow .12s;
  }
  .add-btn:hover{ transform:translateY(-3px) }

  /* LAYOUT */
  .container{
    width:min(1200px,92%);
    margin:28px auto;
    display:grid;
    grid-template-columns: 1fr;
    gap:20px;
  }

  .top-row{
    display:flex;
    gap:20px;
    align-items:stretch;
    flex-wrap:wrap;
  }

  .card{
    background:var(--card);
    border-radius: var(--radius);
    padding:18px;
    box-shadow: var(--shadow);
    flex:1;
    min-width:220px;
  }
  .card.small { max-width:260px; display:flex; align-items:center; gap:14px; }

  .kpi-number{ font-size:28px; font-weight:700; margin-top:6px; }
  .kpi-label{ color:var(--muted); font-size:13px; }

  /* TABLE AREA */
  .panel{
    background: linear-gradient(180deg,var(--card), rgba(255,255,255,0.96));
    border-radius: var(--radius);
    padding:18px;
    box-shadow: var(--shadow);
  }

  .toolbar{
    display:flex;
    justify-content:space-between;
    align-items:center;
    gap:12px;
    margin-bottom:12px;
  }
  .controls{
    display:flex;
    gap:8px;
    align-items:center;
  }
  .select, .perpage {
    background:transparent;
    padding:8px 10px;
    border-radius:8px;
    border:1px solid rgba(30,30,30,0.06);
    font-size:13px;
  }

  table{
    width:100%;
    border-collapse:collapse;
    font-size:14px;
    border-radius:10px;
    overflow:hidden;
    background:transparent;
  }
  thead tr{
    background: linear-gradient(90deg, rgba(254,241,242,0.5), rgba(244,248,255,0.6));
  }
  th, td{
    text-align:left;
    padding:12px 14px;
    border-bottom: 1px solid rgba(35,36,38,0.06);
    vertical-align:middle;
  }
  th{
    font-size:13px;
    color:#444;
    font-weight:600;
  }
  tbody tr:hover{ background: linear-gradient(90deg, rgba(255,255,255,0.6), rgba(250,250,255,0.7)) }

  .avatar{
    width:44px;height:44px;border-radius:10px;object-fit:cover;border:2px solid rgba(255,255,255,0.6);
  }
  .name-row{ display:flex; gap:12px; align-items:center; }
  .muted{ color:var(--muted); font-size:13px }

  .action-btn{
    border:0;padding:8px 10px;border-radius:8px;cursor:pointer;font-weight:600;font-size:13px;
  }
  .btn-edit{ background: linear-gradient(90deg,#FFF1F3,#FFF6EA); color:#6d3b5a; }
  .btn-delete{ background: linear-gradient(90deg,#FFF3E5,#FFEAEA); color:#8a3b2b; }
  .btn-edit:hover, .btn-delete:hover{ transform:translateY(-2px) }

  /* PAGINATION */
  .pagination{ display:flex; gap:8px; align-items:center; justify-content:flex-end; margin-top:12px; }
  .page{ padding:8px 10px; border-radius:8px; background:transparent; border:1px solid rgba(0,0,0,0.05); cursor:pointer; }
  .page.active{ background: linear-gradient(90deg,#C6B6FF,#A3E4DB); color:#2c2c2c; font-weight:700; border:none; }

  /* MODAL */
  .modal-backdrop{
    position:fixed; inset:0; background:rgba(12,12,20,0.35);
    display:none; align-items:center; justify-content:center; z-index:80;
  }
  .modal-window{
    width:100%; max-width:720px; background:linear-gradient(180deg, rgba(255,255,255,0.98), rgba(255,255,255,0.92));
    padding:18px; border-radius:14px; box-shadow: 0 20px 60px rgba(34,30,60,0.18);
  }
  .modal-grid{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:10px; }
  .field{ display:flex; flex-direction:column; gap:6px; }
  .field input, .field textarea, .field select{
    padding:10px 12px; border-radius:10px; border:1px solid rgba(25,25,35,0.06); font-size:14px;
    background: linear-gradient(180deg, #fff, #fafafa);
  }
  .modal-actions{ display:flex; justify-content:flex-end; gap:10px; margin-top:14px; }
  .btn-cancel{ background:transparent; border:1px solid rgba(0,0,0,0.06); padding:10px 12px;border-radius:10px;cursor:pointer; }
  .btn-save{ background: linear-gradient(90deg,var(--accent-1),var(--accent-2)); border:none; padding:10px 12px;border-radius:10px; cursor:pointer; font-weight:700; }

  /* responsive */
  @media (max-width:880px){
    .modal-grid{ grid-template-columns:1fr; }
    .top-row{ flex-direction:column }
    .search{ min-width: 160px }
  }
</style>
</head>
<body>

<!-- NAVBAR -->
<header class="navbar">
  <div class="brand">
    <div class="logo">EM</div>
    <div>
      <h1 style="margin:0;font-size:15px;">Employee Dashboard</h1>
      <div style="font-size:12px;color:var(--muted)">Soft Pastel • HR overview</div>
    </div>
  </div>

  <div class="nav-actions">
    <div class="search" role="search">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" style="opacity:.8"><path d="M21 21l-4.35-4.35" stroke="#6b6b79" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><circle cx="11" cy="11" r="6" stroke="#6b6b79" stroke-width="1.6"/></svg>
      <input id="globalSearch" placeholder="Search name, position, email..." />
    </div>

    <button class="add-btn" id="openAdd">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" style="opacity:.95;margin-left:2px">
        <path d="M12 5v14M5 12h14" stroke="#2b2b2b" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
      </svg>
      Add Employee
    </button>

    <!-- 🔥 BUTTON LOGOUT -->
    <button class="add-btn" id="logoutBtn" style="background:linear-gradient(90deg,#FFD6A5,#FFB3C6)">
      Logout
    </button>
</div>

</header>

<main class="container" role="main">

  <div class="top-row">
    <div class="card small" style="background:linear-gradient(135deg,var(--accent-1), #E8F8F3);">
      <div>
        <div class="kpi-label">Total Employees</div>
        <div class="kpi-number" id="kpiTotal">12</div>
        <div class="muted" style="margin-top:6px;font-size:13px">Updated just now</div>
      </div>
    </div>

    <div class="card">
      <div style="display:flex;justify-content:space-between;align-items:center">
        <div>
          <div class="kpi-label">Active This Month</div>
          <div class="kpi-number">9</div>
        </div>
        <div style="text-align:right;color:var(--muted)">Overview & stats</div>
      </div>
    </div>
  </div>

  <section class="panel" aria-labelledby="employeesHeading">
    <div class="toolbar">
      <h2 id="employeesHeading" style="margin:0;font-size:16px">Employees</h2>

      <div class="controls">
        <label class="muted" style="font-size:13px">Show</label>
        <select id="perPage" class="perpage select" title="Rows per page">
          <option value="5">5</option>
          <option value="8" selected>8</option>
          <option value="12">12</option>
        </select>
      </div>
    </div>

    <div style="overflow-x:auto">
      <table aria-describedby="employeesHeading" id="employeesTable">
        <thead>
          <tr>
            <th style="width:48px">#</th>
            <th>Photo</th>
            <th>Name</th>
            <th>Position</th>
            <th>Phone</th>
            <th>Email</th>
            <th>Join Date</th>
            <th style="width:160px">Action</th>
          </tr>
        </thead>
        <tbody id="tableBody">
          <!-- rows injected by JS -->
        </tbody>
      </table>
    </div>

    <div style="display:flex;align-items:center;justify-content:space-between;margin-top:12px">
      <div class="muted" id="tableInfo">Showing 0 of 0</div>
      <div class="pagination" id="pagination"></div>
    </div>
  </section>
</main>

<!-- MODAL BACKDROP -->
<div class="modal-backdrop" id="modalBackdrop" aria-hidden="true">
  <div class="modal-window" role="dialog" aria-modal="true" aria-labelledby="modalTitle">
    <h3 id="modalTitle">Add Employee</h3>

    <form id="employeeForm" class="modal-grid">
      <input type="hidden" name="id" id="empId" />
      <div class="field">
        <label class="muted">Full name</label>
        <input name="name" id="empName" required />
      </div>
      <div class="field">
        <label class="muted">Position</label>
        <input name="position" id="empPosition" required />
      </div>

      <div class="field">
        <label class="muted">Phone</label>
        <input name="phone" id="empPhone" />
      </div>
      <div class="field">
        <label class="muted">Email</label>
        <input type="email" name="email" id="empEmail" />
      </div>

      <div class="field" style="grid-column:1/3">
        <label class="muted">Address</label>
        <input name="address" id="empAddress" />
      </div>

      <div class="field">
        <label class="muted">Join date</label>
        <input type="date" name="join_date" id="empJoin" />
      </div>

      <div class="field">
        <label class="muted">Photo URL (optional)</label>
        <input name="photo" id="empPhoto" placeholder="https://...jpg or leave blank for avatar" />
      </div>

      <div class="modal-actions" style="grid-column:1/3">
        <button type="button" class="btn-cancel" id="closeModal">Cancel</button>
        <button type="submit" class="btn-save" id="saveBtn">Save</button>
      </div>
    </form>
  </div>
</div>

<script>
/* ===========================
   In-memory dataset (sample)
   =========================== */
let employees = [
  {id:1, name:"Alicia Hart", position:"Designer", phone:"0811-2233", email:"alicia@example.com", address:"Bandung", join_date:"2023-05-12", photo:"https://i.pravatar.cc/120?img=12"},
  {id:2, name:"Bima Santoso", position:"Backend Engineer", phone:"0812-3344", email:"bima@company.com", address:"Jakarta", join_date:"2022-11-01", photo:"https://i.pravatar.cc/120?img=5"},
  {id:3, name:"Clara Wijaya", position:"HR Specialist", phone:"0813-4455", email:"clara@company.com", address:"Surabaya", join_date:"2024-01-08", photo:""},
  {id:4, name:"Dian Pratama", position:"Data Analyst", phone:"0821-5566", email:"dian@company.com", address:"Yogyakarta", join_date:"2021-09-21", photo:"https://i.pravatar.cc/120?img=8"},
  {id:5, name:"Evan Putra", position:"Frontend Engineer", phone:"0856-6677", email:"evan@company.com", address:"Medan", join_date:"2020-07-30", photo:""},
  {id:6, name:"Farah Nur", position:"Product Owner", phone:"0822-7788", email:"farah@company.com", address:"Makassar", join_date:"2019-03-14", photo:"https://i.pravatar.cc/120?img=47"},
  {id:7, name:"Gilang H", position:"QA Engineer", phone:"0819-8899", email:"gilang@company.com", address:"Padang", join_date:"2024-03-05", photo:""},
  {id:8, name:"Hanna S", position:"Support", phone:"0810-9900", email:"hanna@company.com", address:"Semarang", join_date:"2022-12-11", photo:""},
  {id:9, name:"Irfan M", position:"DevOps", phone:"0817-1010", email:"irfan@company.com", address:"Denpasar", join_date:"2021-06-25", photo:""},
  {id:10, name:"Jasmine R", position:"Marketing", phone:"0816-2020", email:"jasmine@company.com", address:"Palembang", join_date:"2023-08-19", photo:""}
];

let state = {
  page: 1,
  perPage: parseInt(document.getElementById('perPage').value),
  query: ''
};

/* DOM refs */
const tableBody = document.getElementById('tableBody');
const pagination = document.getElementById('pagination');
const tableInfo = document.getElementById('tableInfo');
const kpiTotal = document.getElementById('kpiTotal');

function formatDate(d){
  if(!d) return '-';
  return d;
}

function avatarUrl(photo, name){
  if(photo && photo.trim()) return photo;
  // generate colored initial avatar via placeholder service (simple)
  const bgList = ['A3E4DB','FFD6A5','C6B6FF','FFB3C6','FFF6A5'];
  const color = bgList[(name.length) % bgList.length];
  return `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}&background=${color}&color=ffffff&size=128`;
}

/* render table rows with pagination + search */
function getFiltered(){
  const q = state.query.trim().toLowerCase();
  if(!q) return employees.slice();
  return employees.filter(e =>
    (e.name||'').toLowerCase().includes(q) ||
    (e.position||'').toLowerCase().includes(q) ||
    (e.email||'').toLowerCase().includes(q)
  );
}

function renderTable(){
  const list = getFiltered();
  const total = list.length;
  const per = state.perPage;
  const pages = Math.max(1, Math.ceil(total / per));
  if(state.page > pages) state.page = pages;

  const start = (state.page - 1) * per;
  const visible = list.slice(start, start + per);

  tableBody.innerHTML = visible.map((e, idx) => `
    <tr>
      <td>${start + idx + 1}</td>
      <td><img class="avatar" src="${avatarUrl(e.photo, e.name)}" alt=""></td>
      <td>
        <div class="name-row">
          <div style="display:flex;flex-direction:column">
            <strong>${escapeHtml(e.name)}</strong>
            <div class="muted" style="font-size:12px">${escapeHtml(e.address || '')}</div>
          </div>
        </div>
      </td>
      <td>${escapeHtml(e.position)}</td>
      <td>${escapeHtml(e.phone)}</td>
      <td><a href="mailto:${escapeHtml(e.email)}" class="muted">${escapeHtml(e.email)}</a></td>
      <td class="muted">${formatDate(e.join_date)}</td>
      <td>
        <button class="action-btn btn-edit" onclick='openEdit(${e.id})'>Edit</button>
        <button class="action-btn btn-delete" onclick='removeEmployee(${e.id})'>Delete</button>
      </td>
    </tr>
  `).join('');

  // pagination
  renderPagination(pages);
  tableInfo.textContent = `Showing ${visible.length} of ${total} (${employees.length} total)`;
  kpiTotal.textContent = employees.length;
}

function renderPagination(totalPages){
  pagination.innerHTML = '';
  // show previous
  const prev = document.createElement('button'); prev.className='page'; prev.innerText='‹';
  prev.disabled = state.page===1;
  prev.onclick = ()=>{ if(state.page>1){ state.page--; renderTable(); } };
  pagination.appendChild(prev);

  // show limited pages
  const maxButtons = 5;
  let start = Math.max(1, state.page - Math.floor(maxButtons/2));
  let end = Math.min(totalPages, start + maxButtons - 1);
  if(end - start < maxButtons -1){ start = Math.max(1, end - maxButtons +1); }
  for(let p=start;p<=end;p++){
    const btn = document.createElement('button');
    btn.className = 'page' + (p===state.page ? ' active' : '');
    btn.innerText = p;
    btn.onclick = ()=>{ state.page = p; renderTable(); };
    pagination.appendChild(btn);
  }

  const next = document.createElement('button'); next.className='page'; next.innerText='›';
  next.disabled = state.page===totalPages;
  next.onclick = ()=>{ if(state.page<totalPages){ state.page++; renderTable(); } };
  pagination.appendChild(next);
}

/* escape to avoid potential injection if used on real data */
function escapeHtml(s){
  if(!s && s!==0) return '';
  return String(s)
    .replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('>','&gt;')
    .replaceAll('"','&quot;').replaceAll("'","&#039;");
}

/* CRUD-ish actions (in-memory) */
function openModal(mode='add'){
  const bd = document.getElementById('modalBackdrop');
  bd.style.display = 'flex';
  bd.setAttribute('aria-hidden','false');
  document.getElementById('modalTitle').innerText = mode==='add' ? 'Add Employee' : 'Edit Employee';
  document.getElementById('empName').focus();
}

function closeModal(){
  const bd = document.getElementById('modalBackdrop');
  bd.style.display = 'none';
  bd.setAttribute('aria-hidden','true');
  document.getElementById('employeeForm').reset();
  document.getElementById('empId').value = '';
}

document.getElementById('openAdd').addEventListener('click', ()=>{
  openModal('add');
});
document.getElementById('closeModal').addEventListener('click', closeModal);

function openEdit(id){
  const e = employees.find(x=>x.id===id);
  if(!e) return alert('Employee not found');
  document.getElementById('empId').value = e.id;
  document.getElementById('empName').value = e.name;
  document.getElementById('empPosition').value = e.position;
  document.getElementById('empPhone').value = e.phone;
  document.getElementById('empEmail').value = e.email;
  document.getElementById('empAddress').value = e.address;
  document.getElementById('empJoin').value = e.join_date;
  document.getElementById('empPhoto').value = e.photo || '';
  openModal('edit');
}

function removeEmployee(id){
  if(!confirm('Delete this employee?')) return;
  employees = employees.filter(e=>e.id!==id);
  renderTable();
}

/* form submit save */
document.getElementById('employeeForm').addEventListener('submit', function(ev){
  ev.preventDefault();
  const id = document.getElementById('empId').value;
  const obj = {
    id: id ? parseInt(id) : Date.now(),
    name: document.getElementById('empName').value.trim(),
    position: document.getElementById('empPosition').value.trim(),
    phone: document.getElementById('empPhone').value.trim(),
    email: document.getElementById('empEmail').value.trim(),
    address: document.getElementById('empAddress').value.trim(),
    join_date: document.getElementById('empJoin').value,
    photo: document.getElementById('empPhoto').value.trim()
  };

  if(!obj.name || !obj.position){
    alert('Please fill name and position');
    return;
  }

  if(id){
    // update
    const idx = employees.findIndex(e=>e.id===parseInt(id));
    if(idx>-1) employees[idx] = obj;
  } else {
    // add to top
    employees.unshift(obj);
  }

  closeModal();
  state.page = 1;
  renderTable();
});

/* search + perpage */
document.getElementById('globalSearch').addEventListener('input', function(e){
  state.query = e.target.value;
  state.page = 1;
  renderTable();
});
document.getElementById('perPage').addEventListener('change', function(e){
  state.perPage = parseInt(e.target.value);
  state.page = 1;
  renderTable();
});

/* close modal on backdrop click */
document.getElementById('modalBackdrop').addEventListener('click', function(e){
  if(e.target === this) closeModal();
});

/* initial render */
renderTable();
</script>
</body>
</html>
