diff --git a/frontend/src/components/OnboardingSteps/AvatarSelectionStep.tsx b/frontend/src/components/OnboardingSteps/AvatarSelectionStep.tsx index c96136ce1..030d6585a 100644 --- a/frontend/src/components/OnboardingSteps/AvatarSelectionStep.tsx +++ b/frontend/src/components/OnboardingSteps/AvatarSelectionStep.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { setAvatar, setName, @@ -18,11 +18,12 @@ import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { avatars } from '@/constants/avatars'; import { AppFeatures } from '@/components/OnboardingSteps/AppFeatures'; +import { RootState } from '@/app/store'; interface AvatarNameSelectionStepProps { stepIndex: number; totalSteps: number; - currentStepDisplayIndex: number; + currentStepDisplayIndex?: number; } export const AvatarSelectionStep: React.FC = ({ @@ -32,14 +33,26 @@ export const AvatarSelectionStep: React.FC = ({ }) => { const dispatch = useDispatch(); - const [name, setLocalName] = useState(''); - const [selectedAvatar, setLocalAvatar] = useState(''); + const displayIndex = currentStepDisplayIndex ?? stepIndex; + + const [name, setLocalName] = useState(localStorage.getItem('name') || ''); + const [selectedAvatar, setLocalAvatar] = useState( + localStorage.getItem('avatar') || '', + ); + + const isEditing = useSelector( + (state: RootState) => state.onboarding.isEditing, + ); useEffect(() => { - if (localStorage.getItem('name') && localStorage.getItem('avatar')) { + if ( + localStorage.getItem('name') && + localStorage.getItem('avatar') && + !isEditing + ) { dispatch(markCompleted(stepIndex)); } - }, []); + }, [dispatch, isEditing, stepIndex]); const handleAvatarSelect = (avatar: string) => { setLocalAvatar(avatar); @@ -57,7 +70,11 @@ export const AvatarSelectionStep: React.FC = ({ dispatch(markCompleted(stepIndex)); }; - if (localStorage.getItem('name') && localStorage.getItem('avatar')) { + if ( + localStorage.getItem('name') && + localStorage.getItem('avatar') && + !isEditing + ) { return null; } @@ -67,20 +84,20 @@ export const AvatarSelectionStep: React.FC = ({
- Step {currentStepDisplayIndex + 1} of {totalSteps} - - - {Math.round(((currentStepDisplayIndex + 1) / totalSteps) * 100)}% + Step {displayIndex + 1} of {totalSteps} + {Math.round(((displayIndex + 1) / totalSteps) * 100)}%
+
+ Welcome to PictoPy @@ -103,7 +120,6 @@ export const AvatarSelectionStep: React.FC = ({ />
- {/* Avatar Grid */}
diff --git a/frontend/src/components/OnboardingSteps/FolderSetupStep.tsx b/frontend/src/components/OnboardingSteps/FolderSetupStep.tsx index 13a944413..461f0801a 100644 --- a/frontend/src/components/OnboardingSteps/FolderSetupStep.tsx +++ b/frontend/src/components/OnboardingSteps/FolderSetupStep.tsx @@ -9,9 +9,13 @@ import { } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { FolderOpen, X, Folder } from 'lucide-react'; -import { useDispatch } from 'react-redux'; -import { AppDispatch } from '@/app/store'; -import { markCompleted, previousStep } from '@/features/onboardingSlice'; +import { useDispatch, useSelector } from 'react-redux'; +import { AppDispatch, RootState } from '@/app/store'; +import { + markCompleted, + previousStep, + setIsEditing, +} from '@/features/onboardingSlice'; import { AppFeatures } from '@/components/OnboardingSteps/AppFeatures'; import { useFolder } from '@/hooks/useFolder'; import { useEffect, useState } from 'react'; @@ -19,7 +23,7 @@ import { useEffect, useState } from 'react'; interface FolderSetupStepProps { stepIndex: number; totalSteps: number; - currentStepDisplayIndex: number; + currentStepDisplayIndex?: number; } export function FolderSetupStep({ @@ -29,14 +33,18 @@ export function FolderSetupStep({ }: FolderSetupStepProps) { const dispatch = useDispatch(); - // Local state for folders + const displayIndex = currentStepDisplayIndex ?? stepIndex; + const [folder, setFolder] = useState(''); + const isEditing = useSelector( + (state: RootState) => state.onboarding.isEditing, + ); useEffect(() => { - if (localStorage.getItem('folderChosen') === 'true') { + if (localStorage.getItem('folderChosen') === 'true' && !isEditing) { dispatch(markCompleted(stepIndex)); } - }, []); + }, [dispatch, isEditing, stepIndex]); const { pickSingleFolder, addFolderMutate } = useFolder({ title: 'Select folder to import photos from', @@ -60,15 +68,15 @@ export function FolderSetupStep({ }; const handleBack = () => { + dispatch(setIsEditing(true)); dispatch(previousStep()); }; - if (localStorage.getItem('folderChosen') === 'true') { + if (localStorage.getItem('folderChosen') === 'true' && !isEditing) { return null; } - const progressPercent = Math.round( - ((currentStepDisplayIndex + 1) / totalSteps) * 100, - ); + + const progressPercent = Math.round(((displayIndex + 1) / totalSteps) * 100); return ( <> @@ -76,10 +84,11 @@ export function FolderSetupStep({
- Step {currentStepDisplayIndex + 1} of {totalSteps} + Step {displayIndex + 1} of {totalSteps} {progressPercent}%
+
+ {!folder && (
+ ); diff --git a/frontend/src/features/onboardingSlice.ts b/frontend/src/features/onboardingSlice.ts index 541fac94a..6749785c1 100644 --- a/frontend/src/features/onboardingSlice.ts +++ b/frontend/src/features/onboardingSlice.ts @@ -9,6 +9,7 @@ interface OnboardingState { stepStatus: boolean[]; avatar: string | null; name: string; + isEditing: boolean; } const initialState: OnboardingState = { @@ -17,6 +18,7 @@ const initialState: OnboardingState = { stepStatus: STEP_NAMES.map(() => false), avatar: localStorage.getItem('avatar'), name: localStorage.getItem('name') || '', + isEditing: false, }; const onboardingSlice = createSlice({ name: 'onboarding', @@ -28,6 +30,9 @@ const onboardingSlice = createSlice({ setName(state, action: PayloadAction) { state.name = action.payload; }, + setIsEditing(state, action: PayloadAction) { + state.isEditing = action.payload; + }, markCompleted(state, action: PayloadAction) { const stepIndex = action.payload; if (stepIndex >= 0 && stepIndex < state.stepStatus.length) { @@ -51,7 +56,7 @@ const onboardingSlice = createSlice({ }, }); -export const { setAvatar, setName, markCompleted, previousStep } = +export const { setAvatar, setName, setIsEditing, markCompleted, previousStep } = onboardingSlice.actions; export default onboardingSlice.reducer;