new-site/site/src/components/intake/steps/WirelessStep.astro
justin f8cd37ac8c Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 06:54:22 -05:00

112 lines
4.8 KiB
Text

---
// WirelessStep — spectrum / MVNO host / subscriber counts / roaming.
// Inserted into the wizard when line_105_categories contains 'wireless'.
---
<div class="pw-step">
<h2>Wireless carrier details</h2>
<p class="pw-help">
Wireless-specific intake for Form 499-A Lines 309 / 409 / 410 (mobile
revenue to resellers, end-user mobile monthly, roaming + usage) and
for the wireless CPNI template.
</p>
<label class="pw-field">Infrastructure</label>
<select id="pw-wl-infra" class="pw-input">
<option value="facilities">Facilities-based (own spectrum / towers)</option>
<option value="mvno">MVNO (use another carrier's network)</option>
</select>
<div id="pw-wl-mvno-wrap" hidden>
<label class="pw-field">Host MNO</label>
<select id="pw-wl-host" class="pw-input">
<option value="">—</option>
<option value="T-Mobile">T-Mobile</option>
<option value="Verizon">Verizon</option>
<option value="AT&T">AT&T</option>
<option value="Dish">Dish / Boost</option>
<option value="US Cellular">US Cellular</option>
</select>
</div>
<div id="pw-wl-fac-wrap">
<label class="pw-field">Spectrum bands (one per line)</label>
<textarea id="pw-wl-bands" class="pw-input" rows="3"
placeholder="e.g., Lower 700 MHz&#10;PCS 1900&#10;CBRS 3.5 GHz"></textarea>
<label class="pw-field">Cell site count</label>
<input type="number" id="pw-wl-sites" class="pw-input" min="0" />
</div>
<div class="pw-row">
<div><label class="pw-field">Post-paid subscribers</label>
<input type="number" id="pw-wl-post" class="pw-input" min="0" /></div>
<div><label class="pw-field">Pre-paid subscribers</label>
<input type="number" id="pw-wl-pre" class="pw-input" min="0" /></div>
</div>
<div class="pw-row">
<div><label class="pw-field">Inbound roaming MOUs</label>
<input type="number" id="pw-wl-roam-mou" class="pw-input" min="0" /></div>
<div><label class="pw-field">Inbound roaming revenue (USD)</label>
<input type="number" step="0.01" id="pw-wl-roam-rev" class="pw-input" min="0" /></div>
</div>
</div>
<style>
.pw-step h2 { margin: 0 0 0.5rem; color: #1a2744; }
.pw-help { color: #64748b; font-size: 0.9rem; margin-bottom: 1rem; }
.pw-field { display: block; font-weight: 600; color: #1f2937; margin: 0.6rem 0 0.2rem; font-size: 0.88rem; }
.pw-input { width: 100%; padding: 0.5rem 0.7rem; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.93rem; font-family: inherit; }
.pw-row { display: flex; gap: 1rem; flex-wrap: wrap; }
.pw-row > * { flex: 1 1 140px; }
</style>
<script>
const infra = document.getElementById("pw-wl-infra") as HTMLSelectElement;
const mvnoWrap = document.getElementById("pw-wl-mvno-wrap") as HTMLElement;
const facWrap = document.getElementById("pw-wl-fac-wrap") as HTMLElement;
const hostSel = document.getElementById("pw-wl-host") as HTMLSelectElement;
const bands = document.getElementById("pw-wl-bands") as HTMLTextAreaElement;
const sites = document.getElementById("pw-wl-sites") as HTMLInputElement;
const post = document.getElementById("pw-wl-post") as HTMLInputElement;
const pre = document.getElementById("pw-wl-pre") as HTMLInputElement;
const roamMou = document.getElementById("pw-wl-roam-mou") as HTMLInputElement;
const roamRev = document.getElementById("pw-wl-roam-rev") as HTMLInputElement;
function syncInfra() {
mvnoWrap.hidden = infra.value !== "mvno";
facWrap.hidden = infra.value === "mvno";
}
infra.addEventListener("change", syncInfra);
window.addEventListener("pw:step-shown", (evt: any) => {
if (evt.detail.step !== "wireless") return;
const s = (window as any).PWIntake.get();
const m = s.intake_data?.wireless_meta || {};
infra.value = m.infra_type || "facilities";
hostSel.value = m.host_mno || "";
bands.value = (m.spectrum_bands || []).join("\n");
sites.value = m.cell_site_count ?? "";
post.value = m.post_paid_subs ?? "";
pre.value = m.pre_paid_subs ?? "";
roamMou.value = m.roaming_mou ?? "";
roamRev.value = m.roaming_revenue_usd ?? "";
syncInfra();
});
window.addEventListener("pw:step-next", (evt: any) => {
const PW = (window as any).PWIntake;
if (PW.steps[PW.get().step_index] !== "wireless") return;
const meta: Record<string, any> = {
infra_type: infra.value,
host_mno: infra.value === "mvno" ? hostSel.value || null : null,
spectrum_bands: bands.value.split("\n").map((b) => b.trim()).filter(Boolean),
cell_site_count: Number(sites.value) || null,
post_paid_subs: Number(post.value) || 0,
pre_paid_subs: Number(pre.value) || 0,
roaming_mou: Number(roamMou.value) || 0,
roaming_revenue_usd: Number(roamRev.value) || 0,
};
PW.patchIntakeData({ wireless_meta: meta });
});
</script>