diff --git a/BeReal.xcodeproj/project.pbxproj b/BeReal.xcodeproj/project.pbxproj index a49d426..03762d3 100644 --- a/BeReal.xcodeproj/project.pbxproj +++ b/BeReal.xcodeproj/project.pbxproj @@ -101,6 +101,7 @@ 02AE64ED29363DBF005A4AF3 /* BeReal */ = { isa = PBXGroup; children = ( + 02CE555F293B44C900730DC9 /* Profile */, 02FFFD7929395DBF00306533 /* Extensions */, 02AE64EE29363DBF005A4AF3 /* BeRealApp.swift */, 02AE64F029363DBF005A4AF3 /* ContentView.swift */, @@ -135,6 +136,13 @@ path = BeRealUITests; sourceTree = ""; }; + 02CE555F293B44C900730DC9 /* Profile */ = { + isa = PBXGroup; + children = ( + ); + path = Profile; + sourceTree = ""; + }; 02FFFD7929395DBF00306533 /* Extensions */ = { isa = PBXGroup; children = ( diff --git a/BeReal/ContentView.swift b/BeReal/ContentView.swift index d783c13..12650bb 100644 --- a/BeReal/ContentView.swift +++ b/BeReal/ContentView.swift @@ -9,6 +9,7 @@ import SwiftUI import Browse import Login +import Profile struct ContentView: View { var body: some View { @@ -16,7 +17,7 @@ struct ContentView: View { BrowseView() } .sheet(isPresented: .constant(true)) { - LoginView() + ProfileView {} } } } diff --git a/Modules/Package.swift b/Modules/Package.swift index 93ead91..6e6f8a9 100644 --- a/Modules/Package.swift +++ b/Modules/Package.swift @@ -13,7 +13,8 @@ let package = Package( name: "Modules", targets: [ "Login", - "Browse" + "Browse", + "Profile" ] ), ], @@ -25,6 +26,10 @@ let package = Package( .target( name: "Browse", resources: [.process("Resources")] + ), + .target( + name: "Profile", + resources: [.process("Resources")] ) ] ) diff --git a/Modules/Sources/Profile/Resources/en.lproj/Localizable.strings b/Modules/Sources/Profile/Resources/en.lproj/Localizable.strings new file mode 100644 index 0000000..683966f --- /dev/null +++ b/Modules/Sources/Profile/Resources/en.lproj/Localizable.strings @@ -0,0 +1,19 @@ +/* + Localizable.strings + Profile + + Created by Javier Cicchelli on 03/12/2022. + Copyright © 2022 Röck+Cöde. All rights reserved. +*/ + +"profile.sections.names.header.text" = "Names"; +"profile.sections.names.label.first_name.text" = "First name"; +"profile.sections.names.label.last_name.text" = "Last name"; + +"profile.sections.root_info.header.text" = "Root item information"; +"profile.sections.root_info.label.identifier.text" = "Identifier"; +"profile.sections.root_info.label.is_directory.text" = "Is a directory?"; +"profile.sections.root_info.label.last_modified.text" = "Last modified"; +"profile.sections.root_info.label.name.text" = "Name"; + +"profile.button.log_out.text" = "Log out"; diff --git a/Modules/Sources/Profile/UI/Components/ClearBackgroundList.swift b/Modules/Sources/Profile/UI/Components/ClearBackgroundList.swift new file mode 100644 index 0000000..4e5d66b --- /dev/null +++ b/Modules/Sources/Profile/UI/Components/ClearBackgroundList.swift @@ -0,0 +1,48 @@ +// +// ClearBackgroundList.swift +// Profile +// +// Created by Javier Cicchelli on 03/12/2022. +// Copyright © 2022 Röck+Cöde. All rights reserved. +// + +import SwiftUI + +struct ClearBackgroundList: View where Content: View { + + // MARK: Properties + + @ViewBuilder let content: Content + + // MARK: Body + + var body: some View { + if #available(iOS 16.0, *) { + List{ + content + } + .scrollContentBackground(.hidden) + .scrollIndicators(.hidden) + } else { + List { + content + } + .onAppear { + UITableView.appearance().backgroundColor = .clear + UITableView.appearance().showsVerticalScrollIndicator = false + } + } + } + +} + +// MARK: - Previews + +struct ClearBackgroundList_Previews: PreviewProvider { + static var previews: some View { + ClearBackgroundList { + Text("Something...") + } + .background(Color.red) + } +} diff --git a/Modules/Sources/Profile/UI/Styles/NameAndValueLabelStyle.swift b/Modules/Sources/Profile/UI/Styles/NameAndValueLabelStyle.swift new file mode 100644 index 0000000..7e7f232 --- /dev/null +++ b/Modules/Sources/Profile/UI/Styles/NameAndValueLabelStyle.swift @@ -0,0 +1,38 @@ +// +// NameAndValueLabelStyle.swift +// Profile +// +// Created by Javier Cicchelli on 03/12/2022. +// Copyright © 2022 Röck+Cöde. All rights reserved. +// + +import SwiftUI + +struct NameAndValueLabelStyle: LabelStyle { + func makeBody(configuration: Configuration) -> some View { + VStack( + alignment: .leading, + spacing: 0 + ) { + configuration.icon + .font(.subheadline) + .foregroundColor(.secondary) + + configuration.title + .font(.headline) + .lineLimit(1) + .truncationMode(.middle) + .foregroundColor(.primary) + .frame(maxWidth: .infinity, alignment: .trailing) + } + .padding(.vertical, 8) + } +} + +// MARK: - LabelStyle + +extension LabelStyle where Self == NameAndValueLabelStyle { + static var nameAndValue: Self { + NameAndValueLabelStyle() + } +} diff --git a/Modules/Sources/Profile/UI/Views/ProfileView.swift b/Modules/Sources/Profile/UI/Views/ProfileView.swift new file mode 100644 index 0000000..3794647 --- /dev/null +++ b/Modules/Sources/Profile/UI/Views/ProfileView.swift @@ -0,0 +1,156 @@ +// +// ProfileView.swift +// BeReal +// +// Created by Javier Cicchelli on 03/12/2022. +// Copyright © 2022 Röck+Cöde. All rights reserved. +// + +import SwiftUI + +public struct ProfileView: View { + + // MARK: Properties + + private let logOut: () -> Void + + // MARK: Initialisers + + public init(logOut: @escaping () -> Void) { + self.logOut = logOut + } + + // MARK: Body + + public var body: some View { + ClearBackgroundList { + Section { + Image.photo + .resizable() + .scaledToFit() + .frame(width: 160) + .frame(maxWidth: .infinity) + } + .listRowBackground(Color.clear) + + Section { + Label { + Text("Javier") + } icon: { + Text( + "profile.sections.names.label.first_name.text", + bundle: .module, + comment: "First name label text." + ) + } + .labelStyle(.nameAndValue) + + Label { + Text("Cicchelli") + } icon: { + Text( + "profile.sections.names.label.last_name.text", + bundle: .module, + comment: "Last name label text." + ) + } + .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() + } label: { + Text( + "profile.button.log_out.text", + bundle: .module, + comment: "Log out button text." + ) + .fontWeight(.semibold) + .foregroundColor(.primary) + .frame(maxWidth: .infinity) + } + .tint(.orange) + .buttonStyle(.borderedProminent) + .buttonBorderShape(.roundedRectangle(radius: 8)) + .controlSize(.large) + } + .listRowBackground(Color.clear) + } + .background(Color.red) + } +} + +// MARK: - Images+Constants + +private extension Image { + static let photo = Image(systemName: "person.crop.circle.fill") +} + +// MARK: - Previews + +struct ProfileView_Previews: PreviewProvider { + static var previews: some View { + ProfileView { + // closure for log out action. + } + } +}