1import { r as reactExports, j as jsxRuntimeExports, dV as Medal, v as AnimatePresence, w as motion, a5 as Trophy, m as Calendar, z as Users, cb as Ticket, aC as Helmet, b1 as Gift, ae as Lock, dW as UserX, a$ as CircleCheckBig, aY as ChevronUp, ah as ChevronDown } from "./vendor-BRPG2tLG.js"; 2import { M as MemberGate } from "./MemberGate--WQNiOYv.js"; 3import { C as Card, b as CardHeader, c as CardTitle, a as CardContent } from "./card--K7fotj0.js"; 4import { B as Badge } from "./badge-BgHhs2gV.js"; 5import { aG as raffle_announcement, aE as raffle_winner_controls, bY as TIER_CONFIG, bZ as getTier } from "./index-DVj0zJ6X.js"; 6import "./preload-D9ItKcgK.js"; 7function formatDate(iso) { 8 return new Date(iso).toLocaleDateString("en-US", { 9 month: "long", 10 day: "numeric", 11 year: "numeric" 12 }); 13} 14function LotteryHallOfFame() { 15 const [winners, setWinners] = reactExports.useState([]); 16 const [loading, setLoading] = reactExports.useState(true); 17 reactExports.useEffect(() => { 18 fetch("/api/raffle/winners").then((r) => r.json()).then((d) => { 19 setWinners(d.winners ?? []); 20 setLoading(false); 21 }).catch(() => setLoading(false)); 22 }, []); 23 if (loading) { 24 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3 mt-2", children: [1, 2].map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-24 rounded-xl bg-muted animate-pulse" }, i)) }); 25 } 26 if (winners.length === 0) { 27 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-10 text-muted-foreground", children: [
28 /* @__PURE__ */ jsxRuntimeExports.jsx(Medal, { className: "h-8 w-8 mx-auto mb-2 opacity-30" }), 29 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No winners announced yet â be the first." }) 30 ] }); 31 } 32 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(AnimatePresence, { initial: false, children: winners.map((w, i) => /* @__PURE__ */ jsxRuntimeExports.jsx(motion.div, { initial: { 33 opacity: 0, 34 y: 12 35 }, animate: { 36 opacity: 1, 37 y: 0 38 }, transition: { 39 duration: 0.3, 40 delay: i * 0.06, 41 ease: "easeOut" 42 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl border border-border bg-card overflow-hidden flex gap-0", children: [ 43 w.imageUrl && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-20 shrink-0 hidden sm:block", children: /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: w.imageUrl, alt: w.prize, className: "w-full h-full object-cover", loading: "lazy" }) }), 44 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 px-4 py-3 space-y-1.5", children: [
45 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [ 46 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 bg-primary/10 text-primary border border-primary/20 rounded-full px-3 py-0.5 text-sm font-bold", children: [ 47 /* @__PURE__ */ jsxRuntimeExports.jsx(Trophy, { className: "h-3.5 w-3.5" }), 48 w.winnerDisplayName 49 ] }), 50 w.winnerMemberNumber !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-muted-foreground font-mono", children: [ 51 "Member #", 52 w.winnerMemberNumber 53 ] }) 54 ] }), 55 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-semibold text-foreground leading-tight", children: w.prize }), 56 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: w.raffleTitle }), 57 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 text-xs text-muted-foreground flex-wrap pt-0.5", children: [
58 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [ 59 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "h-3 w-3" }), 60 formatDate(w.drawnAt) 61 ] }), 62 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [ 63 /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "h-3 w-3" }), 64 w.entryCount.toLocaleString(), 65 " ", 66 w.entryCount === 1 ? "entry" : "entries" 67 ] }), 68 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [ 69 /* @__PURE__ */ jsxRuntimeExports.jsx(Ticket, { className: "h-3 w-3" }), 70 "1-in-", 71 w.entryCount, 72 " odds" 73 ] }) 74 ] }) 75 ] }) 76 ] }) }, w.raffleId)) }) }); 77} 78const STATUS_LABELS = { 79 open: { 80 label: "Draw Upcoming", 81 color: "bg-green-600 text-white" 82 }, 83 closed: { 84 label: "Drawing Soon", 85 color: "bg-yellow-500 text-black" 86 }, 87 drawn: { 88 label: "Winner Drawn", 89 color: "bg-primary text-primary-foreground" 90 }, 91 draft: { 92 label: "Coming Soon", 93 color: "bg-muted text-muted-foreground" 94 } 95}; 96function RafflePage() { 97 const [raffles, setRaffles] = reactExports.useState([]); 98 const [loading, setLoading] = reactExports.useState(true); 99 const [optedOut, setOptedOut] = reactExports.useState(false); 100 const [loggedIn, setLoggedIn] = reactExports.useState(false); 101 const [isStaff, setIsStaff] = reactExports.useState(false); 102 const [showHallOfFame, setShowHallOfFame] = reactExports.useState(false); 103 const [winnerRecords, setWinnerRecords] = reactExports.useState([]); 104 const [savingWinnerId, setSavingWinnerId] = reactExports.useState(null); 105 const [winnerChoiceError, setWinnerChoiceError] = reactExports.useState(""); 106 reactExports.useEffect(() => { 107 fetch("/api/profile", { 108 credentials: "include" 109 }).then((r) => r.ok ? r.json() : null).then((d) => { 110 if (d == null ? void 0 : d.profile) { 111 setLoggedIn(true); 112 const raw = d.profile; 113 setOptedOut(raw.lottery_opt_out === 1 || raw.lottery_opt_out === true); 114 setIsStaff(!!(raw.is_admin || raw.is_moderator || raw.is_owner)); 115 } 116 }).catch(() => { 117 }); 118 fetch("/api/raffle", { 119 credentials: "include" 120 }).then((r) => r.json()).then((d) => { 121 setRaffles(d.raffles ?? []); 122 setLoading(false); 123 }); 124 fetch("/api/raffle/my-wins", { 125 credentials: "include" 126 }).then((r) => r.ok ? r.json() : { 127 wins: [] 128 }).then((d) => setWinnerRecords(d.wins ?? [])).catch(() => setWinnerRecords([])); 129 }, []); 130 async function saveWinnerPrivacy(raffleId, choice) { 131 setSavingWinnerId(raffleId); 132 setWinnerChoiceError(""); 133 try { 134 const response = await fetch("/api/raffle/winner-privacy", { 135 method: "POST", 136 credentials: "include", 137 headers: { 138 "Content-Type": "application/json" 139 }, 140 body: JSON.stringify({ 141 raffleId, 142 choice 143 }) 144 }); 145 if (!response.ok) throw new Error(); 146 setWinnerRecords((records) => records.map((record) => record.raffle_id === raffleId ? { 147 ...record, 148 public_identity_consent: choice 149 } : record)); 150 } catch { 151 setWinnerChoiceError(raffle_winner_controls.winnerCenter.saveError); 152 } finally { 153 setSavingWinnerId(null); 154 } 155 } 156 return /* @__PURE__ */ jsxRuntimeExports.jsx(MemberGate, { toolName: "Member Lottery", toolDescription: "Active members are automatically entered to win veteran gear and commemorative items. Free to enter â just show up.", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Trophy, { className: "h-8 w-8 text-primary" }), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ 157 /* @__PURE__ */ jsxRuntimeExports.jsxs(Helmet, { children: [
158 /* @__PURE__ */ jsxRuntimeExports.jsx("title", { children: "Member Lottery â Win Veteran Gear & Commemorative Items | LCplUnderground.Vet" }), 159 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { name: "description", content: "Every registered member is automatically entered in member-exclusive raffles for a chance to win challenge coins, athletic shirts, commemorative medals, and more." }), 160 /* @__PURE__ */ jsxRuntimeExports.jsx("link", { rel: "canonical", href: "https://lcplunderground.vet/raffle" }), 161 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { property: "og:type", content: "website" }), 162 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { property: "og:site_name", content: "LCplUnderground.Vet" }), 163 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { property: "og:url", content: "https://lcplunderground.vet/raffle" }), 164 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { property: "og:title", content: "Member Lottery â Win Veteran Gear & Commemorative Items" }), 165 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { property: "og:description", content: "Every registered member is automatically entered in member-exclusive raffles for a chance to win challenge coins, shirts, commemorative medals, and more." }),
166 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { property: "og:image", content: "https://lcplunderground.vet/og-default.png" }), 167 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { name: "twitter:card", content: "summary_large_image" }), 168 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { name: "twitter:site", content: "@LCplUnderground" }), 169 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { name: "twitter:title", content: "Member Lottery â Win Veteran Gear | LCplUnderground.Vet" }), 170 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { name: "twitter:description", content: "Every registered member is automatically entered in member-exclusive raffles for challenge coins, shirts, and more." }), 171 /* @__PURE__ */ jsxRuntimeExports.jsx("meta", { name: "twitter:image", content: "https://lcplunderground.vet/og-default.png" }), 172 /* @__PURE__ */ jsxRuntimeExports.jsx("script", { type: "application/ld+json", children: JSON.stringify({ 173 "@context": "https://schema.org", 174 "@type": "WebPage", 175 "name": "Member Lottery â LCplUnderground.Vet", 176 "url": "https://lcplunderground.vet/raffle", 177 "description": "Member-exclusive raffles for veteran gear, challenge coins, and commemorative items. Every registered member is automatically entered.", 178 "publisher": { 179 "@type": "Organization", 180 "name": "LCplUnderground.Vet", 181 "url": "https://lcplunderground.vet" 182 } 183 }) }) 184 ] }), 185 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-3xl mx-auto px-4 py-12", children: [
186 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mb-2", children: [ 187 /* @__PURE__ */ jsxRuntimeExports.jsx(Gift, { className: "h-8 w-8 text-primary" }), 188 /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-3xl font-bold tracking-tight", children: "Member Lottery" }) 189 ] }), 190 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground mb-6", children: "Every registered member is automatically entered. Your member number is your ticket â no action required. Winners are drawn on the scheduled date and announced on the Events page." }), 191 /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { "aria-labelledby": "fair-draw", className: "mb-8 rounded-xl border border-border bg-muted p-5", children: [ 192 /* @__PURE__ */ jsxRuntimeExports.jsx("section", { "aria-labelledby": "first-member-recognition", className: "mb-4 rounded-xl border border-primary bg-card p-5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
193 /* @__PURE__ */ jsxRuntimeExports.jsx(Medal, { className: "mt-0.5 h-5 w-5 shrink-0 text-primary", "aria-hidden": "true" }), 194 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 195 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { id: "first-member-recognition", className: "text-lg font-bold", style: { 196 whiteSpace: "pre-line" 197 }, children: raffle_announcement.recognition.heading }), 198 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm text-muted-foreground", style: { 199 whiteSpace: "pre-line" 200 }, children: raffle_announcement.recognition.body }) 201 ] }) 202 ] }) }), 203 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ 204 /* @__PURE__ */ jsxRuntimeExports.jsx(Ticket, { className: "mt-0.5 h-5 w-5 shrink-0 text-primary", "aria-hidden": "true" }), 205 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ 206 /* @__P
206URE__ */ jsxRuntimeExports.jsx("h2", { id: "fair-draw", className: "text-lg font-bold", style: { 207 whiteSpace: "pre-line" 208 }, children: raffle_announcement.fairDraw.heading }), 209 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm text-muted-foreground", style: { 210 whiteSpace: "pre-line" 211 }, children: raffle_announcement.fairDraw.body }), 212 /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "mt-4 grid grid-cols-1 gap-3 md:grid-cols-2", children: raffle_announcement.fairDraw.rules.map((rule) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "rounded-lg border border-border bg-card p-3", children: [ 213 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold", style: { 214 whiteSpace: "pre-line" 215 }, children: rule.title }), 216 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", style: { 217 whiteSpace: "pre-line" 218 }, children: rule.body }) 219 ] }, rule.title)) }),
220 /* @__PURE__ */ jsxRuntimeExports.jsx("section", { "aria-labelledby": "raffle-privacy", className: "mt-5 rounded-lg border border-border bg-card p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ 221 /* @__PURE__ */ jsxRuntimeExports.jsx(Lock, { className: "mt-0.5 h-5 w-5 shrink-0 text-primary", "aria-hidden": "true" }), 222 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 223 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { id: "raffle-privacy", className: "text-sm font-semibold", style: { 224 whiteSpace: "pre-line" 225 }, children: raffle_announcement.privacy.heading }), 226 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm leading-relaxed text-muted-foreground", style: { 227 whiteSpace: "pre-line" 228 }, children: raffle_announcement.privacy.body }), 229 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 text-sm leading-relaxed text-muted-foreground", style: { 230 whiteSpace: "pre-line" 231 }, children: raffle_announcement.privacy.decline }) 232 ] }) 233 ] }) }),
234 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "mt-4 text-sm font-semibold", style: { 235 whiteSpace: "pre-line" 236 }, children: raffle_announcement.feedback.heading }), 237 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1 text-sm text-muted-foreground", children: [ 238 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { 239 whiteSpace: "pre-line" 240 }, children: [ 241 raffle_announcement.feedback.body, 242 " " 243 ] }), 244 /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "/contact?topic=merch-feedback", className: "font-medium text-primary underline underline-offset-2 hover:no-underline", children: "Share private feedback" }), 245 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "." }) 246 ] }) 247 ] }) 248 ] }) 249 ] }), 250 loggedIn && /* @__PURE__ */ jsxRuntimeExports.jsx("section", { "aria-labelledby": "winner-options", className: "mb-8 rounded-xl border border-border bg-card p-5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
251 /* @__PURE__ */ jsxRuntimeExports.jsx(Lock, { className: "mt-0.5 h-5 w-5 shrink-0 text-primary", "aria-hidden": "true" }), 252 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [ 253 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { id: "winner-options", className: "text-lg font-bold", style: { 254 whiteSpace: "pre-line" 255 }, children: raffle_winner_controls.winnerCenter.heading }), 256 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm leading-relaxed text-muted-foreground", style: { 257 whiteSpace: "pre-line" 258 }, children: raffle_winner_controls.winnerCenter.intro }), 259 winnerChoiceError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 text-sm text-destructive", children: winnerChoiceError }), 260 winnerRecords.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-4 text-sm text-muted-foreground", style: { 261 whiteSpace: "pre-line" 262 }, children: raffle_winner_controls.winnerCenter.noWins }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4 grid grid-cols-1 gap-3", children: winnerRecords.map((record) => /* @__PURE__ */ jsxRuntimeExports.jsxs("article", { className: "rounded-lg border border-border p-4", children: [
263 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold", children: record.raffle_title }), 264 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: record.prize }), 265 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-3 text-sm text-muted-foreground", children: record.public_identity_consent === "approved" ? raffle_winner_controls.winnerCenter.approvedStatus : raffle_winner_controls.winnerCenter.anonymousStatus }), 266 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex flex-wrap gap-2", children: [ 267 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => saveWinnerPrivacy(record.raffle_id, "anonymous"), disabled: savingWinnerId === record.raffle_id, className: "rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-60", children: savingWinnerId === record.raffle_id ? raffle_winner_controls.winnerCenter.saving : raffle_winner_controls.winnerCenter.anonymous }),
268 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => saveWinnerPrivacy(record.raffle_id, "approved"), disabled: savingWinnerId === record.raffle_id, className: "rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-60", children: savingWinnerId === record.raffle_id ? raffle_winner_controls.winnerCenter.saving : raffle_winner_controls.winnerCenter.approved }) 269 ] }) 270 ] }, record.raffle_id)) }), 271 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-4 text-xs leading-relaxed text-muted-foreground", style: { 272 whiteSpace: "pre-line" 273 }, children: raffle_winner_controls.winnerCenter.privateFulfillment }) 274 ] }) 275 ] }) }), 276 loggedIn && isStaff && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 bg-muted rounded-lg px-4 py-3 mb-8 text-sm border border-border", children: [
277 /* @__PURE__ */ jsxRuntimeExports.jsx(Lock, { className: "h-4 w-4 mt-0.5 text-muted-foreground shrink-0" }), 278 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 279 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground", children: "Staff are not eligible to enter." }), 280 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: " Admins, moderators, and the owner are excluded from all draws to avoid any conflict of interest." }) 281 ] }) 282 ] }), 283 loggedIn && !isStaff && optedOut && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 bg-muted rounded-lg px-4 py-3 mb-8 text-sm border border-border", children: [ 284 /* @__PURE__ */ jsxRuntimeExports.jsx(UserX, { className: "h-4 w-4 mt-0.5 text-muted-foreground shrink-0" }), 285 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 286 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground", children: "You're opted out of lotteries." }),
287 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: " You won't be entered in any draws. To re-enter, go to your " }), 288 /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "/profile", className: "underline text-primary hover:no-underline", children: "Profile â Notifications" }), 289 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: " and turn on lottery entries." }) 290 ] }) 291 ] }), 292 loggedIn && !isStaff && !optedOut && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 bg-green-500/10 border border-green-500/30 rounded-lg px-4 py-3 mb-8 text-sm", children: [ 293 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "h-4 w-4 mt-0.5 text-green-500 shrink-0" }), 294 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 295 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-green-700 dark:text-green-400", children: "You're automatically entered in all open draws." }),
296 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [ 297 " If you win, you may accept or decline the prize. Only members who choose delivery receive a secure link to submit shipping details.", 298 " ", 299 "To opt out, visit ", 300 /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "/profile", className: "underline text-primary hover:no-underline", children: "Profile â Notifications" }), 301 "." 302 ] }) 303 ] }) 304 ] }), 305 !loggedIn && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 bg-muted border border-border rounded-lg px-4 py-3 mb-8 text-sm", children: [ 306 /* @__PURE__ */ jsxRuntimeExports.jsx(Ticket, { className: "h-4 w-4 mt-0.5 text-primary shrink-0" }), 307 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 308 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground", children: "Members are entered automatically." }),
309 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground", children: [ 310 " ", 311 /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "/#auth", className: "underline text-primary hover:no-underline", children: "Sign in" }), 312 " or ", 313 /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "/#auth", className: "underline text-primary hover:no-underline", children: "create an account" }), 314 " to be entered in every draw." 315 ] }) 316 ] }) 317 ] }), 318 loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: [1, 2].map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-32 rounded-xl bg-muted animate-pulse" }, i)) }) : raffles.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-16 text-muted-foreground", children: [ 319 /* @__PURE__ */ jsxRuntimeExports.jsx(Trophy, { className: "h-10 w-10 mx-auto mb-3 opacity-30" }), 320 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium", children: "No active lotteries right now." }),
321 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm mt-1", children: "Check back soon â prizes are coming." }) 322 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: raffles.map((r) => { 323 const st = STATUS_LABELS[r.status] ?? STATUS_LABELS.draft; 324 const entered = r.my_ticket != null; 325 return /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: `overflow-hidden transition-all ${entered ? "border-primary/40" : ""}`, children: [ 326 r.image_url && /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: r.image_url, alt: r.title, className: "w-full h-40 object-cover" }), 327 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-3", children: [ 328 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 329 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-lg", children: r.title }),
330 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-primary font-semibold mt-0.5", children: r.prize }) 331 ] }), 332 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 shrink-0 flex-wrap justify-end", children: [ 333 (() => { 334 const tier = getTier(r.prize_tier); 335 const cfg = TIER_CONFIG[tier]; 336 return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: `inline-flex items-center gap-1 text-xs font-bold px-2 py-0.5 rounded-full ${cfg.badgeClass}`, children: [ 337 cfg.emoji, 338 " ", 339 cfg.label 340 ] }); 341 })(), 342 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: `${st.color}`, children: st.label }) 343 ] }) 344 ] }) }), 345 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-3", children: [ 346 r.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground", children: r.description }),
347 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [ 348 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [ 349 /* @__PURE__ */ jsxRuntimeExports.jsx(Ticket, { className: "h-3.5 w-3.5" }), 350 r.entry_count, 351 " ", 352 r.entry_count === 1 ? "member entered" : "members entered", 353 r.max_entries ? ` / ${r.max_entries} max` : "" 354 ] }), 355 r.draw_at && r.status !== "drawn" && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 356 "Draw: ", 357 new Date(r.draw_at).toLocaleDateString() 358 ] }), 359 r.drawn_at && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 360 "Drawn: ", 361 new Date(r.drawn_at).toLocaleDateString() 362 ] }) 363 ] }), 364 entered && r.status === "open" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm text-green-700 dark:text-green-400 font-medium", children: [
365 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheckBig, { className: "h-4 w-4" }), 366 "You're entered â Member #", 367 r.my_ticket 368 ] }), 369 r.status === "drawn" && entered && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-primary/10 border border-primary/30 rounded-lg px-4 py-3 text-sm font-medium text-primary flex items-center gap-2", children: [ 370 /* @__PURE__ */ jsxRuntimeExports.jsx(Trophy, { className: "h-4 w-4" }), 371 "Member #", 372 r.my_ticket, 373 " was in this draw." 374 ] }) 375 ] }) 376 ] }, r.id); 377 }) }), 378 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-14", children: [ 379 /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { onClick: () => setShowHallOfFame((v) => !v), className: "w-full flex items-center justify-between gap-3 group", children: [ 380 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
381 /* @__PURE__ */ jsxRuntimeExports.jsx(Medal, { className: "h-5 w-5 text-primary" }), 382 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-bold tracking-tight", children: "Hall of Fame" }), 383 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground font-normal", children: "Past winners" }) 384 ] }), 385 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground group-hover:text-foreground transition-colors", children: showHallOfFame ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "h-4 w-4" }) }) 386 ] }), 387 showHallOfFame && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LotteryHallOfFame, {}) }) 388 ] }) 389 ] }) 390 ] }) }); 391} 392export { 393 RafflePage as default 394};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.