diff --git a/api/supabase/queries/onboarding.ts b/api/supabase/queries/onboarding.ts index 3505ee4..dac65a5 100644 --- a/api/supabase/queries/onboarding.ts +++ b/api/supabase/queries/onboarding.ts @@ -7,45 +7,156 @@ export async function submitOnboardingData( role: Role, ): Promise { try { + const { data: sessionData, error: sessionError } = + await supabase.auth.getSession(); + + if (sessionError || !sessionData?.session) { + console.error('Session retrieval error:', sessionError); + throw new Error('Failed to retrieve user session.'); + } + + const user_id = sessionData.session.user.id; + const email = sessionData.session.user.email; + + const volunteerPayload = { + user_id, + email, + first_name: generalInfo.firstName, + last_name: generalInfo.lastName, + phone_number: generalInfo.phoneNumber, + notifications_opt_in: generalInfo.notifications, + }; + const { data: volunteerData, error: volunteerError } = await supabase .from('volunteers') - .insert([ - { - first_name: generalInfo.firstName, - last_name: generalInfo.lastName, - phone_number: generalInfo.phoneNumber, - notifications_opt_in: generalInfo.notifications, - }, - ]); - - if (volunteerError) + .upsert([volunteerPayload], { onConflict: 'user_id' }); + + if (volunteerError) { + console.error('Error upserting volunteer data:', volunteerError); throw new Error(`Volunteer data error: ${volunteerError.message}`); + } + + const preferencesPayload = { + user_id, + role: [ + ...(role.isPerformer ? ['performer'] : []), + ...(role.isHost ? ['host'] : []), + ], + facility_type: preferences.facilityType, + locations: preferences.location, + audience_type: preferences.audience, + performer_type: preferences.performerType, + performance_type: preferences.performanceType, + genre: preferences.genre, + additional_info: preferences.additionalInfo, + }; const { data: preferencesData, error: preferencesError } = await supabase .from('volunteer_preferences') - .insert([ - { - role: [ - role.isPerformer ? 'performer' : null, - role.isHost ? 'host' : null, - ].filter(Boolean), - facility_type: preferences.facilityType, - locations: preferences.location, - audience_type: preferences.audience, - performer_type: preferences.performerType, - performance_type: preferences.performanceType, - genre: preferences.genre, - }, - ]); - - if (preferencesError) + .insert([preferencesPayload]); + + if (preferencesError) { + console.error('Error inserting preferences data:', preferencesError); throw new Error(`Preferences data error: ${preferencesError.message}`); + } console.log('Onboarding data submitted successfully:', { volunteerData, preferencesData, }); } catch (error) { - console.error('Error submitting onboarding data:', error); + console.error('Error during onboarding data submission:', error); + throw error; + } +} + +export async function submitGeneralInfo( + generalInfo: GeneralInfo, +): Promise { + try { + const { data: sessionData, error: sessionError } = + await supabase.auth.getSession(); + if (sessionError || !sessionData?.session) { + throw new Error('Failed to retrieve user session.'); + } + + const user_id = sessionData.session.user.id; + const email = sessionData.session.user.email; + + const generalInfoPayload = { + user_id, + email, + first_name: generalInfo.firstName, + last_name: generalInfo.lastName, + phone_number: generalInfo.phoneNumber, + notifications_opt_in: generalInfo.notifications, + }; + + const { data, error: volunteerError } = await supabase + .from('volunteers') + .upsert([generalInfoPayload], { onConflict: 'user_id' }); + + if (volunteerError) { + throw new Error(`General info data error: ${volunteerError.message}`); + } + + console.log('Upserted general info data:', data); + } catch (error) { + throw error; + } +} + +export async function submitPreferences( + preferences: Preferences, + role: Role, +): Promise { + try { + console.log('Starting preferences data submission...'); + + const { data: sessionData, error: sessionError } = + await supabase.auth.getSession(); + console.log('Session data retrieved:', sessionData); + + if (sessionError || !sessionData?.session) { + console.error('Session retrieval error:', sessionError); + throw new Error('Failed to retrieve user session.'); + } + + const user_id = sessionData.session.user.id; + + const preferencesPayload = { + user_id, + role: [ + ...(role.isPerformer ? ['performer'] : []), + ...(role.isHost ? ['host'] : []), + ], + facility_type: preferences.facilityType, + locations: preferences.location, + audience_type: preferences.audience, + performer_type: preferences.performerType, + performance_type: preferences.performanceType, + genre: preferences.genre, + additional_info: preferences.additionalInfo, + }; + console.log('Preferences payload:', preferencesPayload); + + const { data: preferencesData, error: preferencesError } = await supabase + .from('volunteer_preferences') + .upsert([preferencesPayload]); + + if (preferencesError) { + console.error('Error upserting preferences data:', preferencesError); + throw new Error( + `Preferences data error (only preferences): ${preferencesError.message}`, + ); + } + console.log('Preferences data upserted successfully:', preferencesData); + + console.log('Onboarding data submitted successfully:', { + preferencesData, + }); + } catch (error) { + console.error('Error during onboarding data submission:', error); + throw error; } } diff --git a/app/onboarding/performance/page.tsx b/app/onboarding/performance/page.tsx index 3b0a256..6cabcb4 100644 --- a/app/onboarding/performance/page.tsx +++ b/app/onboarding/performance/page.tsx @@ -113,6 +113,7 @@ export default function Onboarding() { multi onChange={handlePerformanceTypeChange} options={performanceTypeOptions} + value={new Set(preferences.performanceType)} /> diff --git a/app/onboarding/review/page.tsx b/app/onboarding/review/page.tsx index 602ac7c..8cef44c 100644 --- a/app/onboarding/review/page.tsx +++ b/app/onboarding/review/page.tsx @@ -8,13 +8,13 @@ import { SMALL } from '@/styles/text'; import { OnboardingContext } from '@/utils/onboardingContext'; import { Background, - Button, Image, InlineContainer, Label, ProgressBarContainer, Rectangle, StyledLink, + SubmitButton, Title, } from '../styles'; import { BackButton, Line, ReviewContainer, SmallText } from './styles'; @@ -88,11 +88,11 @@ export default function Review() { - + diff --git a/app/onboarding/role-selection/page.tsx b/app/onboarding/role-selection/page.tsx index 8fb1f60..8dc793e 100644 --- a/app/onboarding/role-selection/page.tsx +++ b/app/onboarding/role-selection/page.tsx @@ -47,7 +47,7 @@ export default function Onboarding() { }); }; - const handleContinue = () => { + const handleContinue = async () => { router.push('/onboarding/basic-information'); }; diff --git a/app/onboarding/show-preference/page.tsx b/app/onboarding/show-preference/page.tsx index 79bc3c2..53ac116 100644 --- a/app/onboarding/show-preference/page.tsx +++ b/app/onboarding/show-preference/page.tsx @@ -99,6 +99,7 @@ export default function Onboarding() { multi onChange={handleFacilityChange} options={facilityTypeOptions} + value={new Set(preferences.facilityType)} /> diff --git a/app/onboarding/styles.ts b/app/onboarding/styles.ts index 2eefc8b..21cfa72 100644 --- a/app/onboarding/styles.ts +++ b/app/onboarding/styles.ts @@ -149,6 +149,30 @@ export const Button = styled.button<{ disabled?: boolean }>` bottom: 70px; width: 30%; height: 2.75rem; + background-color: ${({ disabled }) => + disabled ? COLORS.pomegranate10 : COLORS.pomegranate12}; + border-color: ${({ disabled }) => + disabled ? COLORS.pomegranate10 : COLORS.pomegranate12}; + border-style: solid; + border-radius: 8px; + display: inline-flex; + padding: 8px 16px; + justify-content: center; + align-items: center; + cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')}; + text-decoration: none; + transition: all 0.3s ease; + + @media (max-width: 768px) { + width: 85%; + bottom: 40px; + } +`; + +export const SubmitButton = styled.button<{ disabled?: boolean }>` + margin-top: 42px; + width: 100%; + height: 2.75rem; background-color: ${({ disabled }) => disabled ? COLORS.pomegranate10 : COLORS.pomegranate}; border-color: ${({ disabled }) => diff --git a/components/InputDropdown/InputDropdown.tsx b/components/InputDropdown/InputDropdown.tsx index aa53f86..97dcd5d 100644 --- a/components/InputDropdown/InputDropdown.tsx +++ b/components/InputDropdown/InputDropdown.tsx @@ -25,6 +25,7 @@ interface CommonProps { error?: string; disabled?: boolean; required?: boolean; + value: Set; } interface MultiSelectProps extends CommonProps { @@ -51,8 +52,6 @@ function AnimatedMenu(props: MenuProps) { ); } - -// main dropdown component export default function InputDropdown({ label, options, @@ -62,6 +61,7 @@ export default function InputDropdown({ required, onChange, multi, + value, }: InputDropdownProps) { const optionsArray = useMemo( () => @@ -74,6 +74,26 @@ export default function InputDropdown({ [options], ); + const transformedValue = useMemo(() => { + if (multi) { + return Array.from(value).map(v => ({ + value: v, + label: options instanceof Map ? options.get(v) || v : v, + })); + } else { + const singleValue = Array.from(value)[0]; + return singleValue + ? { + value: singleValue, + label: + options instanceof Map + ? options.get(singleValue) || singleValue + : singleValue, + } + : null; + } + }, [value, multi, options]); + const handleChange = useCallback( (newValue: MultiValue | SingleValue) => { if (multi && newValue instanceof Array) { @@ -111,6 +131,7 @@ export default function InputDropdown({ placeholder={placeholder} isMulti={multi} onChange={handleChange} + value={transformedValue} // Pass the transformed value here /> {error && {error}} diff --git a/styles/colors.ts b/styles/colors.ts index 1f35755..4122278 100644 --- a/styles/colors.ts +++ b/styles/colors.ts @@ -53,6 +53,7 @@ const COLORS = { pomegranate: '#342A2F', pomegranate10: '#6F585E', + pomegranate12: '#342A2F', }; export default COLORS; diff --git a/utils/onboardingContext.tsx b/utils/onboardingContext.tsx index 0566263..5aecd7d 100644 --- a/utils/onboardingContext.tsx +++ b/utils/onboardingContext.tsx @@ -1,7 +1,6 @@ 'use client'; import React, { createContext, ReactNode, useState } from 'react'; -import supabase from '@/api/supabase/createClient'; export interface Role { isHost: boolean; @@ -32,7 +31,6 @@ interface OnboardingContextType { setPreferences: (preferences: Preferences) => void; role: Role; setRole: (role: Role) => void; - submitOnboardingData: () => Promise; } export const OnboardingContext = createContext< @@ -44,7 +42,7 @@ export const OnboardingProvider = ({ children }: { children: ReactNode }) => { firstName: '', lastName: '', phoneNumber: '', - notifications: false, + notifications: true, }); const [preferences, setPreferences] = useState({ @@ -62,50 +60,6 @@ export const OnboardingProvider = ({ children }: { children: ReactNode }) => { isPerformer: false, }); - const submitOnboardingData = async () => { - try { - const { data: volunteerData, error: volunteerError } = await supabase - .from('volunteers') - .insert([ - { - first_name: generalInfo.firstName, - last_name: generalInfo.lastName, - phone_number: generalInfo.phoneNumber, - notifications_opt_in: generalInfo.notifications, - }, - ]); - - if (volunteerError) throw volunteerError; - - const { data: preferencesData, error: preferencesError } = await supabase - .from('volunteer_preferences') - .insert([ - { - role: [ - role.isPerformer ? 'performer' : null, - role.isHost ? 'host' : null, - ].filter(Boolean), - facility_type: preferences.facilityType, - locations: preferences.location, - audience_type: preferences.audience, - performance_type: preferences.performanceType, - genre: preferences.genre, - performer_type: preferences.performerType, - additional_info: preferences.additionalInfo, - }, - ]); - - if (preferencesError) throw preferencesError; - - console.log('Onboarding data submitted successfully:', { - volunteerData, - preferencesData, - }); - } catch (error) { - console.error('Error submitting onboarding data:', error); - } - }; - return ( { setPreferences, role, setRole, - submitOnboardingData, }} > {children}