Files
honeyDueKMP/iosApp/iosApp/Onboarding/OnboardingWelcomeView.swift
Trey t 0652908c20 Add iOS onboarding flow with residence creation and task templates
- Add complete onboarding flow with 7 screens: Welcome, Name Residence,
  Value Props, Create Account, Verify Email, First Task, Subscription
- Auto-create residence after email verification for "Start Fresh" users
- Add predefined task templates (HVAC, Smoke Detectors, Lawn Care, Leaks)
  that create real tasks with today as due date
- Add returning user login button on welcome screen
- Update RootView to prioritize onboarding flow for first-time users
- Use app icon asset instead of house.fill SF Symbol
- Smooth slide transitions with fade-out for back navigation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 11:00:51 -06:00

121 lines
4.1 KiB
Swift

import SwiftUI
/// Screen 1: Welcome screen with Start Fresh / Join Existing options
struct OnboardingWelcomeView: View {
var onStartFresh: () -> Void
var onJoinExisting: () -> Void
var onLogin: () -> Void
@State private var showingLoginSheet = false
var body: some View {
VStack(spacing: 0) {
Spacer()
// Hero section
VStack(spacing: AppSpacing.xl) {
// App icon
Image("icon")
.resizable()
.scaledToFit()
.frame(width: 120, height: 120)
.clipShape(RoundedRectangle(cornerRadius: AppRadius.xxl))
.shadow(color: Color.appPrimary.opacity(0.3), radius: 20, y: 10)
// Welcome text
VStack(spacing: AppSpacing.sm) {
Text("Welcome to Casera")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.appTextPrimary)
Text("Your home maintenance companion")
.font(.title3)
.foregroundColor(Color.appTextSecondary)
.multilineTextAlignment(.center)
}
}
Spacer()
// Action buttons
VStack(spacing: AppSpacing.md) {
// Primary CTA - Start Fresh
Button(action: onStartFresh) {
HStack(spacing: AppSpacing.sm) {
Image("icon")
.resizable()
.scaledToFit()
.frame(width: 24, height: 24)
Text("Start Fresh")
.font(.headline)
.fontWeight(.semibold)
}
.frame(maxWidth: .infinity)
.frame(height: 56)
.foregroundColor(Color.appTextOnPrimary)
.background(
LinearGradient(
colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.cornerRadius(AppRadius.md)
.shadow(color: Color.appPrimary.opacity(0.3), radius: 10, y: 5)
}
// Secondary CTA - Join Existing
Button(action: onJoinExisting) {
HStack(spacing: AppSpacing.sm) {
Image(systemName: "person.2.fill")
.font(.title3)
Text("I have a code to join")
.font(.headline)
.fontWeight(.medium)
}
.frame(maxWidth: .infinity)
.frame(height: 56)
.foregroundColor(Color.appPrimary)
.background(Color.appPrimary.opacity(0.1))
.cornerRadius(AppRadius.md)
}
// Returning user login
Button(action: {
showingLoginSheet = true
}) {
Text("Already have an account? Log in")
.font(.subheadline)
.foregroundColor(Color.appTextSecondary)
}
.padding(.top, AppSpacing.sm)
}
.padding(.horizontal, AppSpacing.xl)
.padding(.bottom, AppSpacing.xxxl)
}
.background(Color.appBackgroundPrimary)
.sheet(isPresented: $showingLoginSheet) {
LoginView(onLoginSuccess: {
showingLoginSheet = false
onLogin()
})
}
}
}
// MARK: - Content-only version (no navigation bar)
/// Content-only version for use in coordinator
typealias OnboardingWelcomeContent = OnboardingWelcomeView
// MARK: - Preview
#Preview {
OnboardingWelcomeView(
onStartFresh: {},
onJoinExisting: {},
onLogin: {}
)
}