Files
AudioCore/modules/admin/views/installer.php
2026-03-04 22:01:54 +00:00

299 lines
12 KiB
PHP

<?php
$pageTitle = 'Installer';
$step = (int)($step ?? 1);
$values = is_array($values ?? null) ? $values : [];
$smtpResult = is_array($smtp_result ?? null) ? $smtp_result : [];
$checks = is_array($checks ?? null) ? $checks : [];
$val = static function (string $key, string $default = '') use ($values): string {
return (string)($values[$key] ?? $default);
};
ob_start();
?>
<style>
.ac-installer { max-width: 980px; margin: 0 auto; }
.ac-installer-title { margin: 16px 0 6px; font-size: 42px; line-height: 1.05; }
.ac-installer-intro { margin: 0; color: rgba(235,241,255,.75); }
.ac-installer-steps { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.ac-step-pill {
padding: 8px 12px;
border-radius: 999px;
border: 1px solid rgba(255,255,255,.16);
background: rgba(255,255,255,.03);
font-size: 11px;
letter-spacing: .18em;
text-transform: uppercase;
font-family: 'IBM Plex Mono', monospace;
}
.ac-step-pill.is-active { background: rgba(57,244,179,.18); }
.ac-installer-form { margin-top: 18px; display: grid; gap: 14px; }
.ac-installer-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 12px;
}
.ac-installer-section {
margin-top: 6px;
padding-top: 14px;
border-top: 1px solid rgba(255,255,255,.10);
}
.ac-installer label {
display: inline-block;
margin: 0 0 8px;
font-size: 12px;
color: rgba(238,244,255,.78);
text-transform: uppercase;
letter-spacing: .16em;
font-family: 'IBM Plex Mono', monospace;
}
.ac-installer .input,
.ac-installer textarea.input,
.ac-installer select.input {
width: 100%;
height: 46px;
border-radius: 12px;
border: 1px solid rgba(255,255,255,.16);
background: rgba(12,16,24,.58);
color: #edf2ff;
padding: 0 14px;
font-size: 15px;
outline: none;
}
.ac-installer textarea.input {
height: auto;
min-height: 92px;
padding: 12px 14px;
resize: vertical;
}
.ac-installer .input:focus {
border-color: rgba(57,244,179,.55);
box-shadow: 0 0 0 3px rgba(57,244,179,.14);
}
.ac-installer-actions {
display: flex;
justify-content: flex-end;
gap: 10px;
flex-wrap: wrap;
margin-top: 6px;
}
.ac-installer .button {
height: 44px;
border-radius: 999px;
padding: 0 18px;
border: 1px solid rgba(255,255,255,.2);
background: rgba(255,255,255,.04);
color: #eef4ff;
text-transform: uppercase;
letter-spacing: .16em;
font-family: 'IBM Plex Mono', monospace;
font-size: 12px;
font-weight: 600;
cursor: pointer;
}
.ac-installer .button:hover { background: rgba(255,255,255,.1); }
.ac-installer .button-primary {
background: linear-gradient(135deg, #25afff, #2bd8ff);
border-color: rgba(40,185,255,.75);
color: #041019;
}
.ac-installer .button-primary:hover { filter: brightness(1.05); }
.ac-installer-alert {
margin-top: 16px;
border-radius: 12px;
padding: 12px 14px;
}
.ac-installer-alert.error {
border: 1px solid rgba(255,124,124,.45);
background: rgba(180,40,40,.18);
color: #ffd6d6;
}
.ac-installer-alert.success {
border: 1px solid rgba(57,244,179,.45);
background: rgba(10,90,60,.22);
color: #b8ffe5;
}
.ac-installer-checks {
padding: 12px;
border: 1px solid rgba(255,255,255,.1);
border-radius: 12px;
background: rgba(255,255,255,.02);
}
.ac-installer-checks-title {
font-size: 12px;
text-transform: uppercase;
letter-spacing: .16em;
color: rgba(255,255,255,.65);
margin-bottom: 10px;
font-family: 'IBM Plex Mono', monospace;
}
</style>
<section class="card ac-installer">
<div class="badge">Setup</div>
<h1 class="ac-installer-title">AudioCore V1.5 Installer</h1>
<p class="ac-installer-intro">Deploy a fresh instance with validated SMTP and baseline health checks.</p>
<div class="ac-installer-steps">
<div class="ac-step-pill <?= $step === 1 ? 'is-active' : '' ?>">1. Core Setup</div>
<div class="ac-step-pill <?= $step === 2 ? 'is-active' : '' ?>">2. Site + SMTP</div>
</div>
<?php if (!empty($error)): ?>
<div class="ac-installer-alert error"><?= htmlspecialchars((string)$error, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if (!empty($success)): ?>
<div class="ac-installer-alert success"><?= htmlspecialchars((string)$success, ENT_QUOTES, 'UTF-8') ?></div>
<?php endif; ?>
<?php if ($step === 1): ?>
<form method="post" action="/admin/install" class="ac-installer-form">
<input type="hidden" name="installer_action" value="setup_core">
<div class="ac-installer-grid">
<div>
<label>DB Host *</label>
<input class="input" name="db_host" value="<?= htmlspecialchars($val('db_host', 'localhost'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>DB Port *</label>
<input class="input" name="db_port" value="<?= htmlspecialchars($val('db_port', '3306'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>DB Name *</label>
<input class="input" name="db_name" value="<?= htmlspecialchars($val('db_name', ''), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>DB User *</label>
<input class="input" name="db_user" value="<?= htmlspecialchars($val('db_user', ''), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div style="grid-column:1/-1;">
<label>DB Password</label>
<input class="input" type="password" name="db_pass" value="">
</div>
</div>
<div class="ac-installer-section ac-installer-grid">
<div>
<label>Admin Name *</label>
<input class="input" name="admin_name" value="<?= htmlspecialchars($val('admin_name', 'Admin'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>Admin Email *</label>
<input class="input" type="email" name="admin_email" value="<?= htmlspecialchars($val('admin_email', ''), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>Admin Password *</label>
<input class="input" type="password" name="admin_password" value="" placeholder="Minimum 8 characters">
</div>
</div>
<div class="ac-installer-actions">
<button type="submit" class="button button-primary">Create Core Setup</button>
</div>
</form>
<?php else: ?>
<form method="post" action="/admin/install" class="ac-installer-form">
<div class="ac-installer-grid">
<div>
<label>Site Title *</label>
<input class="input" name="site_title" value="<?= htmlspecialchars($val('site_title', 'AudioCore V1.5'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>Site Tagline</label>
<input class="input" name="site_tagline" value="<?= htmlspecialchars($val('site_tagline', 'Core CMS for DJs & Producers'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>SEO Title Suffix</label>
<input class="input" name="seo_title_suffix" value="<?= htmlspecialchars($val('seo_title_suffix', 'AudioCore V1.5'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div style="grid-column:1/-1;">
<label>SEO Meta Description</label>
<textarea class="input" name="seo_meta_description" rows="3"><?= htmlspecialchars($val('seo_meta_description', ''), ENT_QUOTES, 'UTF-8') ?></textarea>
</div>
</div>
<div class="ac-installer-section ac-installer-grid">
<div>
<label>SMTP Host *</label>
<input class="input" name="smtp_host" value="<?= htmlspecialchars($val('smtp_host', ''), ENT_QUOTES, 'UTF-8') ?>" placeholder="smtp.example.com">
</div>
<div>
<label>SMTP Port *</label>
<input class="input" name="smtp_port" value="<?= htmlspecialchars($val('smtp_port', '587'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>SMTP User</label>
<input class="input" name="smtp_user" value="<?= htmlspecialchars($val('smtp_user', ''), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>SMTP Password</label>
<input class="input" type="password" name="smtp_pass" value="<?= htmlspecialchars($val('smtp_pass', ''), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>SMTP Encryption</label>
<input class="input" name="smtp_encryption" value="<?= htmlspecialchars($val('smtp_encryption', 'tls'), ENT_QUOTES, 'UTF-8') ?>" placeholder="tls or ssl">
</div>
<div>
<label>SMTP From Email *</label>
<input class="input" type="email" name="smtp_from_email" value="<?= htmlspecialchars($val('smtp_from_email', ''), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>SMTP From Name</label>
<input class="input" name="smtp_from_name" value="<?= htmlspecialchars($val('smtp_from_name', 'AudioCore V1.5'), ENT_QUOTES, 'UTF-8') ?>">
</div>
<div>
<label>Test Recipient Email *</label>
<input class="input" type="email" name="smtp_test_email" value="<?= htmlspecialchars($val('smtp_test_email', ''), ENT_QUOTES, 'UTF-8') ?>">
</div>
</div>
<?php if (!empty($smtpResult)): ?>
<div class="ac-installer-alert <?= !empty($smtpResult['ok']) ? 'success' : 'error' ?>" style="margin-top:0;">
<div style="font-weight:700; margin-bottom:4px;">
<?= !empty($smtpResult['ok']) ? 'SMTP test passed' : 'SMTP test failed' ?>
</div>
<div><?= htmlspecialchars((string)($smtpResult['message'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
<?php if (!empty($smtpResult['debug'])): ?>
<details style="margin-top:8px;">
<summary style="cursor:pointer;">Debug output</summary>
<pre style="white-space:pre-wrap; margin-top:8px; font-size:12px; color:#cfd6f5;"><?= htmlspecialchars((string)$smtpResult['debug'], ENT_QUOTES, 'UTF-8') ?></pre>
</details>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if (!empty($checks)): ?>
<div class="ac-installer-checks">
<div class="ac-installer-checks-title">Installer Health Checks</div>
<div style="display:grid; gap:8px;">
<?php foreach ($checks as $check): ?>
<div style="display:flex; gap:10px; align-items:flex-start;">
<span style="display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:999px; font-size:12px; margin-top:2px; background:<?= !empty($check['ok']) ? 'rgba(57,244,179,.2)' : 'rgba(255,124,124,.2)' ?>; color:<?= !empty($check['ok']) ? '#9ff8d8' : '#ffb7b7' ?>;">
<?= !empty($check['ok']) ? '&#10003;' : '!' ?>
</span>
<div>
<div style="font-weight:600;"><?= htmlspecialchars((string)($check['label'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
<div style="color:rgba(235,241,255,.65); font-size:13px;"><?= htmlspecialchars((string)($check['detail'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<div class="ac-installer-actions">
<button type="submit" name="installer_action" value="test_smtp" class="button">Send Test Email + Run Checks</button>
<button type="submit" name="installer_action" value="finish_install" class="button button-primary">Finish Installation</button>
</div>
</form>
<?php endif; ?>
</section>
<?php
$content = ob_get_clean();
require __DIR__ . '/../../../views/site/layout.php';