Files
kane-diagnostics/hubzilla/addon/scn01/scn01_renderer.php
2026-06-13 10:22:58 -04:00

133 lines
5.8 KiB
PHP

<?php
/**
* SCN-01 Renderer
* Renders the scenario browse carousel and submission form.
* Carousel/pin interaction is client-side — see view/js/scn01.js.
*/
// ---------------------------------------------------------------------------
// SCENARIOS LOADING
// ---------------------------------------------------------------------------
function scn01_load_scenarios() {
$raw = @file_get_contents('addon/scn01/scenarios.json');
if ($raw === false) return [];
$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) return [];
return $data['scenarios'] ?? [];
}
// ---------------------------------------------------------------------------
// RENDER — INDEX (association picker)
// ---------------------------------------------------------------------------
function scn01_render_index() {
$out = '<div class="scn01-content">';
$out .= '<div class="scn01-header mb-3">';
$out .= '<h2>Scenarios</h2>';
$out .= '<p class="text-muted">Browse examples of situations other homeowners have experienced. When something looks familiar, select it and describe your own situation in your own words.</p>';
$out .= '</div>';
$raw = @file_get_contents('addon/vs01/config.json');
$cfg = $raw ? json_decode($raw, true) : [];
$associations = $cfg['associations'] ?? [];
if (!empty($associations)) {
$out .= '<ul class="list-group">';
foreach ($associations as $slug => $assoc) {
$name = scn01_h($assoc['name'] ?? $slug);
$url = z_root() . '/scn01/' . scn01_h($slug);
$out .= '<li class="list-group-item"><a href="' . $url . '">' . $name . '</a></li>';
}
$out .= '</ul>';
} else {
$out .= '<div class="scn01-placeholder text-muted fst-italic">No associations registered.</div>';
}
$out .= '</div>';
return $out;
}
// ---------------------------------------------------------------------------
// RENDER — ASSOCIATION LANDING (carousel + form)
// ---------------------------------------------------------------------------
function scn01_render_landing($association_slug, $access) {
$raw = @file_get_contents('addon/vs01/config.json');
$cfg = $raw ? json_decode($raw, true) : [];
$assoc = $cfg['associations'][$association_slug] ?? [];
$name = scn01_h($assoc['name'] ?? $association_slug);
$scenarios = scn01_load_scenarios();
$out = '<div class="scn01-content">';
$out .= '<div class="scn01-header mb-3">';
$out .= '<h2>' . $name . '</h2>';
$out .= '<p class="text-muted">Browse the scenarios below. Select up to 5 that feel similar to your situation, then describe what happened in your own words.</p>';
$out .= '</div>';
// Data island — consumed entirely by scn01.js, no PHP logic beyond this.
$out .= '<script type="application/json" id="scn01-data">'
. json_encode(['scenarios' => $scenarios], JSON_UNESCAPED_SLASHES)
. '</script>';
if ($access === 'public') {
// Public — show carousel + pinned strip read-only (no form)
$out .= '<div class="scn01-narrative">';
$out .= '<label for="scn01_narrative"><strong>Describe your situation</strong></label>';
$out .= '<textarea id="scn01_narrative" class="form-control" rows="6" placeholder="In your own words, describe what happened." disabled></textarea>';
$out .= '</div>';
$out .= '<div class="scn01-carousel mt-3">';
$out .= '<button type="button" id="scn01-prev" class="btn btn-sm btn-outline-secondary" aria-label="Previous scenario">&larr;</button>';
$out .= '<div id="scn01-card" class="scn01-card"></div>';
$out .= '<button type="button" id="scn01-next" class="btn btn-sm btn-outline-secondary" aria-label="Next scenario">&rarr;</button>';
$out .= '</div>';
$out .= '<div id="scn01-pinned" class="scn01-pinned" aria-label="Pinned scenarios"></div>';
$out .= '<div class="alert alert-info mt-3">';
$out .= 'Scenarios are public. ';
$out .= '<a href="https://directory.diagnostics.kane-il.us/channel/theron">Complete the SASE process</a> ';
$out .= 'to submit your own account for this association.';
$out .= '</div>';
$out .= '</div>';
return $out;
}
$form_url = z_root() . '/scn01/' . scn01_h($association_slug);
$out .= '<form method="post" action="' . $form_url . '" id="scn01-form" class="scn01-form" novalidate>';
$out .= scn01_csrf_token();
// Narrative textarea — above the carousel
$out .= '<div class="scn01-narrative">';
$out .= '<label for="scn01_narrative"><strong>Describe your situation</strong></label>';
$out .= '<textarea id="scn01_narrative" name="narrative" class="form-control" rows="6" placeholder="In your own words, describe what happened."></textarea>';
$out .= '</div>';
// Carousel
$out .= '<div class="scn01-carousel mt-3">';
$out .= '<button type="button" id="scn01-prev" class="btn btn-sm btn-outline-secondary" aria-label="Previous scenario">&larr;</button>';
$out .= '<div id="scn01-card" class="scn01-card"></div>';
$out .= '<button type="button" id="scn01-next" class="btn btn-sm btn-outline-secondary" aria-label="Next scenario">&rarr;</button>';
$out .= '</div>';
// Pinned strip — stacked below the carousel
$out .= '<div id="scn01-pinned" class="scn01-pinned" aria-label="Pinned scenarios"></div>';
$out .= '<div id="scn01-pinned-fields"></div>';
$out .= '<div class="alert alert-warning mt-2 small">';
$out .= 'Once submitted, this record cannot be edited. If you want to add more later, you will need to submit a new record.';
$out .= '</div>';
$out .= '<div class="mt-2">';
$out .= '<button type="submit" class="btn btn-primary">Submit</button>';
$out .= '</div>';
$out .= '</form>';
$out .= '</div>';
return $out;
}