Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 7d3c902

Browse files
authored
Add full setup
1 parent 0c00326 commit 7d3c902

1 file changed

Lines changed: 136 additions & 17 deletions

File tree

Lines changed: 136 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,151 @@
11
import SwiftUI
2+
import UIKit
23

34
struct SetupView: View {
45
var onComplete: () -> Void
5-
6+
7+
@State private var currentPage = 0
8+
@State private var isGeneratingCert = false
9+
@State private var certGenerated = false
10+
11+
private let pages: [SetupPage] = [
12+
SetupPage(title: "Welcome to ProStore!",
13+
subtitle: "Before you begin, follow these steps to make sure ProStore works perfectly.",
14+
imageName: "star.fill"),
15+
16+
SetupPage(title: "Install the SSL Certificate",
17+
subtitle: "When the popup appears, click the 'Close' button.",
18+
imageName: "lock.shield"),
19+
20+
SetupPage(title: "Install the SSL Certificate",
21+
subtitle: "ProStore will now automatically generate the SSL certificate and open it for installation.",
22+
imageName: "sparkles"),
23+
24+
SetupPage(title: "Install the SSL Certificate",
25+
subtitle: "Go to Settings, tap 'Profile Downloaded', then 'Install'. Enter your passcode, and confirm by tapping 'Install' on the popup.",
26+
imageName: "checkmark.shield"),
27+
28+
SetupPage(title: "Install the SSL Certificate",
29+
subtitle: "Tap the tick, navigate to 'General → About → Certificate Trust Settings', and enable 'ProStore' under 'Enable Full Trust for Root Certificates'.",
30+
imageName: "hand.thumbsup"),
31+
32+
SetupPage(title: "You're finished!",
33+
subtitle: "Thanks for completing the setup! You're now ready to use ProStore.",
34+
imageName: "party.popper")
35+
]
36+
637
var body: some View {
7-
VStack(spacing: 30) {
38+
VStack(spacing: 20) {
839
Spacer()
940

10-
Text("Welcome to ProStore!")
11-
.font(.largeTitle)
12-
.bold()
13-
.multilineTextAlignment(.center)
14-
15-
Text("Let's set things up before you start using the app.")
16-
.multilineTextAlignment(.center)
17-
.padding(.horizontal)
18-
41+
TabView(selection: $currentPage) {
42+
ForEach(0..<pages.count, id: \.self) { index in
43+
VStack(spacing: 20) {
44+
Image(systemName: pages[index].imageName)
45+
.resizable()
46+
.scaledToFit()
47+
.frame(width: 100, height: 100)
48+
.foregroundColor(.accentColor)
49+
50+
Text(pages[index].title)
51+
.font(.largeTitle)
52+
.bold()
53+
.multilineTextAlignment(.center)
54+
55+
Text(pages[index].subtitle)
56+
.multilineTextAlignment(.center)
57+
.padding(.horizontal)
58+
59+
if index == 2 && !certGenerated {
60+
if isGeneratingCert {
61+
ProgressView("Generating certificate...")
62+
.padding(.top, 20)
63+
} else {
64+
Button("Generate Certificate") {
65+
generateCertificate()
66+
}
67+
.buttonStyle(.borderedProminent)
68+
.padding(.top, 20)
69+
}
70+
}
71+
}
72+
.tag(index)
73+
}
74+
}
75+
.tabViewStyle(.page(indexDisplayMode: .automatic))
76+
.animation(.easeInOut, value: currentPage)
77+
1978
Spacer()
2079

21-
Button("Continue") {
22-
onComplete()
80+
HStack {
81+
if currentPage > 0 {
82+
Button("Back") {
83+
withAnimation {
84+
currentPage -= 1
85+
}
86+
}
87+
.buttonStyle(.bordered)
88+
}
89+
90+
Spacer()
91+
92+
Button(currentPage == pages.count - 1 ? "Finish" : "Next") {
93+
withAnimation {
94+
if currentPage == 2 && !certGenerated {
95+
generateCertificate()
96+
} else if currentPage < pages.count - 1 {
97+
currentPage += 1
98+
} else {
99+
onComplete()
100+
}
101+
}
102+
}
103+
.disabled(currentPage == 2 && !certGenerated)
104+
.buttonStyle(.borderedProminent)
23105
}
24-
.buttonStyle(.borderedProminent)
25-
.font(.title2)
26-
.padding()
106+
.padding(.horizontal)
27107

28-
Spacer()
108+
Spacer(minLength: 20)
29109
}
30110
.padding()
31111
}
112+
113+
private func generateCertificate() {
114+
isGeneratingCert = true
115+
Task {
116+
do {
117+
let urls = try await GenerateCert.createAndSaveCerts()
118+
119+
// Find the ProStore.pem file
120+
if let proStoreCertURL = urls.first(where: { $0.lastPathComponent == "ProStore.pem" }) {
121+
openCertificateFile(url: proStoreCertURL)
122+
}
123+
124+
certGenerated = true
125+
isGeneratingCert = false
126+
Logger.shared.log("Certificate generated successfully.")
127+
} catch {
128+
isGeneratingCert = false
129+
Logger.shared.logError(error)
130+
}
131+
}
132+
}
133+
134+
private func openCertificateFile(url: URL) {
135+
DispatchQueue.main.async {
136+
if UIApplication.shared.canOpenURL(url) {
137+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
138+
} else {
139+
// Fallback to UIDocumentInteractionController
140+
let docController = UIDocumentInteractionController(url: url)
141+
docController.presentOptionsMenu(from: CGRect.zero, in: UIApplication.shared.windows.first!.rootViewController!.view, animated: true)
142+
}
143+
}
144+
}
145+
}
146+
147+
struct SetupPage {
148+
let title: String
149+
let subtitle: String
150+
let imageName: String
32151
}

0 commit comments

Comments
 (0)