2025-12-29 13:04:15 -08:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
2026-01-03 21:04:00 -08:00
< title > Applause for a Cause - HCA RSVP</ title >
2025-12-29 13:04:15 -08:00
< style >
body {
font-family : var ( -- wa - font - sans );
display : flex ;
flex-direction : column ;
align-items : center ;
min-height : 100 vh ;
margin : 0 ;
padding : 1 rem ;
}
2025-12-29 14:27:59 -08:00
# signin { display : none ; flex : 1 ; align-items : center ; justify-content : center ; }
2025-12-29 13:04:15 -08:00
# main { display : none ; width : 100 % ; max-width : 600 px ; }
. header {
display : flex ;
align-items : center ;
gap : 1 rem ;
margin-bottom : 2 rem ;
width : 100 % ;
}
. header img {
width : 40 px ;
height : 40 px ;
border-radius : 50 % ;
}
. header . spacer { flex : 1 ; }
2025-12-29 13:17:02 -08:00
. event-header {
text-align : center ;
margin-bottom : 1.5 rem ;
}
. event-header img {
height : 120 px ;
border-radius : 8 px ;
margin-bottom : 1 rem ;
}
. event-header p {
margin : 0.25 rem 0 ;
opacity : 0.7 ;
}
. rsvp-section {
margin-top : 1.5 rem ;
padding-top : 1.5 rem ;
border-top : 1 px solid var ( -- wa - color - neutral -80 );
}
2025-12-30 09:38:28 -08:00
. button-group {
2025-12-29 13:17:02 -08:00
display : flex ;
2025-12-30 09:38:28 -08:00
flex-wrap : wrap ;
gap : 0.5 rem ;
margin-top : 0.5 rem ;
2025-12-29 13:17:02 -08:00
}
2025-12-30 10:00:55 -08:00
. donation-group {
2025-12-30 12:40:46 -08:00
display : flex ;
flex-wrap : wrap ;
2025-12-29 14:20:03 -08:00
gap : 0.5 rem ;
2025-12-30 09:38:28 -08:00
}
2025-12-30 10:00:55 -08:00
. donation-group wa-button :: part ( base ) {
height : 80 px ;
2025-12-30 09:38:28 -08:00
display : flex ;
align-items : center ;
2025-12-30 10:00:55 -08:00
justify-content : center ;
}
. donation-group wa-button [ data-value = "custom" ] :: part ( base ) {
flex-direction : column ;
}
. donation-group wa-input {
width : 80 px ;
margin-top : 0.4 rem ;
--wa-focus-ring-width : 0 ;
--wa-input-border-width : 0 ;
2025-12-30 10:41:44 -08:00
--wa-input-focus-ring-color : transparent ;
--wa-input-border-color : transparent ;
--wa-input-border-color-focus : transparent ;
2025-12-30 10:00:55 -08:00
}
wa-input [ type = "number" ] :: part ( input ) {
-moz- appearance : textfield ;
text-align : center ;
}
2025-12-30 10:41:44 -08:00
. donation-group wa-input :: part ( base ) {
border : none ;
box-shadow : none ;
outline : none ;
}
. donation-group wa-input :: part ( base ) : focus-within {
border : none ;
box-shadow : none ;
outline : none ;
}
2025-12-30 10:00:55 -08:00
wa-input [ type = "number" ] :: part ( input ) :: -webkit-inner-spin-button ,
wa-input [ type = "number" ] :: part ( input ) :: -webkit-outer-spin-button {
-webkit- appearance : none ;
margin : 0 ;
}
2025-12-30 10:41:44 -08:00
wa-button . selected :: part ( base ) {
2025-12-30 10:00:55 -08:00
background-color : #FEDE02 ;
color : #000 ;
}
. donation-section {
margin-top : 1 rem ;
padding-top : 1 rem ;
border-top : 1 px solid var ( -- wa - color - neutral -80 );
2025-12-29 14:20:03 -08:00
}
. thank-you {
background : var ( -- wa - color - success -95 );
color : var ( -- wa - color - success -30 );
padding : 1 rem ;
border-radius : 8 px ;
margin-bottom : 1 rem ;
}
. wa-dark . thank-you {
background : var ( -- wa - color - success -20 );
color : var ( -- wa - color - success -90 );
}
2025-12-30 12:40:46 -08:00
. info-box {
background : var ( -- wa - color - neutral -95 );
color : var ( -- wa - color - neutral -20 );
padding : 1 rem ;
border-radius : 8 px ;
margin-bottom : 1 rem ;
font-size : 0.9 rem ;
}
. wa-dark . info-box {
background : var ( -- wa - color - neutral -20 );
color : var ( -- wa - color - neutral -90 );
}
. donation-group wa-button {
width : calc ( 50 % - 0.25 rem );
}
2025-12-29 13:04:15 -08:00
</ style >
</ head >
< body style = "opacity: 0" >
< div id = "signin" ></ div >
< div id = "main" >
< div class = "header" >
< img data-bind = "picture" alt = "Profile" >
< span data-bind = "name" ></ span >
< span class = "spacer" ></ span >
< wa-button variant = "neutral" size = "small" id = "logout-btn" > Switch User</ wa-button >
</ div >
2026-01-03 21:19:59 -08:00
< div id = "thank-you" class = "thank-you" style = "display: none;" ></ div >
2025-12-29 13:17:02 -08:00
< wa-card >
< div class = "event-header" >
< img src = "/afac26-logo.png" alt = "Applause for a Cause" >
2026-01-03 21:04:00 -08:00
< p > Saturday, February 7, 2026 · 6:30 PM</ p >
2025-12-29 13:17:02 -08:00
< p > Helios Gym</ p >
2026-01-03 21:04:00 -08:00
< p > 597 Central Avenue, Sunnyvale, CA 94086</ p >
2025-12-29 13:17:02 -08:00
</ div >
2025-12-30 12:40:46 -08:00
< div class = "info-box" >
2026-01-03 21:04:00 -08:00
< p style = "margin: 0 0 0.5rem 0;" > Tickets are pay-what-you-wish. All donations go to < a href = "https://svcommunityservices.org/" target = "_blank" > Sunnyvale Community Services</ a > . We suggest $25 per family, but most importantly we'd love to see you there!</ p >
2025-12-30 12:40:46 -08:00
< p style = "margin: 0;" > Feel free to share this page with friends and family.</ p >
</ div >
2025-12-29 13:17:02 -08:00
< div class = "rsvp-section" >
2026-01-03 21:04:00 -08:00
< div id = "rsvp-header" style = "font-weight: bold; margin-bottom: 1rem;" > RSVP now to reserve your seats!</ div >
< div > Number of people (including performers):</ div >
2025-12-30 12:04:13 -08:00
< div class = "button-group" id = "num-people-group" >
< wa-button size = "small" variant = "neutral" data-value = "0" > 0</ wa-button >
< wa-button size = "small" variant = "neutral" class = "selected" data-value = "1" > 1</ wa-button >
< wa-button size = "small" variant = "neutral" data-value = "2" > 2</ wa-button >
< wa-button size = "small" variant = "neutral" data-value = "3" > 3</ wa-button >
< wa-button size = "small" variant = "neutral" data-value = "4" > 4</ wa-button >
< wa-button size = "small" variant = "neutral" data-value = "5" > 5</ wa-button >
< wa-button size = "small" variant = "neutral" data-value = "6" > 6</ wa-button >
< wa-button size = "small" variant = "neutral" data-value = "7" > 7</ wa-button >
< wa-button size = "small" variant = "neutral" data-value = "8" > 8</ wa-button >
2025-12-29 13:17:02 -08:00
</ div >
2025-12-30 12:04:13 -08:00
< div class = "donation-section" >
2025-12-30 12:18:15 -08:00
< div id = "donation-status" style = "display: none; font-weight: bold; margin-bottom: 1rem;" ></ div >
2025-12-30 12:12:55 -08:00
< div id = "donation-header" > Would you like to make a donation?</ div >
2025-12-30 12:04:13 -08:00
< div class = "button-group donation-group" id = "donation-group" >
< wa-button variant = "neutral" class = "selected" data-value = "25" > $25</ wa-button >
< wa-button variant = "neutral" data-value = "50" > $50</ wa-button >
< wa-button variant = "neutral" data-value = "custom" >< span > Other</ span >< wa-input type = "number" size = "small" id = "custom-amount" min = "1" value = "100" >< span slot = "start" > $</ span ></ wa-input ></ wa-button >
< wa-button variant = "neutral" data-value = "0" > Maybe later</ wa-button >
2025-12-29 14:20:03 -08:00
</ div >
2025-12-29 13:17:02 -08:00
</ div >
2025-12-30 12:04:13 -08:00
< hr style = "margin-top: 1rem; border: none; border-top: 1px solid var(--wa-color-neutral-80);" >
< div style = "text-align: center; margin-top: 1rem;" >
< wa-button variant = "brand" id = "rsvp-btn" > Submit RSVP</ wa-button >
</ div >
2025-12-29 13:17:02 -08:00
</ div >
2025-12-29 13:04:15 -08:00
</ wa-card >
2025-12-29 14:27:59 -08:00
< wa-button variant = "text" size = "small" href = "/" style = "margin-top: 2rem; margin-left: 3px;" > « Events</ wa-button >
2025-12-29 13:04:15 -08:00
</ div >
< script type = "module" >
2025-12-29 13:17:02 -08:00
import { auth , logout , api } from '/app.js' ;
2025-12-29 13:04:15 -08:00
await auth ();
document . getElementById ( 'main' ). style . display = 'block' ;
document . getElementById ( 'logout-btn' ). addEventListener ( 'click' , logout );
2025-12-29 13:17:02 -08:00
const eventId = 'afac26' ;
2026-01-03 21:19:59 -08:00
function showConfirmation ( numPeople , donatedAmount ) {
const parts = [];
if ( numPeople > 0 ) {
const word = numPeople === 1 ? 'person' : 'people' ;
parts . push ( `Your RSVP for ${ numPeople } ${ word } is confirmed.` );
}
if ( donatedAmount ) {
parts . push ( `Thank you for your $ ${ donatedAmount . toFixed ( 2 ) } donation!` );
}
if ( parts . length ) {
document . getElementById ( 'thank-you' ). textContent = parts . join ( ' ' );
document . getElementById ( 'thank-you' ). style . display = 'block' ;
}
}
const params = new URLSearchParams ( location . search );
const donatedParam = params . get ( 'donated' );
const numPeopleParam = params . get ( 'num_people' );
if ( donatedParam || numPeopleParam ) {
showConfirmation ( parseInt ( numPeopleParam ) || 0 , donatedParam ? parseFloat ( donatedParam ) : null );
2026-01-03 21:21:39 -08:00
document . getElementById ( 'thank-you' ). scrollIntoView ({ behavior : 'smooth' , block : 'center' });
2025-12-29 14:20:03 -08:00
history . replaceState ({}, '' , location . pathname );
}
2025-12-30 09:38:28 -08:00
let selectedNumPeople = 1 ;
let selectedDonation = 25 ;
2025-12-30 12:04:13 -08:00
function setupButtonGroup ( groupId , onChange ) {
2025-12-30 09:38:28 -08:00
const group = document . getElementById ( groupId );
group . querySelectorAll ( 'wa-button' ). forEach ( btn => {
2025-12-30 10:00:55 -08:00
btn . addEventListener ( 'click' , ( e ) => {
if ( e . target . tagName === 'WA-INPUT' ) return ;
2025-12-30 12:04:13 -08:00
group . querySelectorAll ( 'wa-button' ). forEach ( b => b . classList . remove ( 'selected' ));
btn . classList . add ( 'selected' );
2025-12-30 09:38:28 -08:00
onChange ( btn . dataset . value );
});
2025-12-29 14:20:03 -08:00
});
2025-12-30 09:38:28 -08:00
}
setupButtonGroup ( 'num-people-group' , val => {
selectedNumPeople = parseInt ( val );
2025-12-30 12:04:13 -08:00
});
2025-12-30 09:38:28 -08:00
setupButtonGroup ( 'donation-group' , val => {
selectedDonation = val === 'custom' ? 'custom' : ( val === '0' ? 0 : parseInt ( val ));
2025-12-30 12:04:13 -08:00
});
2025-12-30 09:38:28 -08:00
2025-12-30 10:41:44 -08:00
document . getElementById ( 'custom-amount' ). addEventListener ( 'focus' , () => {
const group = document . getElementById ( 'donation-group' );
group . querySelectorAll ( 'wa-button' ). forEach ( b => b . classList . remove ( 'selected' ));
group . querySelector ( 'wa-button[data-value="custom"]' ). classList . add ( 'selected' );
selectedDonation = 'custom' ;
});
2025-12-29 13:17:02 -08:00
async function loadRSVP () {
const data = await api ( 'GET' , `/api/rsvp/ ${ eventId } ` );
updateUI ( data );
}
function updateUI ( data ) {
2025-12-30 12:04:13 -08:00
const hasRSVP = data . numPeople > 0 ;
const hasDonation = data . donation > 0 ;
if ( hasRSVP ) {
2025-12-29 13:17:02 -08:00
const word = data . numPeople === 1 ? 'person' : 'people' ;
2025-12-30 12:18:15 -08:00
document . getElementById ( 'rsvp-header' ). textContent = `You've RSVPed for ${ data . numPeople } ${ word } .` ;
2025-12-29 13:17:02 -08:00
} else {
2026-01-03 21:04:00 -08:00
document . getElementById ( 'rsvp-header' ). textContent = 'RSVP now to reserve your seats!' ;
2025-12-30 12:04:13 -08:00
}
const donationStatus = document . getElementById ( 'donation-status' );
if ( hasDonation ) {
donationStatus . textContent = `You've donated $ ${ data . donation . toFixed ( 2 ) } . Thank you!` ;
donationStatus . style . display = 'block' ;
document . getElementById ( 'donation-header' ). textContent = 'Make an additional donation?' ;
} else {
donationStatus . style . display = 'none' ;
document . getElementById ( 'donation-header' ). textContent = 'Would you like to make a donation?' ;
}
document . getElementById ( 'rsvp-btn' ). textContent = ( hasRSVP || hasDonation ) ? 'Update RSVP' : 'Submit RSVP' ;
const numGroup = document . getElementById ( 'num-people-group' );
numGroup . querySelectorAll ( 'wa-button' ). forEach ( b => b . classList . remove ( 'selected' ));
selectedNumPeople = data . numPeople || 1 ;
const currentBtn = numGroup . querySelector ( `wa-button[data-value=" ${ selectedNumPeople } "]` );
if ( currentBtn ) currentBtn . classList . add ( 'selected' );
if ( hasRSVP || hasDonation ) {
const donationGroup = document . getElementById ( 'donation-group' );
donationGroup . querySelectorAll ( 'wa-button' ). forEach ( b => b . classList . remove ( 'selected' ));
donationGroup . querySelector ( 'wa-button[data-value="0"]' ). classList . add ( 'selected' );
selectedDonation = 0 ;
2025-12-29 13:17:02 -08:00
}
}
document . getElementById ( 'rsvp-btn' ). addEventListener ( 'click' , async () => {
2025-12-30 11:46:58 -08:00
let donationCents = 0 ;
if ( selectedDonation === 'custom' ) {
donationCents = ( parseInt ( document . getElementById ( 'custom-amount' ). value ) || 0 ) * 100 ;
} else if ( selectedDonation > 0 ) {
donationCents = selectedDonation * 100 ;
2025-12-30 09:38:28 -08:00
}
2025-12-30 11:46:58 -08:00
const data = await api ( 'POST' , `/api/rsvp/ ${ eventId } ` , { numPeople : selectedNumPeople , donationCents });
if ( data . url ) {
location . href = data . url ;
} else {
updateUI ( data );
2026-01-03 21:19:59 -08:00
showConfirmation ( data . numPeople , null );
2025-12-29 14:20:03 -08:00
}
2025-12-29 13:17:02 -08:00
});
await loadRSVP ();
2025-12-29 13:04:15 -08:00
await customElements . whenDefined ( 'wa-card' );
document . body . style . opacity = 1 ;
</ script >
</ body >
</ html >