generated from nhcarrigan/template
feat: debug panel with force unlocks and hard reset (#65)
## Summary - Adds a new **Debug** tab to the game UI with two self-service tools for players with broken save state - **Force Unlocks**: scans the player's save and grants any zones, quests, bosses, and exploration areas they've earned but that are still locked — shows a breakdown of what was unlocked (or reports nothing needed fixing) - **Hard Reset**: wipes progress back to a fresh save (preserving lifetime stats), guarded behind a confirmation modal to prevent accidental clicks ## Files added - `apps/api/src/routes/debug.ts` — two POST endpoints (`/force-unlocks`, `/hard-reset`) - `apps/web/src/components/game/debugPanel.tsx` — the Debug tab UI - `apps/web/src/components/ui/confirmationModal.tsx` — reusable confirmation modal ## Files modified - `apps/api/src/index.ts` — registers the debug router - `packages/types/src/interfaces/api.ts` — adds `ForceUnlocksResponse` type - `packages/types/src/index.ts` — exports the new type - `apps/web/src/api/client.ts` — adds `forceUnlocks()` and `debugHardReset()` API calls - `apps/web/src/context/gameContext.tsx` — wires both functions into game context - `apps/web/src/components/game/gameLayout.tsx` — adds the Debug tab - `apps/web/src/styles.css` — styles for action buttons, cards, result messages, and confirmation modal ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #65 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #65.
This commit is contained in:
@@ -4515,3 +4515,84 @@ body::before {
|
||||
object-fit: cover;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
/* ===================== ACTION BUTTONS ===================== */
|
||||
.action-button {
|
||||
background: var(--colour-accent);
|
||||
border: none;
|
||||
border-radius: var(--radius);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 700;
|
||||
margin-top: 0.5rem;
|
||||
padding: 0.55rem 1.25rem;
|
||||
transition: background 0.15s;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action-button:hover:not(:disabled) {
|
||||
background: var(--colour-accent-light);
|
||||
}
|
||||
|
||||
.action-button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.action-button-danger {
|
||||
background: var(--colour-error);
|
||||
}
|
||||
|
||||
.action-button-danger:hover:not(:disabled) {
|
||||
background: #f87171;
|
||||
}
|
||||
|
||||
/* ===================== MODAL VARIANTS ===================== */
|
||||
.modal-button-danger {
|
||||
background: var(--colour-error);
|
||||
}
|
||||
|
||||
.modal-button-danger:hover:not(:disabled) {
|
||||
background: #f87171;
|
||||
}
|
||||
|
||||
/* ===================== DEBUG PANEL ===================== */
|
||||
.debug-actions {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.debug-action-card {
|
||||
background: var(--colour-surface);
|
||||
border: 1px solid var(--colour-border);
|
||||
border-radius: var(--radius-lg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.debug-action-card h3 {
|
||||
color: var(--colour-accent-light);
|
||||
font-size: 1rem;
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
|
||||
.debug-action-card > p {
|
||||
color: var(--colour-text-muted);
|
||||
flex: 1;
|
||||
font-size: 0.875rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.debug-result-message {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
border: 1px solid var(--colour-success);
|
||||
border-radius: var(--radius);
|
||||
color: var(--colour-success);
|
||||
font-size: 0.8rem;
|
||||
margin-top: 0.75rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user