2 Commits

Author SHA1 Message Date
hikari 9fcc5bb836 feat: persist zone selection across panel navigation in sessionStorage
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m2s
CI / Lint, Build & Test (pull_request) Successful in 1m7s
Both the boss panel and the quest panel now read their active zone from
sessionStorage on mount and write back to it whenever the user selects
a new zone. The stored selections are cleared automatically when the
session ends, and fall back to verdant_vale when no stored value exists.

Closes #36
2026-03-09 22:02:56 -07:00
hikari fc93efd245 feat: persist adventure multiplier selection in localStorage
Reads the saved batch-size preference on mount and writes it back to
localStorage on every selection change, so the chosen multiplier
survives page refreshes. Falls back to 1 when no stored value is found
or the value is unrecognisable.

Closes #35
2026-03-09 22:02:52 -07:00
4 changed files with 6 additions and 16 deletions
@@ -243,7 +243,7 @@ const CharacterPage = ({ discordId }: CharacterPageProperties): JSX.Element => {
return (
<div
className="character-page-equipment-item"
key={item.name}
key={item.type}
>
<div className="character-page-equipment-header">
<span className="character-page-equipment-slot">
@@ -26,9 +26,7 @@ const bonusLabel: Record<string, string> = {
*/
const CraftingPanel = (): JSX.Element => {
const { state, craftRecipe, formatNumber } = useGame();
const [ activeZoneId, setActiveZoneId ] = useState(() => {
return sessionStorage.getItem("elysium_craft_zone") ?? "verdant_vale";
});
const [ activeZoneId, setActiveZoneId ] = useState("verdant_vale");
const [ pendingRecipeId, setPendingRecipeId ] = useState<string | null>(null);
if (state === null) {
@@ -70,11 +68,6 @@ const CraftingPanel = (): JSX.Element => {
});
}
function handleZoneSelect(zoneId: string): void {
setActiveZoneId(zoneId);
sessionStorage.setItem("elysium_craft_zone", zoneId);
}
async function handleCraft(recipeId: string): Promise<void> {
setPendingRecipeId(recipeId);
try {
@@ -92,7 +85,7 @@ const CraftingPanel = (): JSX.Element => {
<ZoneSelector
activeZoneId={activeZoneId}
onSelectZone={handleZoneSelect}
onSelectZone={setActiveZoneId}
zones={zones}
/>
@@ -67,9 +67,7 @@ interface CollectResult {
const ExplorationPanel = (): JSX.Element => {
const { state, startExploration, collectExploration, formatNumber }
= useGame();
const [ activeZoneId, setActiveZoneId ] = useState(() => {
return sessionStorage.getItem("elysium_explore_zone") ?? "verdant_vale";
});
const [ activeZoneId, setActiveZoneId ] = useState("verdant_vale");
const [ pendingAreaId, setPendingAreaId ] = useState<string | null>(null);
const [ lastResult, setLastResult ] = useState<CollectResult | null>(null);
@@ -118,7 +116,6 @@ const ExplorationPanel = (): JSX.Element => {
function handleZoneSelect(id: string): void {
setActiveZoneId(id);
setLastResult(null);
sessionStorage.setItem("elysium_explore_zone", id);
}
const goldChange = lastResult?.response.event?.goldChange ?? 0;
+2 -2
View File
@@ -108,9 +108,9 @@ const QuestCard = ({
</p>
}
<div className="quest-rewards">
{quest.rewards.map((reward, rewardIndex) => {
{quest.rewards.map((reward) => {
return (
<span className="reward-tag" key={`${reward.type}-${reward.targetId ?? String(reward.amount ?? rewardIndex)}`}>
<span className="reward-tag" key={`${reward.type}-${String(reward.amount ?? "")}`}>
{reward.type === "gold"
&& `🪙 ${formatNumber(reward.amount ?? 0)}`}
{reward.type === "essence"