588 lines
19 KiB
HTML
588 lines
19 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<title>Bossier City Phone Directory</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta name="description" content="Bossier City Casino Phone Directory" />
|
||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||
<meta http-equiv="Pragma" content="no-cache" />
|
||
<meta http-equiv="Expires" content="0" />
|
||
<link rel="icon" href="favicon.png">
|
||
|
||
<style>
|
||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||
|
||
:root {
|
||
--gold: #d4af37;
|
||
--gold-dim: #b8962e;
|
||
--navy-deep: #0f1b2d;
|
||
--navy-mid: #16263e;
|
||
--navy-lite: #1e3353;
|
||
--surface: rgba(255,255,255,0.05);
|
||
--border: rgba(255,255,255,0.10);
|
||
--text: #e2e8f0;
|
||
--muted: #94a3b8;
|
||
--sidebar-w: 240px;
|
||
}
|
||
|
||
html, body { height: 100%; }
|
||
|
||
body {
|
||
font-family: 'Segoe UI', Arial, sans-serif;
|
||
background: var(--navy-deep);
|
||
color: var(--text);
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
/* ══ TOP HEADER ══ */
|
||
.top-header {
|
||
background: linear-gradient(90deg, var(--navy-deep) 0%, var(--navy-mid) 100%);
|
||
border-bottom: 2px solid rgba(212,175,55,0.4);
|
||
padding: 14px 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
}
|
||
|
||
.top-header h1 {
|
||
font-size: clamp(1rem, 2.5vw, 1.45rem);
|
||
font-weight: 700;
|
||
letter-spacing: 0.06em;
|
||
color: var(--gold);
|
||
text-shadow: 0 2px 10px rgba(212,175,55,0.3);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* search */
|
||
.search-wrap {
|
||
position: relative;
|
||
flex: 0 1 280px;
|
||
}
|
||
.search-wrap input {
|
||
width: 100%;
|
||
padding: 8px 12px 8px 36px;
|
||
border-radius: 8px;
|
||
border: 1px solid var(--border);
|
||
background: rgba(255,255,255,0.07);
|
||
color: var(--text);
|
||
font-size: 0.875rem;
|
||
outline: none;
|
||
transition: border-color 0.2s;
|
||
}
|
||
.search-wrap input::placeholder { color: var(--muted); }
|
||
.search-wrap input:focus { border-color: rgba(212,175,55,0.55); }
|
||
.search-wrap svg {
|
||
position: absolute;
|
||
left: 10px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: var(--muted);
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* ══ PROPERTY TABS ══ */
|
||
.prop-tabs {
|
||
display: flex;
|
||
background: var(--navy-mid);
|
||
border-bottom: 1px solid var(--border);
|
||
padding: 0 24px;
|
||
}
|
||
.prop-tab {
|
||
padding: 10px 28px;
|
||
font-size: 0.85rem;
|
||
font-weight: 700;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
color: var(--muted);
|
||
cursor: pointer;
|
||
border-bottom: 3px solid transparent;
|
||
transition: color 0.15s, border-color 0.15s;
|
||
user-select: none;
|
||
}
|
||
.prop-tab:hover { color: var(--text); }
|
||
.prop-tab.active {
|
||
color: var(--gold);
|
||
border-bottom-color: var(--gold);
|
||
}
|
||
|
||
/* ══ BODY LAYOUT ══ */
|
||
.layout {
|
||
display: flex;
|
||
flex: 1;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* ══ SIDEBAR ══ */
|
||
.sidebar {
|
||
width: var(--sidebar-w);
|
||
min-width: var(--sidebar-w);
|
||
background: var(--navy-mid);
|
||
border-right: 1px solid var(--border);
|
||
overflow-y: auto;
|
||
padding: 12px 0 24px;
|
||
}
|
||
|
||
.sidebar-group { margin-bottom: 4px; }
|
||
|
||
.sidebar-group-btn {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 9px 16px 9px 20px;
|
||
background: none;
|
||
border: none;
|
||
color: var(--gold);
|
||
font-size: 0.7rem;
|
||
font-weight: 700;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
cursor: pointer;
|
||
text-align: left;
|
||
transition: background 0.15s;
|
||
}
|
||
.sidebar-group-btn:hover { background: rgba(255,255,255,0.04); }
|
||
|
||
.sidebar-group-btn .chevron {
|
||
transition: transform 0.2s;
|
||
flex-shrink: 0;
|
||
}
|
||
.sidebar-group-btn.open .chevron { transform: rotate(90deg); }
|
||
|
||
.sidebar-items {
|
||
display: none;
|
||
flex-direction: column;
|
||
}
|
||
.sidebar-items.open { display: flex; }
|
||
|
||
.dept-btn {
|
||
padding: 8px 16px 8px 32px;
|
||
background: none;
|
||
border: none;
|
||
color: var(--muted);
|
||
font-size: 0.83rem;
|
||
text-align: left;
|
||
cursor: pointer;
|
||
border-left: 3px solid transparent;
|
||
transition: color 0.12s, background 0.12s, border-color 0.12s;
|
||
}
|
||
.dept-btn:hover {
|
||
color: var(--text);
|
||
background: rgba(255,255,255,0.05);
|
||
}
|
||
.dept-btn.active {
|
||
color: var(--gold);
|
||
border-left-color: var(--gold);
|
||
background: rgba(212,175,55,0.08);
|
||
}
|
||
|
||
/* ══ MAIN CONTENT ══ */
|
||
.main {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: 28px 32px 48px;
|
||
}
|
||
|
||
.dept-heading {
|
||
font-size: 1.3rem;
|
||
font-weight: 700;
|
||
color: var(--gold);
|
||
margin-bottom: 20px;
|
||
padding-bottom: 12px;
|
||
border-bottom: 1px solid rgba(212,175,55,0.25);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
.dept-heading span.prop-badge {
|
||
font-size: 0.65rem;
|
||
font-weight: 700;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
padding: 3px 8px;
|
||
border-radius: 4px;
|
||
background: rgba(212,175,55,0.18);
|
||
color: var(--gold);
|
||
border: 1px solid rgba(212,175,55,0.3);
|
||
}
|
||
|
||
/* table */
|
||
.table-wrap {
|
||
overflow-x: auto;
|
||
border-radius: 10px;
|
||
border: 1px solid var(--border);
|
||
}
|
||
|
||
table.dir-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 0.875rem;
|
||
}
|
||
|
||
table.dir-table thead tr {
|
||
background: rgba(212,175,55,0.12);
|
||
border-bottom: 1px solid rgba(212,175,55,0.3);
|
||
}
|
||
table.dir-table thead th {
|
||
padding: 11px 16px;
|
||
text-align: left;
|
||
font-size: 0.7rem;
|
||
font-weight: 700;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
color: var(--gold);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
table.dir-table tbody tr {
|
||
border-bottom: 1px solid var(--border);
|
||
transition: background 0.1s;
|
||
}
|
||
table.dir-table tbody tr:last-child { border-bottom: none; }
|
||
table.dir-table tbody tr:hover { background: rgba(255,255,255,0.04); }
|
||
table.dir-table tbody tr.hidden { display: none; }
|
||
|
||
table.dir-table td {
|
||
padding: 10px 16px;
|
||
color: var(--text);
|
||
white-space: nowrap;
|
||
}
|
||
table.dir-table td:first-child { font-weight: 600; }
|
||
table.dir-table td.ext { font-family: 'Courier New', monospace; color: var(--gold); }
|
||
table.dir-table td.ext-empty { color: var(--muted); font-style: italic; }
|
||
|
||
.no-results {
|
||
text-align: center;
|
||
padding: 48px 16px;
|
||
color: var(--muted);
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.loading {
|
||
text-align: center;
|
||
padding: 48px 16px;
|
||
color: var(--muted);
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
/* ══ QUICK LINKS FOOTER ══ */
|
||
.quick-links {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
justify-content: center;
|
||
padding: 18px 24px;
|
||
background: rgba(0,0,0,0.3);
|
||
border-top: 1px solid rgba(212,175,55,0.2);
|
||
}
|
||
.quick-links a {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 7px;
|
||
padding: 10px 22px;
|
||
border-radius: 7px;
|
||
font-size: 0.82rem;
|
||
font-weight: 700;
|
||
letter-spacing: 0.05em;
|
||
color: var(--navy-deep);
|
||
background: linear-gradient(135deg, var(--gold), var(--gold-dim));
|
||
text-decoration: none;
|
||
transition: opacity 0.15s, transform 0.15s;
|
||
box-shadow: 0 3px 12px rgba(212,175,55,0.3);
|
||
}
|
||
.quick-links a:hover { opacity: 0.85; transform: translateY(-1px); }
|
||
|
||
/* ══ RESPONSIVE ══ */
|
||
@media (max-width: 700px) {
|
||
.sidebar { width: 200px; min-width: 200px; }
|
||
.main { padding: 20px 16px 40px; }
|
||
}
|
||
@media (max-width: 520px) {
|
||
.layout { flex-direction: column; }
|
||
.sidebar { width: 100%; min-width: 0; border-right: none; border-bottom: 1px solid var(--border); max-height: 220px; }
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<!-- ══ TOP HEADER ══ -->
|
||
<header class="top-header">
|
||
<h1>Bossier City Phone Directory</h1>
|
||
<div class="search-wrap">
|
||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
|
||
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
|
||
</svg>
|
||
<input type="search" id="searchInput" placeholder="Search name, title, extension…" autocomplete="off" />
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ══ PROPERTY TABS ══ -->
|
||
<div class="prop-tabs">
|
||
<div class="prop-tab active" data-prop="btbc">Boomtown — BTBC</div>
|
||
<div class="prop-tab" data-prop="mvbc">Margaritaville — MVBC</div>
|
||
</div>
|
||
|
||
<!-- ══ LAYOUT ══ -->
|
||
<div class="layout">
|
||
|
||
<!-- Sidebar -->
|
||
<nav class="sidebar" id="sidebar">
|
||
<!-- rendered by JS -->
|
||
</nav>
|
||
|
||
<!-- Main panel -->
|
||
<main class="main" id="mainPanel">
|
||
<div class="loading">Select a department from the sidebar.</div>
|
||
</main>
|
||
|
||
</div>
|
||
|
||
<!-- ══ QUICK LINKS ══ -->
|
||
<footer class="quick-links">
|
||
<a href="http://mvbc-files/Phone User Guide.pdf">📞 MVBC Quick Phone Reference</a>
|
||
<a href="http://10.3.32.10/ucmuser/main#phonesettings">⚙ MVBC Self Care Portal</a>
|
||
</footer>
|
||
|
||
<script>
|
||
// ─────────────────────────────────────────────
|
||
// DATA MAP – dept label → JSON file path
|
||
// ─────────────────────────────────────────────
|
||
const DEPTS = [
|
||
{
|
||
group: 'Casino Operations',
|
||
items: [
|
||
{ label: 'Casino Operations', btbc: 'json/btbc-casino-ops.json', mvbc: 'json/mvbc-casino-ops.json' },
|
||
{ label: 'Security', btbc: 'json/btbc-security.json', mvbc: 'json/mvbc-security.json' },
|
||
{ label: 'Slots', btbc: 'json/btbc-slots.json', mvbc: 'json/mvbc-slots.json' },
|
||
{ label: 'Slots Performance', btbc: 'json/btbc-slots-performance.json', mvbc: 'json/mvbc-slots-performance.json' },
|
||
{ label: 'Sports Betting', btbc: 'json/btbc-sport-betting.json', mvbc: 'json/mvbc-sport-betting.json' },
|
||
{ label: 'Surveillance', btbc: 'json/btbc-sureillance.json', mvbc: 'json/mvbc-surveillance.json' },
|
||
{ label: 'Table Games', btbc: 'json/btbc-table-games.json', mvbc: 'json/mvbc-table-games.json' },
|
||
]
|
||
},
|
||
{
|
||
group: 'Executive',
|
||
items: [
|
||
{ label: 'Executive', btbc: 'json/btbc-executive.json', mvbc: 'json/mvbc-executive.json' },
|
||
]
|
||
},
|
||
{
|
||
group: 'Finance & Admin',
|
||
items: [
|
||
{ label: 'Accounting', btbc: 'json/btbc-accounting.json', mvbc: 'json/mvbc-accounting.json' },
|
||
{ label: 'Cage', btbc: 'json/btbc-cage.json', mvbc: 'json/mvbc-cage.json' },
|
||
{ label: 'Compliance', btbc: 'json/btbc-compliance.json', mvbc: 'json/mvbc-compliance.json' },
|
||
{ label: 'Count', btbc: 'json/btbc-count.json', mvbc: 'json/mvbc-count.json' },
|
||
{ label: 'Purchasing', btbc: 'json/btbc-purchasing.json', mvbc: 'json/mvbc-purchasing.json' },
|
||
{ label: 'Receiving', btbc: 'json/btbc-receiving.json', mvbc: 'json/mvbc-receiving.json' },
|
||
]
|
||
},
|
||
{
|
||
group: 'Food & Beverage',
|
||
items: [
|
||
{ label: 'Food & Beverage', btbc: 'json/btbc-food-and-beverage.json', mvbc: 'json/mvbc-food-and-beverage.json' },
|
||
]
|
||
},
|
||
{
|
||
group: 'Hotel',
|
||
items: [
|
||
{ label: 'Hotel', btbc: 'json/btbc-hotel.json', mvbc: 'json/mvbc-hotel.json' },
|
||
]
|
||
},
|
||
{
|
||
group: 'Human Resources',
|
||
items: [
|
||
{ label: 'Human Resources', btbc: 'json/btbc-human-resources.json', mvbc: 'json/mvbc-human-resources.json' },
|
||
]
|
||
},
|
||
{
|
||
group: 'Sales & Marketing',
|
||
items: [
|
||
{ label: 'Sales & Marketing', btbc: 'json/btbc-sales-and-marketing.json', mvbc: 'json/mvbc-sales-and-marketing.json' },
|
||
{ label: 'Entertainment', btbc: 'json/btbc-entertainment.json', mvbc: 'json/mvbc-entertainment.json' },
|
||
]
|
||
},
|
||
{
|
||
group: 'Support Services',
|
||
items: [
|
||
{ label: 'Facilities', btbc: 'json/btbc-facilties.json', mvbc: 'json/mvbc-facilties.json' },
|
||
{ label: 'Information Technology', btbc: 'json/btbc-information-technology.json', mvbc: 'json/mvbc-information-technology.json' },
|
||
]
|
||
},
|
||
];
|
||
|
||
// ─────────────────────────────────────────────
|
||
// STATE
|
||
// ─────────────────────────────────────────────
|
||
let currentProp = 'btbc';
|
||
let currentDept = null; // { label, btbc, mvbc }
|
||
let currentData = [];
|
||
|
||
const sidebar = document.getElementById('sidebar');
|
||
const mainPanel = document.getElementById('mainPanel');
|
||
const searchInput = document.getElementById('searchInput');
|
||
|
||
// ─────────────────────────────────────────────
|
||
// RENDER SIDEBAR
|
||
// ─────────────────────────────────────────────
|
||
function renderSidebar() {
|
||
sidebar.innerHTML = '';
|
||
DEPTS.forEach((grp, gi) => {
|
||
const groupEl = document.createElement('div');
|
||
groupEl.className = 'sidebar-group';
|
||
|
||
const btn = document.createElement('button');
|
||
btn.className = 'sidebar-group-btn';
|
||
const hasActive = grp.items.some(it => it === currentDept);
|
||
if (hasActive) btn.classList.add('open');
|
||
btn.innerHTML = `${grp.group} <svg class="chevron" width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="9 18 15 12 9 6"/></svg>`;
|
||
|
||
const itemsEl = document.createElement('div');
|
||
itemsEl.className = 'sidebar-items' + (hasActive ? ' open' : '');
|
||
|
||
grp.items.forEach(dept => {
|
||
const db = document.createElement('button');
|
||
db.className = 'dept-btn' + (dept === currentDept ? ' active' : '');
|
||
db.textContent = dept.label;
|
||
db.addEventListener('click', () => selectDept(dept));
|
||
itemsEl.appendChild(db);
|
||
});
|
||
|
||
btn.addEventListener('click', () => {
|
||
btn.classList.toggle('open');
|
||
itemsEl.classList.toggle('open');
|
||
});
|
||
|
||
groupEl.appendChild(btn);
|
||
groupEl.appendChild(itemsEl);
|
||
sidebar.appendChild(groupEl);
|
||
});
|
||
}
|
||
|
||
// ─────────────────────────────────────────────
|
||
// SELECT DEPARTMENT
|
||
// ─────────────────────────────────────────────
|
||
function selectDept(dept) {
|
||
currentDept = dept;
|
||
searchInput.value = '';
|
||
renderSidebar();
|
||
loadDept();
|
||
}
|
||
|
||
// ─────────────────────────────────────────────
|
||
// LOAD + DISPLAY
|
||
// ─────────────────────────────────────────────
|
||
function loadDept() {
|
||
if (!currentDept) return;
|
||
const jsonPath = currentDept[currentProp];
|
||
mainPanel.innerHTML = '<div class="loading">Loading…</div>';
|
||
|
||
fetch(jsonPath)
|
||
.then(r => {
|
||
if (!r.ok) throw new Error('HTTP ' + r.status);
|
||
return r.json();
|
||
})
|
||
.then(data => {
|
||
currentData = data;
|
||
renderTable(data);
|
||
})
|
||
.catch(() => {
|
||
mainPanel.innerHTML = '<div class="no-results">Could not load data for this department.</div>';
|
||
});
|
||
}
|
||
|
||
function propLabel(prop) {
|
||
return prop === 'btbc' ? 'BTBC' : 'MVBC';
|
||
}
|
||
|
||
function renderTable(data) {
|
||
const q = searchInput.value.trim().toLowerCase();
|
||
const filtered = q
|
||
? data.filter(r =>
|
||
(r.name || '').toLowerCase().includes(q) ||
|
||
(r.title || '').toLowerCase().includes(q) ||
|
||
(r.extension || '').toLowerCase().includes(q) ||
|
||
(r.exterior || '').toLowerCase().includes(q)
|
||
)
|
||
: data;
|
||
|
||
let html = `
|
||
<div class="dept-heading">
|
||
${escHtml(currentDept.label)}
|
||
<span class="prop-badge">${propLabel(currentProp)}</span>
|
||
</div>`;
|
||
|
||
if (filtered.length === 0) {
|
||
html += `<div class="no-results">No results${q ? ' matching "<strong>' + escHtml(q) + '</strong>"' : ''}.</div>`;
|
||
} else {
|
||
html += `
|
||
<div class="table-wrap">
|
||
<table class="dir-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Name</th>
|
||
<th>Title</th>
|
||
<th>Extension</th>
|
||
<th>Exterior</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>`;
|
||
filtered.forEach(r => {
|
||
const ext = (r.extension || '').trim();
|
||
const exr = (r.exterior || '').trim();
|
||
html += `<tr>
|
||
<td>${escHtml(r.name || '')}</td>
|
||
<td>${escHtml(r.title || '')}</td>
|
||
<td class="${ext ? 'ext' : 'ext-empty'}">${ext ? escHtml(ext) : '—'}</td>
|
||
<td class="${exr ? 'ext' : 'ext-empty'}">${exr ? escHtml(exr) : '—'}</td>
|
||
</tr>`;
|
||
});
|
||
html += `</tbody></table></div>`;
|
||
}
|
||
mainPanel.innerHTML = html;
|
||
}
|
||
|
||
function escHtml(s) {
|
||
return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
||
}
|
||
|
||
// ─────────────────────────────────────────────
|
||
// PROPERTY TABS
|
||
// ─────────────────────────────────────────────
|
||
document.querySelectorAll('.prop-tab').forEach(tab => {
|
||
tab.addEventListener('click', () => {
|
||
document.querySelectorAll('.prop-tab').forEach(t => t.classList.remove('active'));
|
||
tab.classList.add('active');
|
||
currentProp = tab.dataset.prop;
|
||
if (currentDept) loadDept();
|
||
});
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// SEARCH
|
||
// ─────────────────────────────────────────────
|
||
searchInput.addEventListener('input', () => {
|
||
if (currentDept && currentData.length) {
|
||
renderTable(currentData);
|
||
}
|
||
});
|
||
|
||
// ─────────────────────────────────────────────
|
||
// INIT – open Casino Operations, load first dept
|
||
// ─────────────────────────────────────────────
|
||
currentDept = DEPTS[0].items[0];
|
||
renderSidebar();
|
||
loadDept();
|
||
</script>
|
||
</body>
|
||
</html>
|