Merge pull request #11 from rock-n-code/integration/profile
Integration: Profile
This commit is contained in:
commit
f324b59601
@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
02659B192946AA6900C3AD63 /* SheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02659B182946AA6900C3AD63 /* SheetView.swift */; };
|
||||
026D9825293B6374009FE888 /* Libraries in Frameworks */ = {isa = PBXBuildFile; productRef = 026D9824293B6374009FE888 /* Libraries */; };
|
||||
02AE64EF29363DBF005A4AF3 /* BeRealApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02AE64EE29363DBF005A4AF3 /* BeRealApp.swift */; };
|
||||
02AE64F129363DBF005A4AF3 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02AE64F029363DBF005A4AF3 /* ContentView.swift */; };
|
||||
@ -37,6 +38,7 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
02659B182946AA6900C3AD63 /* SheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetView.swift; sourceTree = "<group>"; };
|
||||
026D9823293B6365009FE888 /* Libraries */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Libraries; sourceTree = "<group>"; };
|
||||
02784F03293A8331005F839D /* Modules */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Modules; sourceTree = "<group>"; };
|
||||
02AE64EB29363DBF005A4AF3 /* BeReal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BeReal.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -80,6 +82,31 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
02659B152946AA2700C3AD63 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02659B162946AA2E00C3AD63 /* Enumerations */,
|
||||
02659B172946AA4400C3AD63 /* Views */,
|
||||
);
|
||||
path = UI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
02659B162946AA2E00C3AD63 /* Enumerations */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02659B182946AA6900C3AD63 /* SheetView.swift */,
|
||||
);
|
||||
path = Enumerations;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
02659B172946AA4400C3AD63 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02AE64F029363DBF005A4AF3 /* ContentView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
02AE64E229363DBF005A4AF3 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -108,8 +135,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02AE64EE29363DBF005A4AF3 /* BeRealApp.swift */,
|
||||
02AE64F029363DBF005A4AF3 /* ContentView.swift */,
|
||||
02AE64F229363DC1005A4AF3 /* Assets.xcassets */,
|
||||
02659B152946AA2700C3AD63 /* UI */,
|
||||
02AE64F429363DC1005A4AF3 /* Preview Content */,
|
||||
);
|
||||
path = BeReal;
|
||||
@ -284,6 +311,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
02AE64F129363DBF005A4AF3 /* ContentView.swift in Sources */,
|
||||
02659B192946AA6900C3AD63 /* SheetView.swift in Sources */,
|
||||
02AE64EF29363DBF005A4AF3 /* BeRealApp.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1,49 +0,0 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// BeReal
|
||||
//
|
||||
// Created by Javier Cicchelli on 29/11/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import Browse
|
||||
import DataModels
|
||||
import Login
|
||||
import KeychainStorage
|
||||
import Profile
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
// MARK: Storages
|
||||
|
||||
@KeychainStorage(key: .KeychainStorage.account) private var account: Account?
|
||||
|
||||
// MARK: Body
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
BrowseView()
|
||||
}
|
||||
.sheet(isPresented: showLogin) {
|
||||
LoginView()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension ContentView {
|
||||
var showLogin: Binding<Bool> {
|
||||
.init { account == nil } set: { _ in }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
}
|
||||
}
|
20
BeReal/UI/Enumerations/SheetView.swift
Normal file
20
BeReal/UI/Enumerations/SheetView.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// SheetView.swift
|
||||
// BeReal
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
// MARK: - Enumerations
|
||||
|
||||
enum SheetView: Int {
|
||||
case login
|
||||
case profile
|
||||
}
|
||||
|
||||
// MARK: - Identifiable
|
||||
|
||||
extension SheetView: Identifiable {
|
||||
var id: Int { rawValue }
|
||||
}
|
79
BeReal/UI/Views/ContentView.swift
Normal file
79
BeReal/UI/Views/ContentView.swift
Normal file
@ -0,0 +1,79 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// BeReal
|
||||
//
|
||||
// Created by Javier Cicchelli on 29/11/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import Browse
|
||||
import DataModels
|
||||
import Login
|
||||
import KeychainStorage
|
||||
import Profile
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
// MARK: Storages
|
||||
|
||||
@KeychainStorage(key: .KeychainStorage.account) private var account: Account?
|
||||
|
||||
// MARK: States
|
||||
|
||||
@State private var user: User?
|
||||
@State private var showSheet: SheetView?
|
||||
|
||||
// MARK: Body
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
BrowseView {
|
||||
// ...
|
||||
} uploadFile: {
|
||||
// ...
|
||||
} showProfile: {
|
||||
showSheet = .profile
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
shouldShowLogin()
|
||||
}
|
||||
.onChange(of: account) { _ in
|
||||
shouldShowLogin()
|
||||
}
|
||||
.sheet(item: $showSheet) { sheet in
|
||||
switch sheet {
|
||||
case .login:
|
||||
LoginView {
|
||||
user = $1
|
||||
account = $0
|
||||
}
|
||||
case .profile:
|
||||
ProfileView(user: user) {
|
||||
user = nil
|
||||
account = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension ContentView {
|
||||
func shouldShowLogin() {
|
||||
showSheet = account == nil
|
||||
? .login
|
||||
: nil
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
}
|
||||
}
|
9
Libraries/Sources/DataModels/Defines/Typealiases.swift
Normal file
9
Libraries/Sources/DataModels/Defines/Typealiases.swift
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// Typealiases.swift
|
||||
// DataModels
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
public typealias ActionClosure = () -> Void
|
@ -6,7 +6,7 @@
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
public struct Account: Codable {
|
||||
public struct Account: Codable, Equatable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
|
@ -31,10 +31,18 @@ let package = Package(
|
||||
),
|
||||
.target(
|
||||
name: "Browse",
|
||||
dependencies: [
|
||||
"Cores",
|
||||
"Libraries"
|
||||
],
|
||||
resources: [.process("Resources")]
|
||||
),
|
||||
.target(
|
||||
name: "Profile",
|
||||
dependencies: [
|
||||
"Cores",
|
||||
"Libraries"
|
||||
],
|
||||
resources: [.process("Resources")]
|
||||
)
|
||||
]
|
||||
|
@ -1,19 +1,29 @@
|
||||
//
|
||||
// BrowseToolbar.swift
|
||||
// BeReal
|
||||
// Browse
|
||||
//
|
||||
// Created by Javier Cicchelli on 03/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import DataModels
|
||||
import SwiftUI
|
||||
|
||||
struct BrowseToolbar: ToolbarContent {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
let createFolder: ActionClosure
|
||||
let uploadFile: ActionClosure
|
||||
let showProfile: ActionClosure
|
||||
|
||||
// MARK: Body
|
||||
|
||||
var body: some ToolbarContent {
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
Menu {
|
||||
Button {
|
||||
// TODO: Implement the creation of a new folder.
|
||||
createFolder()
|
||||
} label: {
|
||||
Label {
|
||||
Text(
|
||||
@ -27,7 +37,7 @@ struct BrowseToolbar: ToolbarContent {
|
||||
}
|
||||
|
||||
Button {
|
||||
// TODO: Implement the upload of a file from the device to the API.
|
||||
uploadFile()
|
||||
} label: {
|
||||
Label {
|
||||
Text(
|
||||
@ -55,7 +65,7 @@ struct BrowseToolbar: ToolbarContent {
|
||||
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button {
|
||||
// TODO: Implement the show of the user profile.
|
||||
showProfile()
|
||||
} label: {
|
||||
Label {
|
||||
Text(
|
||||
@ -70,6 +80,7 @@ struct BrowseToolbar: ToolbarContent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Image+Constants
|
||||
|
@ -6,13 +6,28 @@
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import DataModels
|
||||
import SwiftUI
|
||||
|
||||
public struct BrowseView: View {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private let createFolder: ActionClosure
|
||||
private let uploadFile: ActionClosure
|
||||
private let showProfile: ActionClosure
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
public init() {}
|
||||
public init(
|
||||
createFolder: @escaping ActionClosure,
|
||||
uploadFile: @escaping ActionClosure,
|
||||
showProfile: @escaping ActionClosure
|
||||
) {
|
||||
self.createFolder = createFolder
|
||||
self.uploadFile = uploadFile
|
||||
self.showProfile = showProfile
|
||||
}
|
||||
|
||||
// MARK: Body
|
||||
|
||||
@ -106,7 +121,11 @@ public struct BrowseView: View {
|
||||
.background(Color.red)
|
||||
.navigationTitle("Folder name")
|
||||
.toolbar {
|
||||
BrowseToolbar()
|
||||
BrowseToolbar(
|
||||
createFolder: createFolder,
|
||||
uploadFile: uploadFile,
|
||||
showProfile: showProfile
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,7 +142,13 @@ private extension Image {
|
||||
struct BrowseView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
NavigationView {
|
||||
BrowseView()
|
||||
BrowseView {
|
||||
// ...
|
||||
} uploadFile: {
|
||||
// ...
|
||||
} showProfile: {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Modules/Sources/Login/Logic/Defines/Typealiases.swift
Normal file
11
Modules/Sources/Login/Logic/Defines/Typealiases.swift
Normal file
@ -0,0 +1,11 @@
|
||||
//
|
||||
// Typealiases.swift
|
||||
// Login
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import DataModels
|
||||
|
||||
public typealias AuthenticatedClosure = (Account, User) -> Void
|
55
Modules/Sources/Login/Logic/Use Cases/GetUserUseCase.swift
Normal file
55
Modules/Sources/Login/Logic/Use Cases/GetUserUseCase.swift
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// GetUserUseCase.swift
|
||||
// Login
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import APIService
|
||||
import DependencyInjection
|
||||
import Dependencies
|
||||
|
||||
struct GetUserUseCase {
|
||||
|
||||
// MARK: Dependencies
|
||||
|
||||
@Dependency(\.apiService) private var apiService
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
let authenticated: AuthenticatedClosure
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
func callAsFunction(
|
||||
username: String,
|
||||
password: String
|
||||
) async throws {
|
||||
let me = try await apiService.getUser(
|
||||
credentials: .init(
|
||||
username: username,
|
||||
password: password
|
||||
)
|
||||
)
|
||||
|
||||
authenticated(
|
||||
.init(
|
||||
username: username,
|
||||
password: password
|
||||
),
|
||||
.init(
|
||||
profile: .init(
|
||||
firstName: me.firstName,
|
||||
lastName: me.lastName
|
||||
),
|
||||
rootFolder: .init(
|
||||
id: me.rootItem.id,
|
||||
name: me.rootItem.name,
|
||||
lastModifiedAt: me.rootItem.lastModifiedAt
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -7,10 +7,6 @@
|
||||
//
|
||||
|
||||
import APIService
|
||||
import DataModels
|
||||
import DependencyInjection
|
||||
import Dependencies
|
||||
import KeychainStorage
|
||||
import SwiftUI
|
||||
|
||||
public struct LoginView: View {
|
||||
@ -19,9 +15,15 @@ public struct LoginView: View {
|
||||
|
||||
@State private var containerTopPadding: CGFloat = 0
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private let authenticated: AuthenticatedClosure
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
public init() {}
|
||||
public init(authenticated: @escaping AuthenticatedClosure) {
|
||||
self.authenticated = authenticated
|
||||
}
|
||||
|
||||
// MARK: Body
|
||||
|
||||
@ -30,7 +32,7 @@ public struct LoginView: View {
|
||||
.vertical,
|
||||
showsIndicators: false
|
||||
) {
|
||||
LoginContainer()
|
||||
LoginContainer(authenticated: authenticated)
|
||||
.padding(.horizontal, 24)
|
||||
.padding(.top, containerTopPadding)
|
||||
}
|
||||
@ -39,6 +41,7 @@ public struct LoginView: View {
|
||||
.onPreferenceChange(ViewHeightPreferenceKey.self) { height in
|
||||
containerTopPadding = height * 0.1
|
||||
}
|
||||
.interactiveDismissDisabled()
|
||||
}
|
||||
|
||||
}
|
||||
@ -47,21 +50,23 @@ public struct LoginView: View {
|
||||
|
||||
fileprivate extension LoginView {
|
||||
struct LoginContainer: View {
|
||||
|
||||
// MARK: Dependencies
|
||||
|
||||
@Dependency(\.apiService) private var apiService
|
||||
|
||||
// MARK: Storages
|
||||
|
||||
@KeychainStorage(key: .KeychainStorage.account) private var account: Account?
|
||||
|
||||
|
||||
// MARK: States
|
||||
|
||||
@State private var isAuthenticating: Bool = false
|
||||
@State private var username: String = ""
|
||||
@State private var password: String = ""
|
||||
@State private var errorMessage: String?
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private let getUser: GetUserUseCase
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
init(authenticated: @escaping AuthenticatedClosure) {
|
||||
self.getUser = .init(authenticated: authenticated)
|
||||
}
|
||||
|
||||
// MARK: Body
|
||||
|
||||
@ -133,12 +138,7 @@ private extension LoginView.LoginContainer {
|
||||
guard isAuthenticating else { return }
|
||||
|
||||
do {
|
||||
_ = try await apiService.getUser(credentials: .init(
|
||||
username: username,
|
||||
password: password
|
||||
))
|
||||
|
||||
account = .init(
|
||||
try await getUser(
|
||||
username: username,
|
||||
password: password
|
||||
)
|
||||
@ -157,6 +157,8 @@ private extension LoginView.LoginContainer {
|
||||
|
||||
struct LoginView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
LoginView()
|
||||
LoginView { _, _ in
|
||||
// closure for authenticated action.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
41
Modules/Sources/Profile/Logic/Adapters/DateAdapter.swift
Normal file
41
Modules/Sources/Profile/Logic/Adapters/DateAdapter.swift
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// DateAdapter.swift
|
||||
// Profile
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct DateAdapter {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private let dateFormatter: DateFormatter = .dateTimeFormatter
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
func callAsFunction(value: Date?) -> String {
|
||||
if let value {
|
||||
return dateFormatter.string(from: value)
|
||||
} else {
|
||||
return .Constants.noValue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - DateFormatter+Formats
|
||||
|
||||
private extension DateFormatter {
|
||||
static let dateTimeFormatter = {
|
||||
let formatter = DateFormatter()
|
||||
|
||||
formatter.dateStyle = .long
|
||||
formatter.timeStyle = .short
|
||||
formatter.locale = .current
|
||||
|
||||
return formatter
|
||||
}()
|
||||
}
|
13
Modules/Sources/Profile/Logic/Adapters/StringAdapter.swift
Normal file
13
Modules/Sources/Profile/Logic/Adapters/StringAdapter.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// StringAdapter.swift
|
||||
// Profile
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
struct StringAdapter {
|
||||
func callAsFunction(value: String?) -> String {
|
||||
value ?? .Constants.noValue
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
//
|
||||
// String+Constants.swift
|
||||
// Profile
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
extension String {
|
||||
enum Constants {
|
||||
static let noValue = "-"
|
||||
}
|
||||
}
|
75
Modules/Sources/Profile/UI/Components/ProfileSection.swift
Normal file
75
Modules/Sources/Profile/UI/Components/ProfileSection.swift
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// ProfileSection.swift
|
||||
// Profile
|
||||
//
|
||||
// Created by Javier Cicchelli on 12/12/2022.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ProfileSection: View {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
let header: LocalizedStringKey
|
||||
let items: [Item]
|
||||
|
||||
// MARK: Body
|
||||
|
||||
var body: some View {
|
||||
Section {
|
||||
ForEach(items) { item in
|
||||
Label {
|
||||
Text(item.value)
|
||||
} icon: {
|
||||
Text(
|
||||
item.key,
|
||||
bundle: .module
|
||||
)
|
||||
}
|
||||
.labelStyle(.nameAndValue)
|
||||
}
|
||||
} header: {
|
||||
Text(
|
||||
header,
|
||||
bundle: .module
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Structs
|
||||
|
||||
extension ProfileSection {
|
||||
struct Item {
|
||||
let key: LocalizedStringKey
|
||||
let value: String
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Identifiable
|
||||
|
||||
extension ProfileSection.Item: Identifiable {
|
||||
var id: String { UUID().uuidString }
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct ProfileSection_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ProfileSection(
|
||||
header: "some-localised-header-key",
|
||||
items: [
|
||||
.init(
|
||||
key: "some-localized-key",
|
||||
value: "some value"
|
||||
),
|
||||
.init(
|
||||
key: "some-other-localised-key",
|
||||
value: "some other value"
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
@ -6,18 +6,27 @@
|
||||
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||
//
|
||||
|
||||
import DataModels
|
||||
import SwiftUI
|
||||
|
||||
public struct ProfileView: View {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
private let logOut: () -> Void
|
||||
private let user: User?
|
||||
private let logout: ActionClosure
|
||||
|
||||
private let stringAdapter = StringAdapter()
|
||||
private let dateAdapter = DateAdapter()
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
public init(logOut: @escaping () -> Void) {
|
||||
self.logOut = logOut
|
||||
public init(
|
||||
user: User?,
|
||||
logout: @escaping ActionClosure
|
||||
) {
|
||||
self.user = user
|
||||
self.logout = logout
|
||||
}
|
||||
|
||||
// MARK: Body
|
||||
@ -33,96 +42,45 @@ public struct ProfileView: View {
|
||||
}
|
||||
.listRowBackground(Color.clear)
|
||||
|
||||
Section {
|
||||
Label {
|
||||
Text("Javier")
|
||||
} icon: {
|
||||
Text(
|
||||
"profile.sections.names.label.first_name.text",
|
||||
bundle: .module,
|
||||
comment: "First name label text."
|
||||
ProfileSection(
|
||||
header: "profile.sections.names.header.text",
|
||||
items: [
|
||||
.init(
|
||||
key: "profile.sections.names.label.first_name.text",
|
||||
value: stringAdapter(value: user?.profile.firstName)
|
||||
),
|
||||
.init(
|
||||
key: "profile.sections.names.label.last_name.text",
|
||||
value: stringAdapter(value: user?.profile.lastName)
|
||||
)
|
||||
}
|
||||
.labelStyle(.nameAndValue)
|
||||
|
||||
Label {
|
||||
Text("Cicchelli")
|
||||
} icon: {
|
||||
Text(
|
||||
"profile.sections.names.label.last_name.text",
|
||||
bundle: .module,
|
||||
comment: "Last name label text."
|
||||
]
|
||||
)
|
||||
|
||||
ProfileSection(
|
||||
header: "profile.sections.root_info.header.text",
|
||||
items: [
|
||||
.init(
|
||||
key: "profile.sections.root_info.label.identifier.text",
|
||||
value: stringAdapter(value: user?.rootFolder.id)
|
||||
),
|
||||
.init(
|
||||
key: "profile.sections.root_info.label.name.text",
|
||||
value: stringAdapter(value: user?.rootFolder.name)
|
||||
),
|
||||
.init(
|
||||
key: "profile.sections.root_info.label.last_modified.text",
|
||||
value: dateAdapter(value: user?.rootFolder.lastModifiedAt)
|
||||
)
|
||||
}
|
||||
.labelStyle(.nameAndValue)
|
||||
} header: {
|
||||
Text(
|
||||
"profile.sections.names.header.text",
|
||||
bundle: .module,
|
||||
comment: "Names section header text."
|
||||
)
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
Section {
|
||||
Label {
|
||||
Text("71207ee4c0573fde80b03643caafe62731406404")
|
||||
} icon: {
|
||||
Text(
|
||||
"profile.sections.root_info.label.identifier.text",
|
||||
bundle: .module,
|
||||
comment: "Identifier label text."
|
||||
)
|
||||
}
|
||||
.labelStyle(.nameAndValue)
|
||||
|
||||
Label {
|
||||
Text("Yes")
|
||||
} icon: {
|
||||
Text(
|
||||
"profile.sections.root_info.label.is_directory.text",
|
||||
bundle: .module,
|
||||
comment: "Is directory label text."
|
||||
)
|
||||
}
|
||||
.labelStyle(.nameAndValue)
|
||||
|
||||
Label {
|
||||
Text("3 days ago")
|
||||
} icon: {
|
||||
Text(
|
||||
"profile.sections.root_info.label.last_modified.text",
|
||||
bundle: .module,
|
||||
comment: "Last modified label text."
|
||||
)
|
||||
}
|
||||
.labelStyle(.nameAndValue)
|
||||
|
||||
Label {
|
||||
Text("My files")
|
||||
} icon: {
|
||||
Text(
|
||||
"profile.sections.root_info.label.name.text",
|
||||
bundle: .module,
|
||||
comment: "Root name label text."
|
||||
)
|
||||
}
|
||||
.labelStyle(.nameAndValue)
|
||||
} header: {
|
||||
Text(
|
||||
"profile.sections.root_info.header.text",
|
||||
bundle: .module,
|
||||
comment: "Root item information header text."
|
||||
)
|
||||
}
|
||||
|
||||
Section {
|
||||
Button {
|
||||
logOut()
|
||||
logout()
|
||||
} label: {
|
||||
Text(
|
||||
"profile.button.log_out.text",
|
||||
bundle: .module,
|
||||
comment: "Log out button text."
|
||||
bundle: .module
|
||||
)
|
||||
.fontWeight(.semibold)
|
||||
.foregroundColor(.primary)
|
||||
@ -137,6 +95,7 @@ public struct ProfileView: View {
|
||||
}
|
||||
.background(Color.red)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Images+Constants
|
||||
@ -149,8 +108,18 @@ private extension Image {
|
||||
|
||||
struct ProfileView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ProfileView {
|
||||
// closure for log out action.
|
||||
ProfileView(user: .init(
|
||||
profile: .init(
|
||||
firstName: "Some first name...",
|
||||
lastName: "Some last name..."
|
||||
),
|
||||
rootFolder: .init(
|
||||
id: "1234567890",
|
||||
name: "Some folder name...",
|
||||
lastModifiedAt: .now
|
||||
)
|
||||
)) {
|
||||
// closure for logout action.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user