Added admn QOL stuff andalso made shop a bit easier to navigate with

collapsible sections.
This commit is contained in:
sarah committed 2026-09-03 21:27:19 +02:00
1 parent a055a74148
commit afb9dae47a
5 files changed
+379 -17

No files matched your search

+14
View File
@@ -48,6 +48,20 @@ $PageSection = "Admin";
> >
New plant New plant
</button> </button>
<label for="AdminPlantDuplicateSelect">
Duplicate existing
</label>
<select id="AdminPlantDuplicateSelect"></select>
<button
id="AdminPlantDuplicateButton"
class="ActionButton AdminInlineButton"
type="button"
>
Duplicate
</button>
</div> </div>
<form <form
+46 -13
View File
@@ -44,29 +44,62 @@ $PageSection = "Shop";
id="PermanentUpgrades" id="PermanentUpgrades"
class="ShopSection" class="ShopSection"
> >
<h2>Permanent upgrades</h2> <h2 class="ShopSectionHeading">
<button
<p> id="PermanentUpgradesToggle"
Expand your active Garden, buy additional Gardens, class="ShopSectionToggle"
or unlock information and quality-of-life features. type="button"
</p> aria-expanded="false"
aria-controls="PermanentUpgradesContent"
>
<span class="ShopSectionArrow" aria-hidden="true">&gt;</span>
<span>Permanent upgrades</span>
</button>
</h2>
<div <div
id="ShopGardenUpgradeList" id="PermanentUpgradesContent"
class="ShopSeedList" class="ShopSectionContent"
></div> hidden
>
<p>
Expand your active Garden, buy additional Gardens,
or unlock information and quality-of-life features.
</p>
<div
id="ShopGardenUpgradeList"
class="ShopSeedList"
></div>
</div>
</section> </section>
<section <section
id="Seeds" id="Seeds"
class="ShopSection" class="ShopSection"
> >
<h2>Seeds</h2> <h2 class="ShopSectionHeading">
<button
id="SeedsToggle"
class="ShopSectionToggle"
type="button"
aria-expanded="true"
aria-controls="SeedsContent"
>
<span class="ShopSectionArrow" aria-hidden="true">&gt;</span>
<span>Seeds</span>
</button>
</h2>
<div <div
id="ShopSeedList" id="SeedsContent"
class="ShopSeedList" class="ShopSectionContent"
></div> >
<div
id="ShopSeedList"
class="ShopSeedList"
></div>
</div>
</section> </section>
<p id="ShopMessage" class="PageMessage"> <p id="ShopMessage" class="PageMessage">
+189
View File
@@ -64,6 +64,13 @@ function BindAdminPlantEditor() {
StartNewAdminPlant StartNewAdminPlant
); );
document.getElementById(
"AdminPlantDuplicateButton"
).addEventListener(
"click",
DuplicateAdminPlant
);
document.getElementById( document.getElementById(
"AdminPlantForm" "AdminPlantForm"
).addEventListener( ).addEventListener(
@@ -279,6 +286,7 @@ async function LoadAdminPlants(
AdminPlantMutationCatalogue; AdminPlantMutationCatalogue;
RenderAdminPlantSelect(); RenderAdminPlantSelect();
RenderAdminPlantDuplicateSelect();
const Keys = const Keys =
GetSortedAdminPlantKeys(); GetSortedAdminPlantKeys();
@@ -376,6 +384,70 @@ function RenderAdminPlantSelect() {
} }
function RenderAdminPlantDuplicateSelect() {
const Select =
document.getElementById(
"AdminPlantDuplicateSelect"
);
if (Select === null) {
return;
}
const PreviousValue =
Select.value;
Select.replaceChildren();
for (
const PlantKey
of GetSortedAdminPlantKeys()
) {
const Plant =
AdminPlantCatalogue[
PlantKey
];
const Option =
document.createElement(
"option"
);
Option.value =
PlantKey;
Option.textContent =
String(
Plant.Id
).padStart(
3,
"0"
) +
" — " +
Plant.Name +
(
Plant.Archived === true
? " (archived)"
: ""
);
Select.appendChild(
Option
);
}
if (
PreviousValue !== "" &&
AdminPlantCatalogue[
PreviousValue
] !== undefined
) {
Select.value =
PreviousValue;
}
}
function LoadAdminPlantIntoForm( function LoadAdminPlantIntoForm(
PlantKey PlantKey
) { ) {
@@ -475,6 +547,123 @@ function LoadAdminPlantIntoForm(
} }
function DuplicateAdminPlant() {
const SourcePlantKey =
document.getElementById(
"AdminPlantDuplicateSelect"
).value;
const SourcePlant =
AdminPlantCatalogue[
SourcePlantKey
];
if (SourcePlant === undefined) {
SetAdminPlantMessage(
"Choose a plant to duplicate."
);
return;
}
AdminPlantEditingKey = null;
document.getElementById(
"AdminPlantSelect"
).value = "";
SetAdminPlantField(
"AdminPlantId",
GetNextAdminPlantId()
);
SetAdminPlantField(
"AdminPlantKey",
""
);
SetAdminPlantField(
"AdminPlantName",
""
);
SetAdminPlantField(
"AdminPlantDescription",
SourcePlant.Description ?? ""
);
SetAdminPlantField(
"AdminPlantTags",
Array.isArray(
SourcePlant.Tags
)
? SourcePlant.Tags.join(
", "
)
: ""
);
SetAdminPlantDurationFields(
Number(
SourcePlant.GrowthTime ??
0
)
);
SetAdminPlantField(
"AdminPlantHarvestMultiplier",
Number(
SourcePlant.HarvestMultiplier ??
1.5
)
);
document.getElementById(
"AdminPlantShopPlant"
).checked =
SourcePlant.Shop?.ShopPlant === true;
SetAdminPlantField(
"AdminPlantBaseCost",
SourcePlant.Shop?.BaseCost ?? ""
);
SetAdminPlantField(
"AdminPlantEffects",
JSON.stringify(
SourcePlant.Effects ?? {},
null,
4
)
);
document.getElementById(
"AdminPlantId"
).readOnly = false;
document.getElementById(
"AdminPlantKey"
).readOnly = false;
document.getElementById(
"AdminPlantArchiveNote"
).hidden = true;
UpdateAdminPlantShopFields();
RenderAdminPlantPreview();
document.getElementById(
"AdminPlantName"
).focus();
SetAdminPlantMessage(
"Duplicated " +
SourcePlant.Name +
". Give the new plant a name and Plant Key before saving. Sprites are not copied."
);
}
function StartNewAdminPlant() { function StartNewAdminPlant() {
AdminPlantEditingKey = null; AdminPlantEditingKey = null;
+83 -4
View File
@@ -21,10 +21,69 @@ async function StartShop() {
ShopSave = await LoadGame(); ShopSave = await LoadGame();
BindShopSectionToggles();
RenderShop(); RenderShop();
} }
function BindShopSectionToggles() {
BindShopSectionToggle(
"PermanentUpgradesToggle",
"PermanentUpgradesContent"
);
BindShopSectionToggle(
"SeedsToggle",
"SeedsContent"
);
}
function BindShopSectionToggle(
ToggleId,
ContentId
) {
const Toggle =
document.getElementById(
ToggleId
);
const Content =
document.getElementById(
ContentId
);
if (
Toggle === null ||
Content === null
) {
return;
}
Toggle.addEventListener(
"click",
() => {
const IsExpanded =
Toggle.getAttribute(
"aria-expanded"
) === "true";
const NewExpanded =
!IsExpanded;
Toggle.setAttribute(
"aria-expanded",
String(NewExpanded)
);
Content.hidden =
!NewExpanded;
}
);
}
function RenderShop() { function RenderShop() {
RenderShopCurrency(); RenderShopCurrency();
RenderShopSeeds(); RenderShopSeeds();
@@ -413,7 +472,12 @@ function CreatePlantInformationUpgradeCard() {
); );
Header.className = Header.className =
"ShopItemHeader"; "ShopItemHeader" +
(
IsOwned
? " ShopItemHeaderOwned"
: ""
);
const Name = const Name =
@@ -529,7 +593,12 @@ function CreateGardenOverviewUpgradeCard() {
); );
Header.className = Header.className =
"ShopItemHeader"; "ShopItemHeader" +
(
IsOwned
? " ShopItemHeaderOwned"
: ""
);
const Name = const Name =
@@ -645,7 +714,12 @@ function CreateGardenEconomyUpgradeCard() {
); );
Header.className = Header.className =
"ShopItemHeader"; "ShopItemHeader" +
(
IsOwned
? " ShopItemHeaderOwned"
: ""
);
const Name = const Name =
@@ -759,7 +833,12 @@ function CreateMutationHintsUpgradeCard() {
); );
Header.className = Header.className =
"ShopItemHeader"; "ShopItemHeader" +
(
IsOwned
? " ShopItemHeaderOwned"
: ""
);
const Name = const Name =
+47
View File
@@ -1126,6 +1126,48 @@ input, button, textarea, select {
margin-top: 1.5rem; margin-top: 1.5rem;
} }
.ShopSectionHeading {
margin-bottom: 0.75rem;
}
.ShopSectionToggle {
display: flex;
width: 100%;
gap: 0.55rem;
align-items: center;
padding: 0;
cursor: pointer;
color: var(--Text);
background: none;
border: 0;
font-size: inherit;
text-align: left;
}
.ShopSectionToggle:hover {
color: var(--Sky);
}
.ShopSectionToggle:focus-visible {
outline: 3px solid var(--Yellow);
outline-offset: 3px;
}
.ShopSectionArrow {
width: 1ch;
flex: 0 0 1ch;
color: var(--Overlay2);
transform-origin: center;
}
.ShopSectionToggle[aria-expanded="true"] .ShopSectionArrow {
transform: rotate(90deg);
}
.ShopSectionContent[hidden] {
display: none;
}
.ShopSeedList { .ShopSeedList {
display: grid; display: grid;
grid-template-columns: repeat( auto-fit, minmax(15rem, 1fr) ); grid-template-columns: repeat( auto-fit, minmax(15rem, 1fr) );
@@ -1153,6 +1195,11 @@ input, button, textarea, select {
margin: 0; margin: 0;
} }
.ShopItemHeaderOwned {
color: var(--Overlay1);
border-bottom-color: var(--Surface1);
}
.ShopItemBody { .ShopItemBody {
display: grid; display: grid;
grid-template-columns: 5.75rem minmax(0, 1fr); grid-template-columns: 5.75rem minmax(0, 1fr);