generated from nhcarrigan/template
03b6c847b3
## 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>
69 lines
1.9 KiB
TypeScript
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 };
|