SwiftUI version of auth screen
This commit is contained in:
parent
a9bbbfa35b
commit
406b1b02b5
@ -194,6 +194,10 @@
|
|||||||
7ADF6CA12512244400F237B2 /* MapExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6CA02512244400F237B2 /* MapExt.swift */; };
|
7ADF6CA12512244400F237B2 /* MapExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6CA02512244400F237B2 /* MapExt.swift */; };
|
||||||
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE24C5E251F1B4E00758E39 /* Buttons.swift */; };
|
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE24C5E251F1B4E00758E39 /* Buttons.swift */; };
|
||||||
7AE26A3324EEF9EC00625033 /* UIViewControllerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */; };
|
7AE26A3324EEF9EC00625033 /* UIViewControllerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */; };
|
||||||
|
7AF231932DA1C28100AE5EB3 /* AuthScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231922DA1C28100AE5EB3 /* AuthScreen.swift */; };
|
||||||
|
7AF231952DA1C29300AE5EB3 /* AuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231942DA1C29300AE5EB3 /* AuthViewModel.swift */; };
|
||||||
|
7AF231972DA1C30000AE5EB3 /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231962DA1C30000AE5EB3 /* AuthCoordinator.swift */; };
|
||||||
|
7AF231992DA27C1B00AE5EB3 /* ACButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231982DA27C1B00AE5EB3 /* ACButtonView.swift */; };
|
||||||
7AF6D2042677C03B0086EA64 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */; };
|
7AF6D2042677C03B0086EA64 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */; };
|
||||||
7AF6D2052677C03B0086EA64 /* AutoCatCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
7AF6D2052677C03B0086EA64 /* AutoCatCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
7AF6D2122677C12E0086EA64 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A000AA124C2EEDE001F5B00 /* Location.swift */; };
|
7AF6D2122677C12E0086EA64 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A000AA124C2EEDE001F5B00 /* Location.swift */; };
|
||||||
@ -477,6 +481,10 @@
|
|||||||
7AE24C5E251F1B4E00758E39 /* Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = "<group>"; };
|
7AE24C5E251F1B4E00758E39 /* Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = "<group>"; };
|
||||||
7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExt.swift; sourceTree = "<group>"; };
|
7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExt.swift; sourceTree = "<group>"; };
|
||||||
7AE8424D26109F78002F6B31 /* Exportable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exportable.swift; sourceTree = "<group>"; };
|
7AE8424D26109F78002F6B31 /* Exportable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exportable.swift; sourceTree = "<group>"; };
|
||||||
|
7AF231922DA1C28100AE5EB3 /* AuthScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthScreen.swift; sourceTree = "<group>"; };
|
||||||
|
7AF231942DA1C29300AE5EB3 /* AuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
7AF231962DA1C30000AE5EB3 /* AuthCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = "<group>"; };
|
||||||
|
7AF231982DA27C1B00AE5EB3 /* ACButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACButtonView.swift; sourceTree = "<group>"; };
|
||||||
7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AutoCatCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
7AF6D1EF2677C03B0086EA64 /* AutoCatCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AutoCatCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
7AF6D1F12677C03B0086EA64 /* AutoCatCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AutoCatCore.h; sourceTree = "<group>"; };
|
7AF6D1F12677C03B0086EA64 /* AutoCatCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AutoCatCore.h; sourceTree = "<group>"; };
|
||||||
7AF6D1F22677C03B0086EA64 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
7AF6D1F22677C03B0086EA64 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
@ -718,6 +726,7 @@
|
|||||||
7A1441632C297E9800E79018 /* Screens */ = {
|
7A1441632C297E9800E79018 /* Screens */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7AF231912DA1C26C00AE5EB3 /* AuthScreen */,
|
||||||
7A95197E2D80B69800E69883 /* RecordsScreen */,
|
7A95197E2D80B69800E69883 /* RecordsScreen */,
|
||||||
7A5911EC2D63225500EC51BA /* SearchScreen */,
|
7A5911EC2D63225500EC51BA /* SearchScreen */,
|
||||||
7A131FD12D37B74100DC7755 /* HistoryScreen */,
|
7A131FD12D37B74100DC7755 /* HistoryScreen */,
|
||||||
@ -1116,6 +1125,16 @@
|
|||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7AF231912DA1C26C00AE5EB3 /* AuthScreen */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7AF231922DA1C28100AE5EB3 /* AuthScreen.swift */,
|
||||||
|
7AF231942DA1C29300AE5EB3 /* AuthViewModel.swift */,
|
||||||
|
7AF231962DA1C30000AE5EB3 /* AuthCoordinator.swift */,
|
||||||
|
);
|
||||||
|
path = AuthScreen;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7AF6D1F02677C03B0086EA64 /* AutoCatCore */ = {
|
7AF6D1F02677C03B0086EA64 /* AutoCatCore */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1177,6 +1196,7 @@
|
|||||||
7AB490282D6B1217002F39C6 /* ACKeyboardView.swift */,
|
7AB490282D6B1217002F39C6 /* ACKeyboardView.swift */,
|
||||||
7AB4902A2D6B1446002F39C6 /* ACKeyboardButton.swift */,
|
7AB4902A2D6B1446002F39C6 /* ACKeyboardButton.swift */,
|
||||||
7A589E0E2D6B6E8E00EF3FBE /* NumberEditView.swift */,
|
7A589E0E2D6B6E8E00EF3FBE /* NumberEditView.swift */,
|
||||||
|
7AF231982DA27C1B00AE5EB3 /* ACButtonView.swift */,
|
||||||
);
|
);
|
||||||
path = SwiftUI;
|
path = SwiftUI;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1446,6 +1466,7 @@
|
|||||||
7A7158122C444A6400852088 /* AdsViewModel.swift in Sources */,
|
7A7158122C444A6400852088 /* AdsViewModel.swift in Sources */,
|
||||||
7A1E78FA2CE9005C0004B740 /* ReportCoordinator.swift in Sources */,
|
7A1E78FA2CE9005C0004B740 /* ReportCoordinator.swift in Sources */,
|
||||||
7A71580E2C4445A200852088 /* AdsCoordinator.swift in Sources */,
|
7A71580E2C4445A200852088 /* AdsCoordinator.swift in Sources */,
|
||||||
|
7AF231952DA1C29300AE5EB3 /* AuthViewModel.swift in Sources */,
|
||||||
7AB4E4662D58A16C0006D052 /* GenericError.swift in Sources */,
|
7AB4E4662D58A16C0006D052 /* GenericError.swift in Sources */,
|
||||||
7AFBE8CA2C3081C7003C491D /* ACProgressHud+Modifiers.swift in Sources */,
|
7AFBE8CA2C3081C7003C491D /* ACProgressHud+Modifiers.swift in Sources */,
|
||||||
7A71EF572D0A26B200943129 /* EventModel.swift in Sources */,
|
7A71EF572D0A26B200943129 /* EventModel.swift in Sources */,
|
||||||
@ -1460,6 +1481,7 @@
|
|||||||
7AC76D7B270083AE0084DB27 /* TextView.swift in Sources */,
|
7AC76D7B270083AE0084DB27 /* TextView.swift in Sources */,
|
||||||
7A2C96122C3B155B00AE46B5 /* NoteAlertModifier.swift in Sources */,
|
7A2C96122C3B155B00AE46B5 /* NoteAlertModifier.swift in Sources */,
|
||||||
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */,
|
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */,
|
||||||
|
7AF231972DA1C30000AE5EB3 /* AuthCoordinator.swift in Sources */,
|
||||||
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
||||||
7A5911F22D63268400EC51BA /* SearchCoordinator.swift in Sources */,
|
7A5911F22D63268400EC51BA /* SearchCoordinator.swift in Sources */,
|
||||||
7A7DADAC2D99738300F52F6C /* AudioRecordView.swift in Sources */,
|
7A7DADAC2D99738300F52F6C /* AudioRecordView.swift in Sources */,
|
||||||
@ -1474,6 +1496,7 @@
|
|||||||
7ADF6C9F251201D200F237B2 /* GlobalEventsController.swift in Sources */,
|
7ADF6C9F251201D200F237B2 /* GlobalEventsController.swift in Sources */,
|
||||||
7A1022792C557ED600B84627 /* LocationPickerViewModel.swift in Sources */,
|
7A1022792C557ED600B84627 /* LocationPickerViewModel.swift in Sources */,
|
||||||
7A11470323FDE7E500B424AF /* SceneDelegate.swift in Sources */,
|
7A11470323FDE7E500B424AF /* SceneDelegate.swift in Sources */,
|
||||||
|
7AF231932DA1C28100AE5EB3 /* AuthScreen.swift in Sources */,
|
||||||
7A1E78F82CE900440004B740 /* ReportViewModel.swift in Sources */,
|
7A1E78F82CE900440004B740 /* ReportViewModel.swift in Sources */,
|
||||||
7A10226E2C551EE000B84627 /* LocationEditViewModel.swift in Sources */,
|
7A10226E2C551EE000B84627 /* LocationEditViewModel.swift in Sources */,
|
||||||
7AB4902B2D6B1446002F39C6 /* ACKeyboardButton.swift in Sources */,
|
7AB4902B2D6B1446002F39C6 /* ACKeyboardButton.swift in Sources */,
|
||||||
@ -1491,6 +1514,7 @@
|
|||||||
7AC3555B296995B200889457 /* UIEdgeInsets.swift in Sources */,
|
7AC3555B296995B200889457 /* UIEdgeInsets.swift in Sources */,
|
||||||
7A06E0AC2C7065AC005731AC /* SettingsScreen.swift in Sources */,
|
7A06E0AC2C7065AC005731AC /* SettingsScreen.swift in Sources */,
|
||||||
7A4322952CB2CD0F00085CF6 /* FiltersCoordinator.swift in Sources */,
|
7A4322952CB2CD0F00085CF6 /* FiltersCoordinator.swift in Sources */,
|
||||||
|
7AF231992DA27C1B00AE5EB3 /* ACButtonView.swift in Sources */,
|
||||||
7A131FD72D37B77E00DC7755 /* HistoryCoordinator.swift in Sources */,
|
7A131FD72D37B77E00DC7755 /* HistoryCoordinator.swift in Sources */,
|
||||||
7A7158002C43EA6900852088 /* OwnersScreen.swift in Sources */,
|
7A7158002C43EA6900852088 /* OwnersScreen.swift in Sources */,
|
||||||
7A4955822D58CCF900912E66 /* HistoryFilter.swift in Sources */,
|
7A4955822D58CCF900912E66 /* HistoryFilter.swift in Sources */,
|
||||||
|
|||||||
@ -84,7 +84,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
let settingsService = ServiceContainer.shared.resolve(SettingsServiceProtocol.self)
|
let settingsService = ServiceContainer.shared.resolve(SettingsServiceProtocol.self)
|
||||||
|
|
||||||
if settingsService.user.token.isEmpty {
|
if settingsService.user.token.isEmpty {
|
||||||
self.window?.rootViewController = storyboard.instantiateViewController(identifier: "AuthController")
|
let coordinator = AuthCoordinator(window: self.window)
|
||||||
|
self.window?.rootViewController = coordinator.start()
|
||||||
|
//self.window?.rootViewController = storyboard.instantiateViewController(identifier: "AuthController")
|
||||||
} else {
|
} else {
|
||||||
self.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController")
|
self.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController")
|
||||||
if let number {
|
if let number {
|
||||||
|
|||||||
43
AutoCat/Screens/AuthScreen/AuthCoordinator.swift
Normal file
43
AutoCat/Screens/AuthScreen/AuthCoordinator.swift
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// AuthCoordinator.swift
|
||||||
|
// AutoCat
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 05.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SwiftUI
|
||||||
|
import AutoCatCore
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
final class AuthCoordinator {
|
||||||
|
|
||||||
|
let window: UIWindow?
|
||||||
|
|
||||||
|
init(window: UIWindow?) {
|
||||||
|
|
||||||
|
self.window = window
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() -> UIViewController {
|
||||||
|
|
||||||
|
let resolver = ServiceContainer.shared
|
||||||
|
let viewModel = AuthViewModel(
|
||||||
|
apiService: resolver.resolve(ApiServiceProtocol.self),
|
||||||
|
storageService: resolver.resolve(StorageServiceProtocol.self),
|
||||||
|
settingsService: resolver.resolve(SettingsServiceProtocol.self)
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.coordinator = self
|
||||||
|
|
||||||
|
let view = AuthScreen(viewModel: viewModel)
|
||||||
|
return UIHostingController(rootView: view)
|
||||||
|
}
|
||||||
|
|
||||||
|
func openMainScreen() {
|
||||||
|
|
||||||
|
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||||
|
window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController")
|
||||||
|
}
|
||||||
|
}
|
||||||
47
AutoCat/Screens/AuthScreen/AuthScreen.swift
Normal file
47
AutoCat/Screens/AuthScreen/AuthScreen.swift
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// AuthScreen.swift
|
||||||
|
// AutoCat
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 05.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AuthScreen: View {
|
||||||
|
|
||||||
|
@State var viewModel: AuthViewModel
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
VStack(spacing: 16) {
|
||||||
|
Group {
|
||||||
|
TextField("Email", text: $viewModel.email, prompt: Text("Email"))
|
||||||
|
.keyboardType(.emailAddress)
|
||||||
|
SecureField("Password", text: $viewModel.password, prompt: Text("Password"))
|
||||||
|
}
|
||||||
|
.padding(8)
|
||||||
|
.background {
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(.background)
|
||||||
|
.stroke(.secondary)
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
ACButtonView(title: "Log In") {
|
||||||
|
Task { await viewModel.login() }
|
||||||
|
}
|
||||||
|
ACButtonView(title: "Sign up") {
|
||||||
|
Task { await viewModel.signup() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.disabled(!viewModel.actionsEnabled)
|
||||||
|
.opacity(viewModel.actionsEnabled ? 1 : 0.5)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 32)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.hud($viewModel.hud)
|
||||||
|
.onAppear(perform: viewModel.onAppear)
|
||||||
|
}
|
||||||
|
}
|
||||||
72
AutoCat/Screens/AuthScreen/AuthViewModel.swift
Normal file
72
AutoCat/Screens/AuthScreen/AuthViewModel.swift
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// AuthViewModel.swift
|
||||||
|
// AutoCat
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 05.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import AutoCatCore
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
@Observable
|
||||||
|
final class AuthViewModel: ACHudContainer {
|
||||||
|
|
||||||
|
let apiService: ApiServiceProtocol
|
||||||
|
let storageService: StorageServiceProtocol
|
||||||
|
var settingsService: SettingsServiceProtocol
|
||||||
|
var coordinator: AuthCoordinator?
|
||||||
|
|
||||||
|
var hud: ACHud?
|
||||||
|
|
||||||
|
var email: String = ""
|
||||||
|
var password: String = ""
|
||||||
|
|
||||||
|
var actionsEnabled: Bool {
|
||||||
|
email.count >= 5 && password.count >= 5
|
||||||
|
}
|
||||||
|
|
||||||
|
init(
|
||||||
|
apiService: ApiServiceProtocol,
|
||||||
|
storageService: StorageServiceProtocol,
|
||||||
|
settingsService: SettingsServiceProtocol
|
||||||
|
) {
|
||||||
|
self.apiService = apiService
|
||||||
|
self.storageService = storageService
|
||||||
|
self.settingsService = settingsService
|
||||||
|
}
|
||||||
|
|
||||||
|
func onAppear() {
|
||||||
|
|
||||||
|
if settingsService.user.email.count > 0 {
|
||||||
|
email = settingsService.user.email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func login() async {
|
||||||
|
await wrapWithToast { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
let user = try await apiService.login(email: email, password: password)
|
||||||
|
try await saveUser(user)
|
||||||
|
coordinator?.openMainScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func signup() async {
|
||||||
|
await wrapWithToast { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
let user = try await apiService.signUp(email: email, password: password)
|
||||||
|
try await saveUser(user)
|
||||||
|
coordinator?.openMainScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveUser(_ user: User) async throws {
|
||||||
|
if user.email != settingsService.user.email {
|
||||||
|
try await storageService.deleteAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
settingsService.user = user
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -36,9 +36,12 @@ class SettingsCoordinator: Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func openAuthScreen() {
|
func openAuthScreen() {
|
||||||
|
guard let window = viewController?.tabBar.window else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
let coordinator = AuthCoordinator(window: window)
|
||||||
viewController?.view.window?.rootViewController = storyboard.instantiateViewController(identifier: "AuthController")
|
window.rootViewController = coordinator.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
func openGoogleOauthPage() {
|
func openGoogleOauthPage() {
|
||||||
|
|||||||
32
AutoCat/SwiftUI/ACButtonView.swift
Normal file
32
AutoCat/SwiftUI/ACButtonView.swift
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// ACButtonView.swift
|
||||||
|
// AutoCat
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 06.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ACButtonView: View {
|
||||||
|
|
||||||
|
let title: LocalizedStringKey
|
||||||
|
let onTap: () -> Void
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Button(action: onTap) {
|
||||||
|
Text(title)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(12)
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
.background {
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(.blue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
ACButtonView(title: "Button") {}
|
||||||
|
}
|
||||||
@ -206,7 +206,7 @@
|
|||||||
"Location adding time" = "Время добавления локаций";
|
"Location adding time" = "Время добавления локаций";
|
||||||
|
|
||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Log In" = "Войти";
|
"Log In" = "Вход";
|
||||||
|
|
||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Main filters" = "Основные фильтры";
|
"Main filters" = "Основные фильтры";
|
||||||
@ -423,3 +423,7 @@
|
|||||||
"Are you sure you want to delete this event?" = "Вы уверены, что хотите удалить это событие?";
|
"Are you sure you want to delete this event?" = "Вы уверены, что хотите удалить это событие?";
|
||||||
|
|
||||||
"Voice records" = "Голосовые записи";
|
"Voice records" = "Голосовые записи";
|
||||||
|
|
||||||
|
"Password" = "Пароль";
|
||||||
|
|
||||||
|
"Sign up" = "Регистрация";
|
||||||
|
|||||||
@ -11,6 +11,9 @@ import Mockable
|
|||||||
@Mockable
|
@Mockable
|
||||||
public protocol ApiServiceProtocol: Sendable {
|
public protocol ApiServiceProtocol: Sendable {
|
||||||
|
|
||||||
|
func login(email: String, password: String) async throws -> User
|
||||||
|
func signUp(email: String, password: String) async throws -> User
|
||||||
|
|
||||||
func add(notes: [VehicleNoteDto], to number: String) async throws -> VehicleDto
|
func add(notes: [VehicleNoteDto], to number: String) async throws -> VehicleDto
|
||||||
func edit(note: VehicleNoteDto) async throws -> VehicleDto
|
func edit(note: VehicleNoteDto) async throws -> VehicleDto
|
||||||
func remove(note id: String) async throws -> VehicleDto
|
func remove(note id: String) async throws -> VehicleDto
|
||||||
|
|||||||
@ -28,6 +28,13 @@ public actor StorageService: StorageServiceProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func deleteAll() async throws {
|
||||||
|
|
||||||
|
try await realm.asyncWrite {
|
||||||
|
realm.deleteAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func updateVehicle(dto: VehicleDto, policy: DbUpdatePolicy) async throws -> Bool {
|
public func updateVehicle(dto: VehicleDto, policy: DbUpdatePolicy) async throws -> Bool {
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,8 @@ public protocol StorageServiceProtocol: Sendable {
|
|||||||
// Generic
|
// Generic
|
||||||
var dbFileURL: URL? { get async }
|
var dbFileURL: URL? { get async }
|
||||||
|
|
||||||
|
func deleteAll() async throws
|
||||||
|
|
||||||
// Vehicles
|
// Vehicles
|
||||||
func loadVehicles() async -> [VehicleDto]
|
func loadVehicles() async -> [VehicleDto]
|
||||||
func loadVehicle(number: String) async throws -> VehicleDto
|
func loadVehicle(number: String) async throws -> VehicleDto
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user