BossierCityPhoneBooks/mvbc-files.html

588 lines
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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 &mdash; BTBC</div>
<div class="prop-tab" data-prop="mvbc">Margaritaville &mdash; 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">&#128222; MVBC Quick Phone Reference</a>
<a href="http://10.3.32.10/ucmuser/main#phonesettings">&#9881; 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&hellip;</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,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
// ─────────────────────────────────────────────
// 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>