import SwiftUI struct AboutScreen: View { @Environment(\.dismiss) private var dismiss @State private var appearAnimation = false var body: some View { ScrollView { VStack(spacing: 20) { // Logo + version VStack(spacing: 8) { Image("PayfritLogoLight") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 80, height: 80) Text("Payfrit Works") .font(.subheadline) .fontWeight(.bold) .foregroundColor(.primary) Text("Version 1.0.0") .font(.caption) .foregroundColor(.secondary) } .frame(maxWidth: .infinity) .padding(.top, 16) .scaleEffect(appearAnimation ? 1 : 0.9) .opacity(appearAnimation ? 1 : 0) // Intro Text("Payfrit Works helps you manage tasks, accept cash payments, and earn money. Get notified of new tasks, complete them efficiently, and track your earnings.") .font(.caption) .foregroundColor(.secondary) .multilineTextAlignment(.leading) .padding(.horizontal, 16) .opacity(appearAnimation ? 1 : 0) .offset(y: appearAnimation ? 0 : 15) // Feature cards VStack(spacing: 12) { featureCard( icon: "checkmark.circle", title: "Claim Tasks", description: "View available tasks from businesses you work for and claim them with one tap." ) .staggeredAppear(index: 0, appeared: appearAnimation) featureCard( icon: "dollarsign.circle", title: "Accept Cash", description: "Collect cash payments from customers with automatic change calculation." ) .staggeredAppear(index: 1, appeared: appearAnimation) featureCard( icon: "antenna.radiowaves.left.and.right", title: "Beacon Auto-Complete", description: "Tasks complete automatically when you're near the customer's table beacon." ) .staggeredAppear(index: 2, appeared: appearAnimation) featureCard( icon: "creditcard", title: "Earn & Get Paid", description: "Track your earnings in real-time and receive payouts to your bank account." ) .staggeredAppear(index: 3, appeared: appearAnimation) } .padding(.horizontal, 16) // Links VStack(spacing: 8) { Link(destination: URL(string: "https://www.payfrit.com")!) { HStack(spacing: 10) { Image(systemName: "globe") .font(.subheadline) .foregroundColor(.payfritGreen) .frame(width: 28, height: 28) .background(Color.payfritGreen.opacity(0.1)) .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) VStack(alignment: .leading, spacing: 2) { Text("Website") .font(.caption) .fontWeight(.medium) .foregroundColor(.primary) Text("www.payfrit.com") .font(.caption2) .foregroundColor(.secondary) } Spacer() Image(systemName: "arrow.up.right") .font(.caption2) .foregroundColor(.secondary) } .padding(12) .background(Color(.secondarySystemGroupedBackground)) .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) .contentShape(Rectangle()) } } .padding(.horizontal, 16) .staggeredAppear(index: 4, appeared: appearAnimation) // Copyright Text("\u{00A9} 2026 Payfrit. All rights reserved.") .font(.caption2) .foregroundColor(.secondary) .padding(.top, 4) Spacer() .frame(height: 20) } } .background(Color(.systemGroupedBackground).ignoresSafeArea()) .navigationTitle("About Payfrit") .navigationBarTitleDisplayMode(.inline) .onAppear { withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { appearAnimation = true } } } private func featureCard(icon: String, title: String, description: String) -> some View { HStack(spacing: 10) { Image(systemName: icon) .font(.subheadline) .foregroundColor(.payfritGreen) .frame(width: 28, height: 28) .background(Color.payfritGreen.opacity(0.1)) .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) VStack(alignment: .leading, spacing: 2) { Text(title) .font(.caption) .fontWeight(.medium) .foregroundColor(.primary) Text(description) .font(.caption2) .foregroundColor(.secondary) } Spacer() } .padding(12) .background(Color(.secondarySystemGroupedBackground)) .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) .contentShape(Rectangle()) } } // MARK: - Staggered Appear Modifier private struct StaggeredAppearModifier: ViewModifier { let index: Int let appeared: Bool func body(content: Content) -> some View { content .opacity(appeared ? 1 : 0) .offset(y: appeared ? 0 : 20) .animation( .spring(response: 0.4, dampingFraction: 0.8) .delay(Double(index) * 0.06), value: appeared ) } } private extension View { func staggeredAppear(index: Int, appeared: Bool) -> some View { modifier(StaggeredAppearModifier(index: index, appeared: appeared)) } } #Preview { NavigationStack { AboutScreen() } }