Files
elysium/apps/web/src/components/ui/confirmationModal.tsx
T
hikari 03b6c847b3
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m5s
CI / Lint, Build & Test (push) Successful in 1m10s
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>
2026-03-18 12:37:06 -07:00

69 lines
1.9 KiB
TypeScript

/**
* @file Reusable confirmation modal component for destructive operations.
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import type { JSX } from "react";
interface ConfirmationModalProperties {
readonly title: string;
readonly description: string;
readonly confirmLabel: string;
readonly onConfirm: ()=> void;
readonly onCancel: ()=> void;
readonly isLoading: boolean;
}
/**
* Renders a confirmation modal for destructive operations.
* @param props - The modal properties.
* @param props.title - The modal heading.
* @param props.description - Warning text explaining what the operation does.
* @param props.confirmLabel - Label for the confirm button.
* @param props.onConfirm - Callback fired when the player confirms.
* @param props.onCancel - Callback fired when the player cancels.
* @param props.isLoading - Whether the operation is currently in progress.
* @returns The JSX element.
*/
const ConfirmationModal = ({
title,
description,
confirmLabel,
onConfirm,
onCancel,
isLoading,
}: ConfirmationModalProperties): JSX.Element => {
return (
<div className="modal-overlay">
<div className="modal">
<h2>{title}</h2>
<p>{description}</p>
<p className="modal-note">{"Are you sure you want to do this?"}</p>
<div className="modal-actions">
<button
className="modal-close-button modal-button-danger"
disabled={isLoading}
onClick={onConfirm}
type="button"
>
{isLoading
? "Working..."
: confirmLabel}
</button>
<button
className="modal-close-button"
disabled={isLoading}
onClick={onCancel}
type="button"
>
{"Cancel"}
</button>
</div>
</div>
</div>
);
};
export { ConfirmationModal };