fix: persist UI preferences across navigation and sessions (#48)
CI / Lint, Build & Test (push) Successful in 1m10s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m11s

## Summary

- **#35** — Adventure multiplier selection is now persisted in `localStorage` (`"elysium_batch_size"`). The chosen batch size is restored automatically on the next visit, with a graceful fallback to `1` for missing or unrecognisable values.
- **#36** — Zone selection in the boss panel and quest panel is now persisted in `sessionStorage` (`"elysium_boss_zone"` / `"elysium_quest_zone"`). The selected zone survives navigation within a session and resets cleanly when the session ends, defaulting to Verdant Vale if no stored value exists.

## Test plan

- [x] Lint — zero errors, zero warnings
- [x] Build — all packages build cleanly
- [x] Tests — 415 tests passing, 100% coverage across all packages
- [ ] Manual: select a non-default batch size, refresh the page — multiplier should be restored
- [ ] Manual: switch to a non-default zone in the boss panel, navigate away and back — zone should still be selected
- [ ] Manual: repeat for the quest panel
- [ ] Manual: log out and back in — zone selection should reset to Verdant Vale

 This PR was created with help from Hikari~ 🌸

Reviewed-on: #48
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #48.
This commit is contained in:
2026-03-09 22:17:12 -07:00
committed by Naomi Carrigan
parent d0790890ee
commit 404b31bd13
5 changed files with 54 additions and 9 deletions
+11 -4
View File
@@ -108,9 +108,9 @@ const QuestCard = ({
</p>
}
<div className="quest-rewards">
{quest.rewards.map((reward) => {
{quest.rewards.map((reward, rewardIndex) => {
return (
<span className="reward-tag" key={`${reward.type}-${String(reward.amount ?? "")}`}>
<span className="reward-tag" key={`${reward.type}-${reward.targetId ?? String(reward.amount ?? rewardIndex)}`}>
{reward.type === "gold"
&& `🪙 ${formatNumber(reward.amount ?? 0)}`}
{reward.type === "essence"
@@ -184,7 +184,9 @@ const QuestCard = ({
*/
const QuestPanel = (): JSX.Element => {
const { state, toggleAutoQuest } = useGame();
const [ activeZoneId, setActiveZoneId ] = useState("verdant_vale");
const [ activeZoneId, setActiveZoneId ] = useState(() => {
return sessionStorage.getItem("elysium_quest_zone") ?? "verdant_vale";
});
const [ showLocked, setShowLocked ] = useState(true);
if (state === null) {
@@ -243,6 +245,11 @@ const QuestPanel = (): JSX.Element => {
}
}
function handleZoneSelect(zoneId: string): void {
setActiveZoneId(zoneId);
sessionStorage.setItem("elysium_quest_zone", zoneId);
}
function handleToggle(): void {
setShowLocked((current) => {
return !current;
@@ -285,7 +292,7 @@ const QuestPanel = (): JSX.Element => {
<ZoneSelector
activeZoneId={activeZoneId}
onSelectZone={setActiveZoneId}
onSelectZone={handleZoneSelect}
zones={zones}
/>