Skip to content

Commit 7d0dc52

Browse files
committed
UPDATE - shop system and UI
1 parent 679640d commit 7d0dc52

9 files changed

Lines changed: 259 additions & 93 deletions

File tree

client/src/components/AdminShopPage.jsx

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const emptyForm = {
55
name: "",
66
price: "",
77
priceUsd: "",
8-
dollarPerHour: "",
8+
discountPercent: "",
99
maxPerPerson: "",
1010
itemLink: "",
1111
imageUrl: "",
@@ -185,7 +185,7 @@ export function AdminShopPage() {
185185
<th>Max / person</th>
186186
<th>bricks</th>
187187
<th>$ price</th>
188-
<th>$/h</th>
188+
<th>Discount</th>
189189
<th>Link</th>
190190
<th>Active</th>
191191
<th>Actions</th>
@@ -204,7 +204,7 @@ export function AdminShopPage() {
204204
<td>{item.maxPerPerson ?? "None"}</td>
205205
<td>{item.price ?? "—"}</td>
206206
<td>{item.priceUsd ?? "—"}</td>
207-
<td>{item.dollarPerHour ?? "—"}</td>
207+
<td>{item.discountPercent ? `${item.discountPercent}% off` : "—"}</td>
208208
<td>{item.itemLink ? <a href={item.itemLink} target="_blank" rel="noreferrer">View</a> : "—"}</td>
209209
<td>{item.active ? "Yes" : "No"}</td>
210210
<td>
@@ -268,18 +268,21 @@ function ShopItemForm({ value, submitLabel, onChange, onSubmit }) {
268268
/>
269269
</label>
270270
<label>
271-
$/h *
271+
bricks
272+
<input type="number" value={brickValue || ""} readOnly />
273+
</label>
274+
<label>
275+
Discount %
272276
<input
273277
type="number"
274-
step="0.01"
275-
value={value.dollarPerHour || ""}
276-
onChange={(event) => onChange("dollarPerHour", event.target.value)}
278+
min="0"
279+
max="100"
280+
step="1"
281+
placeholder="25"
282+
value={value.discountPercent || ""}
283+
onChange={(event) => onChange("discountPercent", event.target.value)}
277284
/>
278285
</label>
279-
<label>
280-
bricks
281-
<input type="number" value={brickValue || ""} readOnly />
282-
</label>
283286
<label>
284287
Max purchases per person
285288
<input type="number" value={value.maxPerPerson || ""} onChange={(event) => onChange("maxPerPerson", event.target.value)} />

client/src/components/ShopPage.css

Lines changed: 106 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,49 @@
148148
font-size: clamp(1.4rem, 2vw, 2.2rem);
149149
}
150150

151+
.shop-page__discount {
152+
position: absolute;
153+
left: -0.45rem;
154+
top: -0.62rem;
155+
z-index: 2;
156+
display: inline-flex;
157+
align-items: center;
158+
justify-content: center;
159+
min-width: min(5.4rem, 8vw);
160+
min-height: min(3.15rem, 4.4vw);
161+
padding: 0.35rem 0.55rem;
162+
border: 3px solid #fff2bb;
163+
border-radius: 999px;
164+
background: radial-gradient(circle at 30% 25%, #fff7a8 0%, #ffcb3d 38%, #ff6848 100%);
165+
color: #7a1b00;
166+
font-size: clamp(0.88rem, 1.25vw, 1.2rem);
167+
font-weight: 900;
168+
line-height: 1;
169+
text-align: center;
170+
text-transform: uppercase;
171+
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.65);
172+
box-shadow: 0 5px 0 #9b2a16, 0 0 18px rgba(255, 203, 61, 0.75);
173+
transform: rotate(-10deg);
174+
animation: shop-discount-bounce 1.45s ease-in-out infinite;
175+
}
176+
177+
@keyframes shop-discount-bounce {
178+
0%,
179+
100% {
180+
transform: rotate(-10deg) scale(1);
181+
filter: brightness(1);
182+
}
183+
184+
45% {
185+
transform: rotate(-7deg) scale(1.08);
186+
filter: brightness(1.12);
187+
}
188+
189+
70% {
190+
transform: rotate(-13deg) scale(0.98);
191+
}
192+
}
193+
151194
.shop-page__nav {
152195
position: relative;
153196
z-index: 4;
@@ -312,27 +355,6 @@
312355
font: inherit;
313356
}
314357

315-
.shop-page__modal-rules {
316-
margin-top: 0.8rem;
317-
padding: 0.7rem;
318-
border: 2px solid #c7d6ff;
319-
border-radius: 12px;
320-
background: rgba(255, 255, 255, 0.58);
321-
color: #27376f;
322-
}
323-
324-
.shop-page__modal-rules p {
325-
margin: 0.35rem 0 0.55rem;
326-
font-size: 0.88rem;
327-
}
328-
329-
.shop-page__modal-rules label {
330-
display: flex;
331-
align-items: flex-start;
332-
gap: 0.45rem;
333-
font-size: 0.86rem;
334-
}
335-
336358
.shop-page__modal-total {
337359
display: flex;
338360
align-items: center;
@@ -379,6 +401,69 @@
379401
filter: brightness(1.05);
380402
}
381403

404+
.shop-page__confirm-backdrop {
405+
position: fixed;
406+
inset: 0;
407+
z-index: 30;
408+
display: grid;
409+
place-items: center;
410+
padding: 1rem;
411+
background: rgba(15, 20, 36, 0.72);
412+
}
413+
414+
.shop-page__confirm {
415+
position: relative;
416+
width: min(28rem, 92vw);
417+
border: 4px solid #1b4cc0;
418+
border-radius: 16px;
419+
padding: 1.15rem;
420+
background: linear-gradient(160deg, #f6f7fd 0%, #dee6ff 100%);
421+
color: #27376f;
422+
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
423+
}
424+
425+
.shop-page__confirm h3 {
426+
margin: 0 2rem 0.75rem 0;
427+
color: #12235c;
428+
font-size: 1.35rem;
429+
}
430+
431+
.shop-page__confirm p {
432+
margin: 0.8rem 0;
433+
line-height: 1.45;
434+
}
435+
436+
.shop-page__confirm a {
437+
color: #1b4cc0;
438+
font-weight: 800;
439+
}
440+
441+
.shop-page__confirm-toggle {
442+
display: flex;
443+
align-items: center;
444+
gap: 0.55rem;
445+
width: fit-content;
446+
font-weight: 800;
447+
color: #12235c;
448+
}
449+
450+
.shop-page__confirm-toggle input {
451+
width: 1.2rem;
452+
height: 1.2rem;
453+
accent-color: #dd3b45;
454+
}
455+
456+
.shop-page__confirm-total {
457+
margin: 0.9rem 0 0;
458+
padding: 0.65rem 0.75rem;
459+
border: 2px dashed #9cb7ff;
460+
border-radius: 12px;
461+
background: rgba(255, 255, 255, 0.58);
462+
color: #12235c;
463+
font-weight: 900;
464+
text-align: center;
465+
}
466+
382467
@media (max-width: 980px) {
383468
.shop-page__left-panel {
384469
width: min(16rem, 27vw);

0 commit comments

Comments
 (0)