Merge pull request 'Fix account dashboard sync rendering' (#4) from feature/fix-account-dashboard-js-sync into main

Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
2026-06-12 15:27:12 -04:00
3 changed files with 72 additions and 29 deletions
+39 -14
View File
@@ -445,13 +445,13 @@ def bb_sync_info(account_id):
regions = {
"us": {
"host": "psopeeps_us",
"targets": ["us-live", "us-test", "us-hardcore"],
"targets": ["us-live", "us-hardcore"],
"status": "pending",
"applied_at": None,
},
"eu": {
"host": "psopeeps_eu",
"targets": ["eu-live", "eu-test", "eu-hardcore"],
"targets": ["eu-live", "eu-hardcore"],
"status": "pending",
"applied_at": None,
},
@@ -1055,8 +1055,16 @@ def local_syncer_save_summary(account_id):
applied_dir = root / "state" / "applied"
paths = {
"us": applied_dir / f"psopeeps_us.site.{account}.json",
"eu": applied_dir / f"psopeeps_eu.site.{account}.json",
"us": [
applied_dir / f"psopeeps_us.us-live.site.{account}.json",
applied_dir / f"psopeeps_us.us-test.site.{account}.json",
applied_dir / f"psopeeps_us.us-hardcore.site.{account}.json",
],
"eu": [
applied_dir / f"psopeeps_eu.eu-live.site.{account}.json",
applied_dir / f"psopeeps_eu.eu-test.site.{account}.json",
applied_dir / f"psopeeps_eu.eu-hardcore.site.{account}.json",
],
}
def parse_time(value):
@@ -1079,19 +1087,36 @@ def local_syncer_save_summary(account_id):
"manifest_sha256": None,
}
if path.exists():
states = []
errors = []
for path in paths[region]:
if not path.exists():
continue
try:
data = json.loads(path.read_text())
info.update({
"status": "seen",
"label": "Seen",
"style": "warn",
"host": data.get("host"),
"applied_at": data.get("applied_at"),
"manifest_sha256": data.get("manifest_sha256"),
})
data["_path"] = str(path)
states.append(data)
except Exception as e:
info["error"] = str(e)
errors.append(f"{path.name}: {e}")
if states:
latest_state = max(states, key=lambda x: str(x.get("applied_at") or ""))
hashes = {x.get("manifest_sha256") for x in states if x.get("manifest_sha256")}
info.update({
"status": "seen",
"label": "Seen",
"style": "warn",
"host": latest_state.get("host"),
"applied_at": latest_state.get("applied_at"),
"manifest_sha256": latest_state.get("manifest_sha256"),
"targets_seen": len(states),
"targets_expected": len(paths[region]),
"all_targets_same_hash": len(hashes) == 1,
})
if errors:
info["errors"] = errors
regions[region] = info
+25 -13
View File
@@ -32,13 +32,9 @@
<div>
<p class="eyebrow">Account Dashboard</p>
<h1 id="account-title">chuudoku</h1>
<p>
Manage your Blue Burst login and the serial/access keys you use for DC V2, PC V2, and GC V3.
Linked saves are mirrored between US and EU automatically.
</p>
</div>
<div class="status-badges" aria-label="Account setup status">
<span class="badge badge--ok">BB account ready</span>
<span class="badge badge--ok">Account ready</span>
<span class="badge badge--ok">Saves synced</span>
</div>
</section>
@@ -54,12 +50,25 @@
<section class="dashboard-grid dashboard-grid--setup">
<section class="card setup-card setup-card--bb" aria-labelledby="bb-heading">
<h2 id="bb-heading" class="section-title">Blue Burst Account</h2>
<dl class="account-summary account-summary--large">
<div><dt>BB username</dt><dd>chuudoku</dd></div>
<div><dt>BB account ID</dt><dd>0126326509</dd></div>
</dl>
<p class="fine-print">Blue Burst is limited to one account per website account. Password reset can come later.</p>
<h2 id="bb-heading" class="section-title">Blue Burst</h2>
<p>BB username <strong>chuudoku</strong><br>BB account ID <strong>0126326509</strong></p>
<form class="bb-account-form" data-bb-action="change-password">
<p class="muted">Change your Blue Burst login password. This updates the account file, then it needs to sync to the ships.</p>
<label>
New BB password
<input name="password" type="password" autocomplete="new-password" maxlength="16" required>
</label>
<label>
Confirm new BB password
<input name="confirm_password" type="password" autocomplete="new-password" maxlength="16" required>
</label>
<button class="button" type="submit">Change Blue Burst Password</button>
<div class="bb-message" role="status"></div>
</form>
</section>
<section class="card setup-card setup-card--key-sync" aria-labelledby="key-sync-heading">
@@ -88,10 +97,13 @@
<input id="key-label" name="key-label" type="text" placeholder="Dreamcast US disc, GameCube JP, etc.">
<label for="key-serial">Serial Number</label>
<input id="key-serial" name="key-serial" type="text" inputmode="numeric">
<input id="key-serial" name="key-serial" type="text" inputmode="numeric" placeholder="DC V2 serial number">
<label for="key-display-serial">Confirm Serial Number</label>
<input id="key-display-serial" name="display_serial" autocomplete="off" type="text" inputmode="numeric" placeholder="confirm serial number">
<label for="key-access">Access Key</label>
<input id="key-access" name="key-access" type="text">
<input id="key-access" name="key-access" type="text" placeholder="access key">
<button type="button">Register Key Profile</button>
</form>
</section>
+8 -2
View File
@@ -388,7 +388,10 @@
if (!hero || !title) return;
for (const p of Array.from(hero.querySelectorAll("p"))) {
if (p.textContent.includes("Manage your Blue Burst login")) {
if (
p.textContent.includes("Manage your Blue Burst login") ||
p.classList.contains("account-email-line")
) {
p.remove();
}
}
@@ -575,7 +578,10 @@
renderAccountEmail(accountData);
updateAccountStatusBadges(accountData);
renderBBCard(accountData);
// Account dashboard BB card is server-rendered.
// Do not let the generic app bootstrap rewrite it into a stale layout.
return;
}
async function boot() {