- config.php: Azure tenant/client constants, SSO_ENABLED = true
- auth.php: requireAuth() middleware, getSafeUser(), getUserDataFile()
- auth_gate.php: MSAL.js PKCE login flow, stores return URL in sessionStorage
- logout.php: destroys PHP session + calls msalInstance.logoutRedirect()
- api.php: public create_session endpoint (JWT validation), 401 guard on all other actions, per-user data files (data_{safeUser}.json)
- sheet_helpers.php: fix dot sanitisation '_' → '_dot_' to match getSafeUser()
- index/builder/help.php: requireAuth() at top, user email + Sign Out in header
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
121 lines
6 KiB
PHP
121 lines
6 KiB
PHP
<?php require_once __DIR__ . '/auth.php'; requireAuth(); ?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Dow Jones Job Naming Tool</title>
|
|
<link rel="stylesheet" href="style.css">
|
|
|
|
<!-- Jspreadsheet & Jsuites -->
|
|
<script src="https://jsuites.net/v4/jsuites.js"></script>
|
|
<script src="https://bossanova.uk/jspreadsheet/v4/jexcel.js"></script>
|
|
<link rel="stylesheet" href="https://jsuites.net/v4/jsuites.css" type="text/css" />
|
|
<link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v4/jexcel.css" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header style="display: flex; justify-content: space-between; align-items: center;">
|
|
<div>
|
|
<h1>DOW JONES JOB NAMING TOOL</h1>
|
|
<p style="color: var(--text-secondary);">Generate job names using the Dow Jones naming convention</p>
|
|
</div>
|
|
<div style="display: flex; gap: 10px; align-items: center;">
|
|
<span style="font-size: 0.8rem; color: var(--text-secondary);"><?php echo htmlspecialchars($CURRENT_USER); ?></span>
|
|
<a href="builder.php" class="btn btn-primary" style="text-decoration: none;">Builder / Decoder</a>
|
|
<a href="help.php" class="btn btn-secondary" style="text-decoration: none;">Help</a>
|
|
<a href="logout.php" class="btn btn-secondary" style="text-decoration: none;">Sign Out</a>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="command-bar-container">
|
|
<div class="input-group">
|
|
<input type="text" id="commandInput" placeholder='Try: "Create 5 jobs for PMKT ACQ WSJ, initiative BIC, year 26"' autocomplete="off">
|
|
<button id="micBtn" class="btn btn-icon" title="Speak">🎤</button>
|
|
<button id="sendBtn" class="btn btn-primary">Send</button>
|
|
</div>
|
|
|
|
<div style="display: flex; align-items: center; gap: 10px; margin-top: 10px;">
|
|
<label class="switch">
|
|
<input type="checkbox" id="yoloToggle">
|
|
<span class="slider round"></span>
|
|
</label>
|
|
<span style="font-weight: bold; color: var(--text-color);">YOLO Mode</span>
|
|
<span style="font-size: 0.8em; color: #888;">(Skip clarifying questions)</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Starters -->
|
|
<div class="quick-starters">
|
|
<span style="color: var(--text-secondary); font-size: 0.85rem; margin-right: 10px;">Try:</span>
|
|
<button class="starter-chip" onclick="fillCommand('Create 3 jobs for PMKT ACQ WSJ, initiative BIC, year 26')">PMKT Acquisition</button>
|
|
<button class="starter-chip" onclick="fillCommand('Create 2 event jobs for Global Food Forum, year 26')">Event - GFF</button>
|
|
<button class="starter-chip" onclick="fillCommand('Create 4 B2B Enterprise jobs for Factiva, initiative demo, year 26')">B2B Enterprise</button>
|
|
</div>
|
|
|
|
<div class="toolbar">
|
|
<div style="display: flex; gap: 15px; align-items: center;">
|
|
<label style="font-weight: 600;">Campaign:</label>
|
|
<input type="text" id="campaignName" placeholder="e.g., q1-2026" style="padding: 8px; width: 150px; border: 1px solid var(--border-color); border-radius: 4px;">
|
|
</div>
|
|
<div style="display: flex; gap: 10px;">
|
|
<button id="loadCampaignBtn" class="btn btn-secondary">Load Campaign</button>
|
|
<button id="saveCampaignBtn" class="btn btn-primary">Save Campaign</button>
|
|
<button id="exportBtn" class="btn btn-secondary">Export CSV</button>
|
|
<button id="copyFilenamesBtn" class="btn btn-secondary">Copy Filenames</button>
|
|
<button id="clearSheetBtn" class="btn btn-danger">Clear All</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-container">
|
|
<div id="spreadsheet"></div>
|
|
</div>
|
|
|
|
<!-- AI Activity Log -->
|
|
<div class="ai-log">
|
|
<div class="ai-log-header" style="cursor: pointer;" onclick="document.getElementById('aiOutput').classList.toggle('collapsed'); this.querySelector('.collapse-icon').textContent = document.getElementById('aiOutput').classList.contains('collapsed') ? '>' : 'v';">
|
|
<h3><span class="collapse-icon">v</span> AI ACTIVITY LOG</h3>
|
|
<button id="clearLogBtn" class="btn btn-secondary" style="padding: 6px 12px; font-size: 0.85rem;" onclick="event.stopPropagation();">Clear Log</button>
|
|
</div>
|
|
<div id="aiOutput" class="ai-output">Waiting for command...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function fillCommand(text) {
|
|
const input = document.getElementById('commandInput');
|
|
input.value = text;
|
|
input.focus();
|
|
}
|
|
</script>
|
|
|
|
<div id="loadingOverlay">
|
|
<div class="spinner"></div>
|
|
</div>
|
|
|
|
<!-- AI Question Modal -->
|
|
<div id="aiQuestionModal" class="modal-overlay">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h3>AI Needs Clarification</h3>
|
|
<button class="close-modal-btn" onclick="closeAiModal()">x</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p id="aiQuestionText" class="ai-question-text"></p>
|
|
|
|
<div class="modal-input-group">
|
|
<input type="text" id="aiModalInput" placeholder="Type your answer..." autocomplete="off">
|
|
<button id="aiModalMicBtn" class="btn btn-icon" title="Speak">🎤</button>
|
|
</div>
|
|
|
|
<div class="modal-actions">
|
|
<button id="aiModalSendBtn" class="btn btn-primary">Send Answer</button>
|
|
<button id="aiModalYoloBtn" class="btn btn-secondary">Do what you think (YOLO)</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="script.js"></script>
|
|
</body>
|
|
</html>
|