SPB Git

spb/poche Public

Agent personnel 100 % on-device — SwiftUI + Apple Foundation Models + EventKit + SwiftData. Aucune API, aucun serveur.

Swift 100%
2.7 KB · 73 lines swift
Raw Blame History
1//2//  WelcomeView.swift3//  Poche4//5//  Author:  Simon-Pierre Boucher6//  Contact: contact@spboucher.ai7//89import SwiftUI1011/// Empty state: the promise, then three one-tap ways to try the agent.12struct WelcomeView: View {13    let onSuggestion: (String) -> Void1415    private static let suggestions: [(icon: String, text: String)] = [16        ("bell", "Rappelle-moi d'appeler le dentiste demain à 9 h"),17        ("calendar", "Qu'est-ce que j'ai au programme cette semaine ?"),18        ("note.text", "Note que je dois renouveler mon passeport"),19    ]2021    var body: some View {22        VStack(spacing: 0) {23            Spacer()2425            BrandMark(size: 76)26                .padding(.bottom, Theme.spacingLarge)2728            Text("Ton agent, sur ton appareil.")29                .font(.title2.weight(.bold))30                .multilineTextAlignment(.center)3132            Text("Hors ligne. Privé. Rien ne quitte ton iPhone.")33                .font(.subheadline)34                .foregroundStyle(.secondary)35                .padding(.top, Theme.spacingSmall)3637            Spacer()3839            VStack(spacing: Theme.spacingSmall + 4) {40                ForEach(Self.suggestions, id: \.text) { suggestion in41                    Button {42                        onSuggestion(suggestion.text)43                    } label: {44                        HStack(spacing: Theme.spacingMedium) {45                            Image(systemName: suggestion.icon)46                                .font(.system(size: 15, weight: .semibold))47                                .foregroundStyle(Theme.accentGradient)48                                .frame(width: 22)49                            Text(suggestion.text)50                                .font(.subheadline.weight(.medium))51                                .foregroundStyle(.primary)52                                .multilineTextAlignment(.leading)53                            Spacer()54                        }55                        .padding(.horizontal, Theme.spacingMedium + 4)56                        .padding(.vertical, Theme.spacingMedium)57                        .background(Theme.surface)58                        .clipShape(RoundedRectangle(cornerRadius: Theme.cardCornerRadius - 4))59                        .overlay {60                            RoundedRectangle(cornerRadius: Theme.cardCornerRadius - 4)61                                .strokeBorder(Theme.accentA.opacity(0.14))62                        }63                    }64                    .buttonStyle(.plain)65                }66            }67            .padding(.horizontal, Theme.spacingLarge)68            .padding(.bottom, Theme.spacingMedium)69        }70        .frame(maxWidth: .infinity, maxHeight: .infinity)71    }72}73