add all files

This commit is contained in:
Rucus
2026-02-17 09:29:34 -06:00
parent b8c8d67c67
commit 782d203799
21925 changed files with 2433086 additions and 0 deletions

View File

@@ -0,0 +1,685 @@
<?php // phpcs:ignoreFile
/**
* Alerts Admin - Manage alert definitions
*/
require __DIR__ . '/session.php';
require __DIR__ . '/userAccess.php';
// Only allow admin or controls
if ($_SESSION['SESS_MEMBER_LEVEL'] < 4) {
header("Location: access-denied.php");
exit();
}
$alertsConn = mysqli_connect('192.168.0.16', 'lasucaai', 'is413#dfslw', 'controls');
if (!$alertsConn) {
die("Connection failed: " . mysqli_connect_error());
}
mysqli_set_charset($alertsConn, 'utf8mb4');
// Create alert_definitions table if not exists
$createTable = "CREATE TABLE IF NOT EXISTS alert_definitions (
id INT AUTO_INCREMENT PRIMARY KEY,
tag_name VARCHAR(100) NOT NULL,
alert_type ENUM('danger', 'warning', 'info') DEFAULT 'warning',
comparison ENUM('<', '>', '<=', '>=', '=', '!=') DEFAULT '<',
threshold_value DECIMAL(18,4) NOT NULL,
duration_seconds INT DEFAULT 0,
message_template VARCHAR(255) NOT NULL,
icon VARCHAR(10) DEFAULT '⚠️',
is_active TINYINT(1) DEFAULT 1,
display_alert TINYINT(1) DEFAULT 1,
created_by VARCHAR(100) NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_tag_name (tag_name),
INDEX idx_is_active (is_active)
)";
mysqli_query($alertsConn, $createTable);
$message = '';
$messageType = '';
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
switch ($action) {
case 'add':
$tagName = trim($_POST['tag_name'] ?? '');
$alertType = $_POST['alert_type'] ?? 'warning';
$comparison = $_POST['comparison'] ?? '<';
$threshold = floatval($_POST['threshold_value'] ?? 0);
$duration = intval($_POST['duration_seconds'] ?? 0);
$messageTemplate = trim($_POST['message_template'] ?? '');
$icon = trim($_POST['icon'] ?? '⚠️');
$displayAlert = isset($_POST['display_alert']) ? 1 : 0;
$createdBy = $_SESSION['SESS_FIRST_NAME'] ?? 'Unknown';
if ($tagName && $messageTemplate) {
$stmt = mysqli_prepare($alertsConn,
"INSERT INTO alert_definitions
(tag_name, alert_type, comparison, threshold_value, duration_seconds,
message_template, icon, display_alert, created_by)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
);
mysqli_stmt_bind_param($stmt, 'sssdissis',
$tagName, $alertType, $comparison, $threshold, $duration,
$messageTemplate, $icon, $displayAlert, $createdBy
);
if (mysqli_stmt_execute($stmt)) {
$message = "Alert added successfully!";
$messageType = 'success';
} else {
$message = "Error adding alert: " . mysqli_error($alertsConn);
$messageType = 'error';
}
mysqli_stmt_close($stmt);
} else {
$message = "Tag name and message are required.";
$messageType = 'error';
}
break;
case 'update':
$id = intval($_POST['id'] ?? 0);
$tagName = trim($_POST['tag_name'] ?? '');
$alertType = $_POST['alert_type'] ?? 'warning';
$comparison = $_POST['comparison'] ?? '<';
$threshold = floatval($_POST['threshold_value'] ?? 0);
$duration = intval($_POST['duration_seconds'] ?? 0);
$messageTemplate = trim($_POST['message_template'] ?? '');
$icon = trim($_POST['icon'] ?? '⚠️');
$isActive = isset($_POST['is_active']) ? 1 : 0;
$displayAlert = isset($_POST['display_alert']) ? 1 : 0;
if ($id && $tagName && $messageTemplate) {
$stmt = mysqli_prepare($alertsConn,
"UPDATE alert_definitions SET
tag_name = ?, alert_type = ?, comparison = ?, threshold_value = ?,
duration_seconds = ?, message_template = ?, icon = ?,
is_active = ?, display_alert = ?
WHERE id = ?"
);
mysqli_stmt_bind_param($stmt, 'sssdiasiii',
$tagName, $alertType, $comparison, $threshold, $duration,
$messageTemplate, $icon, $isActive, $displayAlert, $id
);
if (mysqli_stmt_execute($stmt)) {
$message = "Alert updated successfully!";
$messageType = 'success';
} else {
$message = "Error updating alert: " . mysqli_error($alertsConn);
$messageType = 'error';
}
mysqli_stmt_close($stmt);
}
break;
case 'delete':
$id = intval($_POST['id'] ?? 0);
if ($id) {
$stmt = mysqli_prepare($alertsConn, "DELETE FROM alert_definitions WHERE id = ?");
mysqli_stmt_bind_param($stmt, 'i', $id);
if (mysqli_stmt_execute($stmt)) {
$message = "Alert deleted!";
$messageType = 'success';
} else {
$message = "Error deleting alert.";
$messageType = 'error';
}
mysqli_stmt_close($stmt);
}
break;
case 'toggle':
$id = intval($_POST['id'] ?? 0);
if ($id) {
mysqli_query($alertsConn, "UPDATE alert_definitions SET is_active = NOT is_active WHERE id = $id");
$message = "Alert toggled!";
$messageType = 'success';
}
break;
}
}
// Fetch all alerts
$alerts = [];
$result = mysqli_query($alertsConn, "SELECT * FROM alert_definitions ORDER BY is_active DESC, tag_name ASC");
while ($row = mysqli_fetch_assoc($result)) {
$alerts[] = $row;
}
// Fetch available tags for autocomplete
$tags = [];
$tagResult = mysqli_query($alertsConn, "SELECT DISTINCT Name FROM items ORDER BY Name");
while ($row = mysqli_fetch_assoc($tagResult)) {
$tags[] = $row['Name'];
}
// Layout config
$layoutWithoutSidebar = true;
$layoutReturnUrl = 'overview.php';
$layoutReturnLabel = 'Back to overview';
$assetBasePath = '';
include __DIR__ . '/includes/layout/header.php';
?>
<style>
.admin-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
h1 {
color: var(--text);
margin-bottom: 20px;
font-size: 1.5rem;
}
.message {
padding: 12px 16px;
border-radius: 6px;
margin-bottom: 20px;
}
.message.success {
background: rgba(76, 175, 80, 0.2);
border: 1px solid #4caf50;
color: #4caf50;
}
.message.error {
background: rgba(244, 67, 54, 0.2);
border: 1px solid #f44336;
color: #f44336;
}
.add-form {
background: var(--surface);
border-radius: 8px;
padding: 20px;
margin-bottom: 30px;
border: 1px solid var(--border);
}
.add-form h2 {
color: var(--text);
font-size: 1.1rem;
margin-bottom: 15px;
}
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 5px;
}
.form-group.full-width {
grid-column: 1 / -1;
}
.form-group label {
font-size: 0.8rem;
color: var(--text-muted, #888);
}
.form-group input,
.form-group select {
background: var(--surface-alt, #2a2a4a);
border: 1px solid var(--border);
border-radius: 4px;
padding: 8px 12px;
color: var(--text);
font-size: 0.9rem;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: var(--accent);
}
.form-actions {
margin-top: 15px;
display: flex;
gap: 10px;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
transition: opacity 0.2s;
}
.btn:hover {
opacity: 0.8;
}
.btn-primary {
background: var(--accent, #3b82f6);
color: #fff;
}
.btn-danger {
background: #f44336;
color: #fff;
}
.btn-secondary {
background: #666;
color: #fff;
}
.btn-sm {
padding: 4px 10px;
font-size: 0.8rem;
}
.alerts-table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
}
.alerts-table th,
.alerts-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid var(--border);
}
.alerts-table th {
background: var(--surface-alt, #2a2a4a);
color: var(--text);
font-weight: 600;
font-size: 0.8rem;
text-transform: uppercase;
}
.alerts-table tr:hover {
background: rgba(255, 255, 255, 0.03);
}
.alerts-table tr.inactive {
opacity: 0.5;
}
.tag-badge {
font-family: monospace;
background: var(--surface-alt, #2a2a4a);
padding: 4px 8px;
border-radius: 4px;
font-size: 0.85rem;
}
.type-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
font-size: 0.75rem;
font-weight: 600;
}
.type-badge.danger {
background: rgba(244, 67, 54, 0.2);
color: #f44336;
}
.type-badge.warning {
background: rgba(255, 152, 0, 0.2);
color: #ff9800;
}
.type-badge.info {
background: rgba(33, 150, 243, 0.2);
color: #2196f3;
}
.condition-cell {
font-family: monospace;
font-size: 0.85rem;
}
.actions-cell {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.status-toggle {
cursor: pointer;
}
.edit-row {
display: none;
background: var(--surface-alt, #2a2a4a);
}
.edit-row.active {
display: table-row;
}
.edit-form {
padding: 15px;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 8px;
}
.checkbox-group input[type="checkbox"] {
width: 18px;
height: 18px;
}
.help-text {
font-size: 0.75rem;
color: var(--text-muted, #666);
margin-top: 3px;
}
</style>
<div class="admin-container">
<h1>🔔 Alerts Admin</h1>
<?php if ($message): ?>
<div class="message <?= $messageType ?>"><?= htmlspecialchars($message) ?></div>
<?php endif; ?>
<!-- Add New Alert Form -->
<div class="add-form">
<h2> Add New Alert</h2>
<form method="POST">
<input type="hidden" name="action" value="add">
<div class="form-grid">
<div class="form-group">
<label>Tag Name</label>
<input type="text" name="tag_name" list="tag-list" required
placeholder="e.g., HouseAirPressure">
<datalist id="tag-list">
<?php foreach ($tags as $tag): ?>
<option value="<?= htmlspecialchars($tag) ?>">
<?php endforeach; ?>
</datalist>
</div>
<div class="form-group">
<label>Alert Type</label>
<select name="alert_type">
<option value="danger">🔴 Danger (Red)</option>
<option value="warning" selected>🟠 Warning (Orange)</option>
<option value="info">🔵 Info (Log only)</option>
</select>
</div>
<div class="form-group">
<label>Comparison</label>
<select name="comparison">
<option value="<">Less than (&lt;)</option>
<option value="<=">Less or equal (≤)</option>
<option value=">">Greater than (&gt;)</option>
<option value=">=">Greater or equal (≥)</option>
<option value="=">Equal to (=)</option>
<option value="!=">Not equal (≠)</option>
</select>
</div>
<div class="form-group">
<label>Threshold Value</label>
<input type="number" name="threshold_value" step="0.0001" required
placeholder="e.g., 75">
</div>
<div class="form-group">
<label>Duration (seconds)</label>
<input type="number" name="duration_seconds" value="0" min="0">
<div class="help-text">0 = trigger immediately</div>
</div>
<div class="form-group">
<label>Icon</label>
<select name="icon">
<option value="⚠️">⚠️ Warning</option>
<option value="🔴">🔴 Red Circle</option>
<option value="🚨">🚨 Siren</option>
<option value="⛔">⛔ Stop</option>
<option value="🔥">🔥 Fire</option>
<option value="❄️">❄️ Cold</option>
<option value="💧">💧 Water</option>
<option value="⚡">⚡ Electric</option>
<option value="🛑">🛑 Stop Sign</option>
<option value=""> Info</option>
</select>
</div>
<div class="form-group full-width">
<label>Message Template</label>
<input type="text" name="message_template" required
placeholder="e.g., LOW PRESSURE: {value} PSI (Threshold: {threshold})">
<div class="help-text">Use {value} for current value, {threshold} for threshold</div>
</div>
<div class="form-group">
<label>&nbsp;</label>
<div class="checkbox-group">
<input type="checkbox" name="display_alert" id="display_alert_new" checked>
<label for="display_alert_new">Display on page</label>
</div>
<div class="help-text">Unchecked = log only</div>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Add Alert</button>
</div>
</form>
</div>
<!-- Existing Alerts Table -->
<h2 style="color: var(--text); margin-bottom: 15px;">📋 Active Alerts (<?= count($alerts) ?>)</h2>
<?php if (empty($alerts)): ?>
<p style="color: var(--text-muted);">No alerts defined yet. Add one above!</p>
<?php else: ?>
<table class="alerts-table">
<thead>
<tr>
<th>Tag</th>
<th>Type</th>
<th>Condition</th>
<th>Duration</th>
<th>Message</th>
<th>Display</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($alerts as $alert): ?>
<tr class="<?= $alert['is_active'] ? '' : 'inactive' ?>" id="row-<?= $alert['id'] ?>">
<td><span class="tag-badge"><?= htmlspecialchars($alert['tag_name']) ?></span></td>
<td>
<span class="type-badge <?= $alert['alert_type'] ?>">
<?= $alert['icon'] ?> <?= strtoupper($alert['alert_type']) ?>
</span>
</td>
<td class="condition-cell">
<?= htmlspecialchars($alert['comparison']) ?> <?= $alert['threshold_value'] ?>
</td>
<td><?= $alert['duration_seconds'] ?>s</td>
<td style="max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
<?= htmlspecialchars($alert['message_template']) ?>
</td>
<td><?= $alert['display_alert'] ? '✅' : '📝' ?></td>
<td>
<form method="POST" style="display: inline;">
<input type="hidden" name="action" value="toggle">
<input type="hidden" name="id" value="<?= $alert['id'] ?>">
<button type="submit" class="btn btn-sm <?= $alert['is_active'] ? 'btn-primary' : 'btn-secondary' ?>">
<?= $alert['is_active'] ? 'ON' : 'OFF' ?>
</button>
</form>
</td>
<td>
<div class="actions-cell">
<button type="button" class="btn btn-sm btn-secondary"
onclick="toggleEdit(<?= $alert['id'] ?>)">Edit</button>
<form method="POST" style="display: inline;"
onsubmit="return confirm('Delete this alert?');">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= $alert['id'] ?>">
<button type="submit" class="btn btn-sm btn-danger">×</button>
</form>
</div>
</td>
</tr>
<tr class="edit-row" id="edit-<?= $alert['id'] ?>">
<td colspan="8">
<form method="POST" class="edit-form">
<input type="hidden" name="action" value="update">
<input type="hidden" name="id" value="<?= $alert['id'] ?>">
<div class="form-grid">
<div class="form-group">
<label>Tag Name</label>
<input type="text" name="tag_name" list="tag-list" required
value="<?= htmlspecialchars($alert['tag_name']) ?>">
</div>
<div class="form-group">
<label>Alert Type</label>
<select name="alert_type">
<option value="danger" <?= $alert['alert_type'] === 'danger' ? 'selected' : '' ?>>
🔴 Danger
</option>
<option value="warning" <?= $alert['alert_type'] === 'warning' ? 'selected' : '' ?>>
🟠 Warning
</option>
<option value="info" <?= $alert['alert_type'] === 'info' ? 'selected' : '' ?>>
🔵 Info
</option>
</select>
</div>
<div class="form-group">
<label>Comparison</label>
<select name="comparison">
<option value="<" <?= $alert['comparison'] === '<' ? 'selected' : '' ?>>
Less than (&lt;)
</option>
<option value="<=" <?= $alert['comparison'] === '<=' ? 'selected' : '' ?>>
Less or equal (≤)
</option>
<option value=">" <?= $alert['comparison'] === '>' ? 'selected' : '' ?>>
Greater than (&gt;)
</option>
<option value=">=" <?= $alert['comparison'] === '>=' ? 'selected' : '' ?>>
Greater or equal (≥)
</option>
<option value="=" <?= $alert['comparison'] === '=' ? 'selected' : '' ?>>
Equal to (=)
</option>
<option value="!=" <?= $alert['comparison'] === '!=' ? 'selected' : '' ?>>
Not equal (≠)
</option>
</select>
</div>
<div class="form-group">
<label>Threshold</label>
<input type="number" name="threshold_value" step="0.0001" required
value="<?= $alert['threshold_value'] ?>">
</div>
<div class="form-group">
<label>Duration (sec)</label>
<input type="number" name="duration_seconds" min="0"
value="<?= $alert['duration_seconds'] ?>">
</div>
<div class="form-group">
<label>Icon</label>
<select name="icon">
<?php
$icons = ['⚠️', '🔴', '🚨', '⛔', '🔥', '❄️', '💧', '⚡', '🛑', ''];
foreach ($icons as $ico):
?>
<option value="<?= $ico ?>" <?= $alert['icon'] === $ico ? 'selected' : '' ?>>
<?= $ico ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group full-width">
<label>Message Template</label>
<input type="text" name="message_template" required
value="<?= htmlspecialchars($alert['message_template']) ?>">
</div>
<div class="form-group">
<div class="checkbox-group">
<input type="checkbox" name="is_active"
id="active-<?= $alert['id'] ?>"
<?= $alert['is_active'] ? 'checked' : '' ?>>
<label for="active-<?= $alert['id'] ?>">Active</label>
</div>
</div>
<div class="form-group">
<div class="checkbox-group">
<input type="checkbox" name="display_alert"
id="display-<?= $alert['id'] ?>"
<?= $alert['display_alert'] ? 'checked' : '' ?>>
<label for="display-<?= $alert['id'] ?>">Display on page</label>
</div>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Save Changes</button>
<button type="button" class="btn btn-secondary"
onclick="toggleEdit(<?= $alert['id'] ?>)">Cancel</button>
</div>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<script>
function toggleEdit(id) {
const editRow = document.getElementById('edit-' + id);
editRow.classList.toggle('active');
}
</script>
<?php
mysqli_close($alertsConn);
include __DIR__ . '/includes/layout/footer.php';
?>