feat: Implement comprehensive onboarding system for new users

Add complete user onboarding flow that redirects new users to complete their
profile before accessing the application:

- Add onboarding_completed boolean field to users with migration
- Create OnboardingController with form validation and completion logic
- Design professional onboarding UI with progressive disclosure for company info
- Implement Stimulus controller for toggling company information section
- Add application-wide redirect middleware for incomplete users
- Create comprehensive test suite for all onboarding functionality
- Update test fixtures and helpers to support onboarding in existing tests

The onboarding collects required first/last name and optional company information.
Users are redirected to onboarding after login until profile is completed.
Features smooth animations, full-width form button, and clean UX design.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kbe
2025-09-08 11:38:28 +02:00
parent 67d3bcde5b
commit 758d461c1a
16 changed files with 472 additions and 8 deletions

View File

@@ -5,6 +5,9 @@ class ApplicationController < ActionController::Base
# Ensures that all non-GET requests include a valid authenticity token
protect_from_forgery with: :exception
# Redirect authenticated users to onboarding if not completed
before_action :require_onboarding_completion
# Restrict access to modern browsers only
# Requires browsers to support modern web standards:
# - WebP images for better compression
@@ -14,4 +17,29 @@ class ApplicationController < ActionController::Base
# - CSS nesting and :has() pseudo-class
# allow_browser versions: :modern
# allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
private
def require_onboarding_completion
# Skip onboarding check for these paths
return if skip_onboarding_check?
# Only apply to signed-in users
if user_signed_in? && current_user.needs_onboarding?
redirect_to onboarding_path unless request.path == onboarding_path
end
end
def skip_onboarding_check?
# Skip for devise controllers (login, signup, password reset, etc.)
devise_controller? ||
# Skip for onboarding controller itself
controller_name == "onboarding" ||
# Skip for API endpoints
controller_name.start_with?("api/") ||
# Skip for health checks
controller_name == "rails/health" ||
# Skip for home page (when not signed in)
(controller_name == "pages" && action_name == "home")
end
end

View File

@@ -0,0 +1,38 @@
class OnboardingController < ApplicationController
before_action :authenticate_user!
before_action :redirect_if_onboarding_complete, except: [:complete]
def index
# Display the onboarding form
end
def complete
if onboarding_params_valid?
current_user.update!(onboarding_params)
current_user.complete_onboarding!
flash[:notice] = "Bienvenue sur AperoNight ! Votre profil a été configuré avec succès."
redirect_to dashboard_path
else
flash.now[:alert] = "Veuillez remplir tous les champs requis."
render :index
end
end
private
def onboarding_params
params.require(:user).permit(:first_name, :last_name, :company_name)
end
def onboarding_params_valid?
onboarding_params[:first_name].present? &&
onboarding_params[:last_name].present?
end
def redirect_if_onboarding_complete
if current_user&.onboarding_completed?
redirect_to dashboard_path
end
end
end