Scanner: compact 3-cell Adults / Youth / Kids party panel
All checks were successful
Build Android APK / build-apk (push) Successful in 55m8s

Split the party panel into Adults (18+) / Youth (13-16) / Kids (0-12)
so the paid tickets (adults + youth) are both visible, and shrank it
(36px numbers, tighter padding, single-line kid detail) so the confirm
card no longer scrolls on a phone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hank 2026-07-22 03:34:14 +00:00
parent 62231e9b10
commit 60f0908299

View file

@ -396,30 +396,38 @@ function AdultNames({ names }: { names: string[] }) {
} }
/** /**
* Big Adults / Kids breakdown so gate staff can eyeball the party against the * Big Adults / Youth / Kids breakdown so gate staff can eyeball the party
* ticket a deterrent for adults signing up under a (free/cheaper) kid bracket. * against the ticket a deterrent for adults signing up under a (free/cheaper)
* Adults = the 18+ bracket; Kids = everyone else (youth 13-16 + all under-13). * younger bracket. Adults (18+) and Youth (13-16) are the paid tickets; Kids
* (0-12) are free. A detail line breaks the kids into their age bands.
*/ */
function PartyPanel({ ticket }: { ticket: TicketView }) { function PartyPanel({ ticket }: { ticket: TicketView }) {
const adults = ticket.ages.find((a) => a.bracket === "Adults")?.count ?? 0; const get = (b: string) => ticket.ages.find((a) => a.bracket === b)?.count ?? 0;
const kidBrackets = ticket.ages.filter((a) => a.bracket !== "Adults"); const adults = get("Adults");
const youth = get("Youth 13-16");
const kidBrackets = ticket.ages.filter((a) => a.bracket.startsWith("Kids"));
const kids = kidBrackets.reduce((s, a) => s + a.count, 0); const kids = kidBrackets.reduce((s, a) => s + a.count, 0);
return ( return (
<View style={styles.party}> <View style={styles.party}>
<View style={styles.partyRow}> <View style={styles.partyRow}>
<View style={styles.partyCell}> <View style={styles.partyCell}>
<Text style={styles.partyNum}>{adults}</Text> <Text style={styles.partyNum}>{adults}</Text>
<Text style={styles.partyLbl}>{adults === 1 ? "ADULT" : "ADULTS"}</Text> <Text style={styles.partyLbl}>ADULTS{"\n"}18+</Text>
</View>
<View style={styles.partyDivider} />
<View style={styles.partyCell}>
<Text style={styles.partyNum}>{youth}</Text>
<Text style={styles.partyLbl}>YOUTH{"\n"}13-16</Text>
</View> </View>
<View style={styles.partyDivider} /> <View style={styles.partyDivider} />
<View style={styles.partyCell}> <View style={styles.partyCell}>
<Text style={styles.partyNum}>{kids}</Text> <Text style={styles.partyNum}>{kids}</Text>
<Text style={styles.partyLbl}>{kids === 1 ? "KID" : "KIDS"}</Text> <Text style={styles.partyLbl}>KIDS{"\n"}0-12</Text>
</View> </View>
</View> </View>
{kidBrackets.length > 0 && ( {kidBrackets.length > 0 && (
<Text style={styles.partyDetail}> <Text style={styles.partyDetail}>
{kidBrackets.map((a) => `${a.count}× ${a.bracket.replace(/^(Kids|Youth)\s*/, "")}`).join(" · ")} kids: {kidBrackets.map((a) => `${a.count}× ${a.bracket.replace(/^Kids\s*/, "")}`).join(" · ")}
</Text> </Text>
)} )}
</View> </View>
@ -573,18 +581,18 @@ const styles = StyleSheet.create({
backgroundColor: "#1d2a1f", backgroundColor: "#1d2a1f",
borderWidth: 2, borderWidth: 2,
borderColor: theme.warn, borderColor: theme.warn,
borderRadius: 16, borderRadius: 14,
paddingVertical: 18, paddingVertical: 10,
paddingHorizontal: 12, paddingHorizontal: 10,
marginTop: 16, marginTop: 10,
marginBottom: 2, marginBottom: 2,
}, },
partyRow: { flexDirection: "row", alignItems: "center", justifyContent: "center" }, partyRow: { flexDirection: "row", alignItems: "center", justifyContent: "center" },
partyCell: { flex: 1, alignItems: "center" }, partyCell: { flex: 1, alignItems: "center" },
partyNum: { color: theme.text, fontSize: 60, fontWeight: "900", lineHeight: 64 }, partyNum: { color: theme.text, fontSize: 36, fontWeight: "900", lineHeight: 40 },
partyLbl: { color: theme.warn, fontSize: 15, fontWeight: "800", letterSpacing: 2, marginTop: 2 }, partyLbl: { color: theme.warn, fontSize: 11, fontWeight: "800", letterSpacing: 0.5, marginTop: 1, textAlign: "center", lineHeight: 13 },
partyDivider: { width: 2, alignSelf: "stretch", backgroundColor: theme.cardBorder, marginVertical: 6 }, partyDivider: { width: 1.5, height: 42, backgroundColor: theme.cardBorder },
partyDetail: { color: theme.textDim, fontSize: 14, textAlign: "center", marginTop: 12, fontWeight: "600" }, partyDetail: { color: theme.textDim, fontSize: 12, textAlign: "center", marginTop: 8, fontWeight: "600" },
tags: { flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: 8, marginTop: 14 }, tags: { flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: 8, marginTop: 14 },
tag: { color: "#fff", backgroundColor: "rgba(255,255,255,0.18)", paddingHorizontal: 10, paddingVertical: 5, borderRadius: 999, fontSize: 13, overflow: "hidden" }, tag: { color: "#fff", backgroundColor: "rgba(255,255,255,0.18)", paddingHorizontal: 10, paddingVertical: 5, borderRadius: 999, fontSize: 13, overflow: "hidden" },