-
Notifications
You must be signed in to change notification settings - Fork 45
Fix: Add logout and navigation improvements to onboarding flow #94
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
base: main
Are you sure you want to change the base?
Fix: Add logout and navigation improvements to onboarding flow #94
Conversation
- Add logout button with confirmation dialog in onboarding header - Implement 'Skip for now' option to allow completing onboarding later - Add clickable step navigation to go back to previous steps - Implement auto-save functionality for onboarding progress - Add error handling and loading states for logout process - Enhance UI with better progress indicators and navigation - Fix missing exit options during onboarding flow Fixes AOSSIE-Org#93
""" WalkthroughThe Onboarding component was updated to introduce an exit confirmation dialog, logout and skip options, clickable progress indicators for back navigation, and auto-saving of onboarding progress. Additional UI enhancements and error handling were added to improve navigation and user control during the onboarding flow. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant OnboardingComponent
participant AuthContext
participant LocalStorage
participant Router
User->>OnboardingComponent: Clicks "Logout" or "Skip for now"
OnboardingComponent->>OnboardingComponent: Show exit confirmation dialog
User->>OnboardingComponent: Confirms exit action
alt Logout
OnboardingComponent->>AuthContext: Call logout()
AuthContext-->>OnboardingComponent: Logout result
OnboardingComponent->>Router: Navigate to login/dashboard
else Skip
OnboardingComponent->>LocalStorage: Save onboarding progress
OnboardingComponent->>Router: Navigate to dashboard
end
OnboardingComponent->>OnboardingComponent: Handle errors/loading states
sequenceDiagram
participant User
participant OnboardingComponent
User->>OnboardingComponent: Clicks completed step in progress indicator
OnboardingComponent->>OnboardingComponent: Navigate to selected previous step
Assessment against linked issues
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
Frontend/src/components/Onboarding.tsx (2)
643-688
: Clean up empty lines and improve error message.The exit confirmation logic is well-implemented, but there are a few minor improvements needed:
Remove the empty lines and improve the error message specificity:
const handleExitConfirm = async () => { setExitLoading(true); setExitError(""); try { - - if (exitAction === 'logout') { await logout(); // Note: logout() should handle navigation, so we don't close dialog here // The AuthContext logout function should redirect to home page } else if (exitAction === 'skip') { console.log("Skipping onboarding..."); // Save current progress to localStorage for later const progressData = { step, role, personal, selectedPlatforms, platformDetails, pricing, profilePic: null, // Can't save file to localStorage brandStep, brandData: { ...brandData, logo: null }, // Can't save file to localStorage timestamp: Date.now() }; localStorage.setItem('onboarding_progress', JSON.stringify(progressData)); // Navigate to appropriate dashboard if (role === "brand") { navigate('/brand/dashboard'); } else { navigate('/dashboard'); } // Close dialog after navigation setShowExitDialog(false); setExitAction(null); } } catch (error) { console.error("Error in handleExitConfirm:", error); - setExitError(`Failed to ${exitAction}. Please try again.`); + setExitError(exitAction === 'logout' ? 'Failed to logout. Please try again.' : 'Failed to save progress. Please try again.'); } finally { setExitLoading(false); } };
66-1740
: Consider splitting this large component for better maintainability.This component has grown to over 1700 lines. Consider extracting some parts into separate components:
- Exit confirmation dialog component
- Stepper UI component
- Individual step form components
- Brand onboarding flow as a separate component
This would improve code organization, reusability, and make the codebase easier to maintain.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Frontend/src/components/Onboarding.tsx
(9 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
Frontend/src/components/Onboarding.tsx (1)
Frontend/src/context/AuthContext.tsx (1)
useAuth
(216-222)
🔇 Additional comments (8)
Frontend/src/components/Onboarding.tsx (8)
4-4
: Icon imports look good.The addition of LogOut, X, ArrowLeft, and AlertCircle icons from lucide-react aligns with the UI improvements for the navigation flow.
68-68
: Auth context and state management properly implemented.Good implementation of:
- Extracting the
logout
function from the auth context for the new logout feature- Properly typed state variables for exit dialog management with appropriate initial values
Also applies to: 88-93
697-707
: Step navigation properly restricted to completed steps.Good implementation that only allows users to navigate back to previously completed steps, maintaining the integrity of the onboarding flow.
710-730
: Progress restoration with expiration is well-implemented.Excellent implementation of progress restoration with:
- 24-hour expiration check to ensure data freshness
- Proper error handling for JSON parsing
- Restoration of all relevant state variables
1171-1192
: Header navigation controls are well-designed.Good implementation with:
- Clear visual hierarchy with the InPact branding
- Conditional rendering of the "Skip for now" button after role selection
- Consistent styling and hover effects
- Proper icon usage for the logout button
1194-1251
: Interactive stepper with visual feedback is excellent.The enhanced stepper implementation provides:
- Clear visual distinction between active, completed, and pending steps
- Clickable completed steps for backward navigation
- Hover effects for better UX
- Checkmarks for completed steps
- Consistent implementation for both brand and creator flows
1277-1341
: Navigation controls enhanced with better visual feedback.Excellent improvements:
- ArrowLeft icon enhances the back button
- Step counter (e.g., "Step 2 of 7") provides clear progress context
- Consistent hover effects and disabled states
- Proper handling for both brand and creator flows
1348-1403
: Exit confirmation dialog is well-structured.Great implementation with:
- Clear messaging differentiating logout vs skip actions
- Loading states with spinner animation
- Error message display
- Proper button disable states during operations
- Conditional button styling based on action type
|
||
{/* Exit Confirmation Dialog */} | ||
{showExitDialog && ( | ||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-opacity-50"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix missing background color class for dialog overlay.
The overlay div uses bg-opacity-50
but is missing the actual background color class.
- <div className="fixed inset-0 z-50 flex items-center justify-center bg-opacity-50">
+ <div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<div className="fixed inset-0 z-50 flex items-center justify-center bg-opacity-50"> | |
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"> |
🤖 Prompt for AI Agents
In Frontend/src/components/Onboarding.tsx at line 1347, the overlay div has a
background opacity class but lacks a background color class. Add an appropriate
background color class such as 'bg-black' or 'bg-gray-900' alongside
'bg-opacity-50' to ensure the overlay has a visible background color with the
specified opacity.
if (role === "brand") { | ||
navigate('/brand/dashboard'); | ||
} else { | ||
navigate('/dashboard'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if this is the logical way forward....the code is simply giving users a way to bypass onboarding especially the above code snippet....it is doing direct redirection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haved test it
it is working properly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also in the PR #92 i have solved the goole auth process
you mention
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haved test it it is working properly
ohh ...no problem then....I'll review the good when I get some free time....in the meantime can you ,in the pr description also attach. screen recording of the process?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yaa sure
@varunchitre15 please you can also have a look in that |
Untitled.video.-.Made.with.Clipchamp.mp4 |
so the idea is to keep the basic fields which we'll need later on for creator recommendation and matching mandatory and not allow user to bypass them..... |
@Saahi30 By Understanding your Feedback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
Frontend/src/components/Onboarding.tsx (1)
1406-1406
: Fix missing background color class for dialog overlay.The overlay div uses
bg-opacity-50
but is missing the actual background color class.- <div className="fixed inset-0 z-50 flex items-center justify-center bg-opacity-50"> + <div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
Frontend/src/components/Onboarding.tsx
(10 hunks)
🔇 Additional comments (11)
Frontend/src/components/Onboarding.tsx (11)
4-4
: LGTM on icon imports.The new lucide-react icons are properly imported and used throughout the component for enhanced navigation and dialog functionality.
24-29
: Well-defined essential steps for smart skip functionality.The essential steps definition appropriately identifies the minimum required information for creator-brand matching while allowing flexibility for optional fields.
74-74
: Appropriate auth context usage.The logout function is correctly extracted from the auth context for the new logout functionality.
94-99
: Well-structured state management for exit dialog.The state variables are appropriately typed and named for managing the exit confirmation dialog and its various states.
644-647
: Simple and correct exit request handler.The function properly initiates the exit dialog flow by setting the action type and showing the dialog.
735-740
: Proper cleanup function for exit dialog.The function correctly resets all exit dialog state variables when the user cancels the action.
742-752
: Good implementation of step navigation.The function properly enables navigation to previously completed steps with appropriate validation to prevent forward navigation to incomplete steps.
754-775
: Robust progress restoration implementation.The useEffect properly loads saved progress with appropriate expiration checks and error handling, providing a good user experience for session restoration.
1214-1238
: Well-designed header with clear navigation options.The header provides intuitive logout and skip functionality with appropriate conditional rendering, tooltips, and visual feedback.
1240-1310
: Excellent stepper UI enhancement.The enhanced stepper provides clear visual feedback with clickable navigation, essential step marking, and intuitive color coding that significantly improves the user experience.
1407-1462
: Well-structured exit confirmation dialog.The dialog provides clear messaging, proper error handling, loading states, and intuitive button interactions that enhance the user experience.
const handleExitConfirm = async () => { | ||
setExitLoading(true); | ||
setExitError(""); | ||
|
||
try { | ||
if (exitAction === 'logout') { | ||
await logout(); | ||
// Note: logout() should handle navigation, so we don't close dialog here | ||
// The AuthContext logout function should redirect to home page | ||
} else if (exitAction === 'skip') { | ||
console.log("Skipping non-essential onboarding fields..."); | ||
|
||
// Only allow skipping if essential fields are completed | ||
if (role === "creator") { | ||
// For creators, essential fields are: role, personal details, platform selection, platform details, pricing | ||
const essentialFieldsComplete = role && | ||
personal.name && personal.email && personal.age && personal.gender && | ||
personal.category && personal.country && | ||
selectedPlatforms.length > 0; | ||
|
||
if (!essentialFieldsComplete) { | ||
setExitError("Please complete the essential fields (Personal Details, Platform Selection, and Platform Details) before skipping. These are required for creator matching."); | ||
return; | ||
} | ||
|
||
// Allow skipping pricing and profile picture (non-essential for basic matching) | ||
if (step < 4) { // Before pricing step | ||
setExitError("Please complete platform details before skipping. This information is essential for creator matching."); | ||
return; | ||
} | ||
|
||
} else if (role === "brand") { | ||
// For brands, essential fields are: brand details, contact info, platforms | ||
const essentialFieldsComplete = brandData.brand_name && | ||
brandData.website_url && brandData.industry && brandData.company_size && | ||
brandData.location && brandData.description && | ||
brandData.contact_person && brandData.contact_email && | ||
brandData.platforms.length > 0; | ||
|
||
if (!essentialFieldsComplete) { | ||
setExitError("Please complete the essential fields (Brand Details, Contact Information, and Platform Selection) before skipping. These are required for brand matching."); | ||
return; | ||
} | ||
|
||
// Allow skipping social links and collaboration preferences (non-essential for basic matching) | ||
if (brandStep < 2) { // Before social links step | ||
setExitError("Please complete platform selection before skipping. This information is essential for brand matching."); | ||
return; | ||
} | ||
} | ||
|
||
// Save current progress to localStorage for later | ||
const progressData = { | ||
step, | ||
role, | ||
personal, | ||
selectedPlatforms, | ||
platformDetails, | ||
pricing, | ||
profilePic: null, // Can't save file to localStorage | ||
brandStep, | ||
brandData: { ...brandData, logo: null }, // Can't save file to localStorage | ||
timestamp: Date.now(), | ||
skipped: true // Mark as skipped for later completion | ||
}; | ||
localStorage.setItem('onboarding_progress', JSON.stringify(progressData)); | ||
|
||
// Navigate to appropriate dashboard | ||
if (role === "brand") { | ||
navigate('/brand/dashboard'); | ||
} else { | ||
navigate('/dashboard'); | ||
} | ||
|
||
// Close dialog | ||
setShowExitDialog(false); | ||
setExitAction(null); | ||
} | ||
} catch (error) { | ||
console.error("Error in handleExitConfirm:", error); | ||
setExitError(`Failed to ${exitAction}. Please try again.`); | ||
} finally { | ||
setExitLoading(false); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Complex exit confirmation logic needs validation improvements.
The function handles both logout and skip actions but has potential issues in the validation logic:
-
Creator validation gap: Lines 675-678 only check if
step < 4
but don't validate that platform details are actually completed. A user could be on step 4 with incomplete platform details. -
Consider more specific validation: The essential field validation could be more robust by checking actual data completeness rather than just step progression.
Consider this improvement for creator validation:
- // Allow skipping pricing and profile picture (non-essential for basic matching)
- if (step < 4) { // Before pricing step
- setExitError("Please complete platform details before skipping. This information is essential for creator matching.");
- return;
- }
+ // Validate platform details are actually completed
+ const platformDetailsComplete = selectedPlatforms.length > 0 &&
+ selectedPlatforms.every(platform => {
+ const details = platformDetails[platform];
+ return details && (
+ platform === "YouTube" ?
+ details.channelUrl && details.channelId && details.channelName :
+ details.profileUrl && details.followers && details.posts
+ );
+ });
+
+ if (!platformDetailsComplete) {
+ setExitError("Please complete platform details before skipping. This information is essential for creator matching.");
+ return;
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const handleExitConfirm = async () => { | |
setExitLoading(true); | |
setExitError(""); | |
try { | |
if (exitAction === 'logout') { | |
await logout(); | |
// Note: logout() should handle navigation, so we don't close dialog here | |
// The AuthContext logout function should redirect to home page | |
} else if (exitAction === 'skip') { | |
console.log("Skipping non-essential onboarding fields..."); | |
// Only allow skipping if essential fields are completed | |
if (role === "creator") { | |
// For creators, essential fields are: role, personal details, platform selection, platform details, pricing | |
const essentialFieldsComplete = role && | |
personal.name && personal.email && personal.age && personal.gender && | |
personal.category && personal.country && | |
selectedPlatforms.length > 0; | |
if (!essentialFieldsComplete) { | |
setExitError("Please complete the essential fields (Personal Details, Platform Selection, and Platform Details) before skipping. These are required for creator matching."); | |
return; | |
} | |
// Allow skipping pricing and profile picture (non-essential for basic matching) | |
if (step < 4) { // Before pricing step | |
setExitError("Please complete platform details before skipping. This information is essential for creator matching."); | |
return; | |
} | |
} else if (role === "brand") { | |
// For brands, essential fields are: brand details, contact info, platforms | |
const essentialFieldsComplete = brandData.brand_name && | |
brandData.website_url && brandData.industry && brandData.company_size && | |
brandData.location && brandData.description && | |
brandData.contact_person && brandData.contact_email && | |
brandData.platforms.length > 0; | |
if (!essentialFieldsComplete) { | |
setExitError("Please complete the essential fields (Brand Details, Contact Information, and Platform Selection) before skipping. These are required for brand matching."); | |
return; | |
} | |
// Allow skipping social links and collaboration preferences (non-essential for basic matching) | |
if (brandStep < 2) { // Before social links step | |
setExitError("Please complete platform selection before skipping. This information is essential for brand matching."); | |
return; | |
} | |
} | |
// Save current progress to localStorage for later | |
const progressData = { | |
step, | |
role, | |
personal, | |
selectedPlatforms, | |
platformDetails, | |
pricing, | |
profilePic: null, // Can't save file to localStorage | |
brandStep, | |
brandData: { ...brandData, logo: null }, // Can't save file to localStorage | |
timestamp: Date.now(), | |
skipped: true // Mark as skipped for later completion | |
}; | |
localStorage.setItem('onboarding_progress', JSON.stringify(progressData)); | |
// Navigate to appropriate dashboard | |
if (role === "brand") { | |
navigate('/brand/dashboard'); | |
} else { | |
navigate('/dashboard'); | |
} | |
// Close dialog | |
setShowExitDialog(false); | |
setExitAction(null); | |
} | |
} catch (error) { | |
console.error("Error in handleExitConfirm:", error); | |
setExitError(`Failed to ${exitAction}. Please try again.`); | |
} finally { | |
setExitLoading(false); | |
} | |
}; | |
const handleExitConfirm = async () => { | |
setExitLoading(true); | |
setExitError(""); | |
try { | |
if (exitAction === 'logout') { | |
await logout(); | |
// Note: logout() should handle navigation, so we don't close dialog here | |
// The AuthContext logout function should redirect to home page | |
} else if (exitAction === 'skip') { | |
console.log("Skipping non-essential onboarding fields..."); | |
// Only allow skipping if essential fields are completed | |
if (role === "creator") { | |
// For creators, essential fields are: role, personal details, platform selection, platform details, pricing | |
const essentialFieldsComplete = role && | |
personal.name && personal.email && personal.age && personal.gender && | |
personal.category && personal.country && | |
selectedPlatforms.length > 0; | |
if (!essentialFieldsComplete) { | |
setExitError("Please complete the essential fields (Personal Details, Platform Selection, and Platform Details) before skipping. These are required for creator matching."); | |
return; | |
} | |
// Validate platform details are actually completed | |
const platformDetailsComplete = selectedPlatforms.length > 0 && | |
selectedPlatforms.every(platform => { | |
const details = platformDetails[platform]; | |
return details && ( | |
platform === "YouTube" | |
? details.channelUrl && details.channelId && details.channelName | |
: details.profileUrl && details.followers && details.posts | |
); | |
}); | |
if (!platformDetailsComplete) { | |
setExitError("Please complete platform details before skipping. This information is essential for creator matching."); | |
return; | |
} | |
} else if (role === "brand") { | |
// For brands, essential fields are: brand details, contact info, platforms | |
const essentialFieldsComplete = brandData.brand_name && | |
brandData.website_url && brandData.industry && brandData.company_size && | |
brandData.location && brandData.description && | |
brandData.contact_person && brandData.contact_email && | |
brandData.platforms.length > 0; | |
if (!essentialFieldsComplete) { | |
setExitError("Please complete the essential fields (Brand Details, Contact Information, and Platform Selection) before skipping. These are required for brand matching."); | |
return; | |
} | |
// Allow skipping social links and collaboration preferences (non-essential for basic matching) | |
if (brandStep < 2) { // Before social links step | |
setExitError("Please complete platform selection before skipping. This information is essential for brand matching."); | |
return; | |
} | |
} | |
// Save current progress to localStorage for later | |
const progressData = { | |
step, | |
role, | |
personal, | |
selectedPlatforms, | |
platformDetails, | |
pricing, | |
profilePic: null, // Can't save file to localStorage | |
brandStep, | |
brandData: { ...brandData, logo: null }, // Can't save file to localStorage | |
timestamp: Date.now(), | |
skipped: true // Mark as skipped for later completion | |
}; | |
localStorage.setItem('onboarding_progress', JSON.stringify(progressData)); | |
// Navigate to appropriate dashboard | |
if (role === "brand") { | |
navigate('/brand/dashboard'); | |
} else { | |
navigate('/dashboard'); | |
} | |
// Close dialog | |
setShowExitDialog(false); | |
setExitAction(null); | |
} | |
} catch (error) { | |
console.error("Error in handleExitConfirm:", error); | |
setExitError(`Failed to ${exitAction}. Please try again.`); | |
} finally { | |
setExitLoading(false); | |
} | |
}; |
🤖 Prompt for AI Agents
In Frontend/src/components/Onboarding.tsx around lines 649 to 733, the exit
confirmation logic for skipping onboarding has insufficient validation for
creators, as it only checks if the step number is less than 4 without verifying
if platform details are fully completed. To fix this, enhance the validation by
explicitly checking the completeness of platform details data rather than
relying solely on the step number. Update the condition to validate that all
required platform details fields are filled before allowing the user to skip,
ensuring more robust and accurate validation of essential fields.
so by essential field what I meant was that every section/step of the onboarding process....to simplify dont just generalise that these 4-5 fields are imp/mandatory rest none like it is done In the code...rather go through each onboarding step and understand what all fields are crucial and what not for data collection...if you want you can take reference to the current code..... |
P.S handle all the code rabbit suggestions |
Fix: Add logout and navigation improvements to onboarding flow
Closes #93
📝 Description
This PR fixes the critical UX issue where users were trapped in the onboarding flow without any way to logout or navigate back to previous steps. The changes implement comprehensive navigation improvements to provide users with proper control during the onboarding process.
Problem Solved:
Solution Implemented:
🔧 Changes Made
Add logout button with confirmation dialog in onboarding header
Implement 'Skip for now' option to allow completing onboarding later
Add clickable step navigation to go back to previous steps
Implement auto-save functionality for onboarding progress
Add error handling and loading states for logout process
Enhance UI with better progress indicators and navigation
Fix missing exit options during onboarding flow
📷 Screenshots or Visual Changes
Before:
After:
Key UI Improvements:
🧪 Testing
Manual Testing Performed:
Test Scenarios:
✅ Checklist
Summary by CodeRabbit
New Features
Improvements