Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] Uperting profiles to Supabase for onboarding #12

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions api/supabase/queries/profiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Profile } from '@/types/schema';
import supabase from '../createClient';

export async function upsertProfile(profile: Profile) {
const { data, error } = await supabase
.from('profiles')
.upsert(profile)
.select()
.single();

if (error) throw new Error(`Error upserting profile data: ${error.message}`);

return data;
}
172 changes: 172 additions & 0 deletions app/onboarding/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
'use client';

import React, { useState } from 'react';
import { upsertProfile } from '@/api/supabase/queries/profiles';
import { Profile } from '@/types/schema';

// Define the possible options for each question
const states = ['Tennessee', 'Missouri'];
const gardenTypes = ['Individual', 'Community', 'School'];
const plotOptions = [
{ label: 'yes', value: true },
{ label: 'no', value: false },
];
//Interfaces and props to avoid typ errors on Lint
interface StateSelectionProps {
selectedState: string;
setSelectedState: React.Dispatch<React.SetStateAction<string>>;
}

interface GardenTypeSelectionProps {
selectedGardenType: string;
setSelectedGardenType: React.Dispatch<React.SetStateAction<string>>;
}

interface PlotSelectionProps {
selectedPlot: boolean | null;
setSelectedPlot: React.Dispatch<React.SetStateAction<boolean>>;
}

// Select State
const StateSelection: React.FC<StateSelectionProps> = ({
selectedState,
setSelectedState,
}) => {
return (
<div>
<h2>Which state do you live in?</h2>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will probably be a radio button as well eventually, but this is all right for now!

<select
value={selectedState}
onChange={e => setSelectedState(e.target.value)}
>
<option value="" disabled>
Select a state
</option>
{states.map(state => (
<option key={state} value={state}>
{state}
</option>
))}
</select>
</div>
);
};

// Step 2: Select garden type

const GardenTypeSelection: React.FC<GardenTypeSelectionProps> = ({
selectedGardenType,
setSelectedGardenType,
}) => {
return (
<div>
<h2>What type of garden do you want to create?</h2>
{gardenTypes.map(type => (
<label key={type}>
<input
type="radio"
name="gardenType"
value={type}
checked={selectedGardenType === type}
onChange={e => setSelectedGardenType(e.target.value)}
/>
{type}
</label>
))}
</div>
);
};

// Step 3: Do you have a plot?
const PlotSelection: React.FC<PlotSelectionProps> = ({
selectedPlot,
setSelectedPlot,
}) => {
return (
<div>
<h2>Do you already have a plot?</h2>
{plotOptions.map(option => (
<label key={option.label}>
<input
type="radio"
name="plot"
value={String(option.value)}
checked={selectedPlot === option.value}
onChange={() => setSelectedPlot(option.value)}
/>
{option.label}
</label>
))}
</div>
);
};

// Main Onboarding Component
const OnboardingFlow = () => {
const [step, setStep] = useState(1);
const [selectedState, setSelectedState] = useState<string>('');
const [selectedGardenType, setSelectedGardenType] = useState<string>('');
const [selectedPlot, setSelectedPlot] = useState<boolean>(false);

const handleNext = () => {
setStep(step + 1);
};

const handleBack = () => {
setStep(step - 1);
};

const handleSubmit = async () => {
const profile: Profile = {
user_id: '2abd7296-374a-42d1-bb4f-b813da1615ae',
state: selectedState,
user_type: selectedGardenType,
has_plot: selectedPlot,
};
try {
upsertProfile(profile);
} catch (error) {
console.error('Error upserting profile:', error);
throw new Error('Error upserting profile');
} finally {
//TODO: Remove console log.
console.log('Submitted data: ', profile);
}
// Handle form submission, e.g., send to a server or display a confirmation
};

return (
<div>
{step === 1 && (
<StateSelection
selectedState={selectedState}
setSelectedState={setSelectedState}
/>
)}
{step === 2 && (
<GardenTypeSelection
selectedGardenType={selectedGardenType}
setSelectedGardenType={setSelectedGardenType}
/>
)}
{step === 3 && (
<PlotSelection
selectedPlot={selectedPlot}
setSelectedPlot={setSelectedPlot}
/>
)}

<div>
{step > 1 && <button onClick={handleBack}>Back</button>}
{step < 3 && (
<button onClick={handleNext} disabled={!selectedState && step === 1}>
Next
</button>
)}
{step === 3 && <button onClick={handleSubmit}>Submit</button>}
</div>
</div>
);
};

export default OnboardingFlow;
33 changes: 33 additions & 0 deletions app/onboarding/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import styled from 'styled-components';
import COLORS from '@/styles/colors';

export const PageContainer = styled.div`
width: 100%;
height: 100svh;
background-color: ${COLORS.seed};
`;
export const ContentContainer = styled.div`
display: flex; /* Enable flexbox */
flex-direction: column;
align-items: center;
justify-content: center;

height: 100vh;
`;

export const ButtonContainer = styled.div`
display: flex; /* Enable flexbox */
flex-direction: row;
align-items: center;
justify-content: center;
gap: 10px;
`;

export const Button = styled.button`
width: 9.375rem;
height: 3.125rem;
border-radius: 25rem;
border-width: 0px;
background-color: ${COLORS.sprout};
color: white;
`;
9 changes: 9 additions & 0 deletions styles/colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const COLORS = {
// background white
seed: '#FFFBF2',

//greens
shrub: '#1F5A2A',
sprout: '#94B506',
};
export default COLORS;
7 changes: 7 additions & 0 deletions types/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import type { UUID } from 'crypto';

export type Season = 'SPRING' | 'SUMMER' | 'FALL' | 'WINTER';

export interface Profile {
user_id: UUID;
state: string;
user_type: string;
has_plot: boolean;
}

export interface Plant {
id: UUID;
plant_name: string;
Expand Down
Loading