feat: Fixes signup flow, begins updating form input fields.
This commit is contained in:
@@ -5366,9 +5366,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.my-1 {
|
||||||
|
margin-block: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.my-1\.5 {
|
.my-1\.5 {
|
||||||
margin-block: calc(var(--spacing) * 1.5);
|
margin-block: calc(var(--spacing) * 1.5);
|
||||||
}
|
}
|
||||||
|
.my-6 {
|
||||||
|
margin-block: calc(var(--spacing) * 6);
|
||||||
|
}
|
||||||
.my-auto {
|
.my-auto {
|
||||||
margin-block: auto;
|
margin-block: auto;
|
||||||
}
|
}
|
||||||
@@ -7823,6 +7829,9 @@
|
|||||||
.px-4 {
|
.px-4 {
|
||||||
padding-inline: calc(var(--spacing) * 4);
|
padding-inline: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
|
.py-1 {
|
||||||
|
padding-block: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.py-1\.5 {
|
.py-1\.5 {
|
||||||
padding-block: calc(var(--spacing) * 1.5);
|
padding-block: calc(var(--spacing) * 1.5);
|
||||||
}
|
}
|
||||||
@@ -7832,6 +7841,9 @@
|
|||||||
.py-4 {
|
.py-4 {
|
||||||
padding-block: calc(var(--spacing) * 4);
|
padding-block: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
|
.py-6 {
|
||||||
|
padding-block: calc(var(--spacing) * 6);
|
||||||
|
}
|
||||||
.ps-2 {
|
.ps-2 {
|
||||||
padding-inline-start: calc(var(--spacing) * 2);
|
padding-inline-start: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
@@ -8476,6 +8488,9 @@
|
|||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.text-base-100 {
|
||||||
|
color: var(--color-base-100);
|
||||||
|
}
|
||||||
.text-base-content {
|
.text-base-content {
|
||||||
color: var(--color-base-content);
|
color: var(--color-base-content);
|
||||||
}
|
}
|
||||||
@@ -8491,12 +8506,21 @@
|
|||||||
.text-info {
|
.text-info {
|
||||||
color: var(--color-info);
|
color: var(--color-info);
|
||||||
}
|
}
|
||||||
|
.text-neutral {
|
||||||
|
color: var(--color-neutral);
|
||||||
|
}
|
||||||
|
.text-neutral-content {
|
||||||
|
color: var(--color-neutral-content);
|
||||||
|
}
|
||||||
.text-primary {
|
.text-primary {
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
.text-secondary {
|
.text-secondary {
|
||||||
color: var(--color-secondary);
|
color: var(--color-secondary);
|
||||||
}
|
}
|
||||||
|
.text-secondary-content {
|
||||||
|
color: var(--color-secondary-content);
|
||||||
|
}
|
||||||
.text-slate-900 {
|
.text-slate-900 {
|
||||||
color: var(--color-slate-900);
|
color: var(--color-slate-900);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ extension DatabaseClient {
|
|||||||
public struct UserProfile: Sendable {
|
public struct UserProfile: Sendable {
|
||||||
public var create: @Sendable (User.Profile.Create) async throws -> User.Profile
|
public var create: @Sendable (User.Profile.Create) async throws -> User.Profile
|
||||||
public var delete: @Sendable (User.Profile.ID) async throws -> Void
|
public var delete: @Sendable (User.Profile.ID) async throws -> Void
|
||||||
|
public var fetch: @Sendable (User.ID) async throws -> User.Profile?
|
||||||
public var get: @Sendable (User.Profile.ID) async throws -> User.Profile?
|
public var get: @Sendable (User.Profile.ID) async throws -> User.Profile?
|
||||||
public var update: @Sendable (User.Profile.ID, User.Profile.Update) async throws -> User.Profile
|
public var update: @Sendable (User.Profile.ID, User.Profile.Update) async throws -> User.Profile
|
||||||
}
|
}
|
||||||
@@ -32,6 +33,13 @@ extension DatabaseClient.UserProfile: TestDependencyKey {
|
|||||||
}
|
}
|
||||||
try await model.delete(on: database)
|
try await model.delete(on: database)
|
||||||
},
|
},
|
||||||
|
fetch: { userID in
|
||||||
|
try await UserProfileModel.query(on: database)
|
||||||
|
.with(\.$user)
|
||||||
|
.filter(\.$user.$id == userID)
|
||||||
|
.first()
|
||||||
|
.map { try $0.toDTO() }
|
||||||
|
},
|
||||||
get: { id in
|
get: { id in
|
||||||
try await UserProfileModel.find(id, on: database)
|
try await UserProfileModel.find(id, on: database)
|
||||||
.map { try $0.toDTO() }
|
.map { try $0.toDTO() }
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
import Elementary
|
import Elementary
|
||||||
|
|
||||||
|
public struct LabeledInput: HTML, Sendable {
|
||||||
|
|
||||||
|
let labelText: String
|
||||||
|
let inputAttributes: [HTMLAttribute<HTMLTag.input>]
|
||||||
|
|
||||||
|
public init(
|
||||||
|
_ label: String,
|
||||||
|
_ attributes: HTMLAttribute<HTMLTag.input>...
|
||||||
|
) {
|
||||||
|
self.labelText = label
|
||||||
|
self.inputAttributes = attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
public var body: some HTML<HTMLTag.label> {
|
||||||
|
label(.class("input w-full")) {
|
||||||
|
span(.class("label")) { labelText }
|
||||||
|
input(attributes: inputAttributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct Input: HTML, Sendable {
|
public struct Input: HTML, Sendable {
|
||||||
|
|
||||||
let id: String?
|
let id: String?
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public struct Label: HTML, Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var body: some HTML<HTMLTag.span> {
|
public var body: some HTML<HTMLTag.span> {
|
||||||
span(.class("text-xl text-gray-400 font-bold")) {
|
span(.class("text-xl text-secondary font-bold")) {
|
||||||
title
|
title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ extension ViewController.Request {
|
|||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
func createAndAuthenticate(
|
func createAndAuthenticate(
|
||||||
_ signup: User.Create
|
_ signup: User.Create
|
||||||
) async throws -> User {
|
) async throws -> User {
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ extension ViewController.Request {
|
|||||||
|
|
||||||
switch route {
|
switch route {
|
||||||
case .test:
|
case .test:
|
||||||
return view {
|
return await view {
|
||||||
TestPage()
|
TestPage()
|
||||||
}
|
}
|
||||||
case .login(let route):
|
case .login(let route):
|
||||||
switch route {
|
switch route {
|
||||||
case .index(let next):
|
case .index(let next):
|
||||||
return view {
|
return await view {
|
||||||
LoginForm(next: next)
|
LoginForm(next: next)
|
||||||
}
|
}
|
||||||
case .submit(let login):
|
case .submit(let login):
|
||||||
@@ -35,7 +35,7 @@ extension ViewController.Request {
|
|||||||
case .signup(let route):
|
case .signup(let route):
|
||||||
switch route {
|
switch route {
|
||||||
case .index:
|
case .index:
|
||||||
return view {
|
return await view {
|
||||||
LoginForm(style: .signup)
|
LoginForm(style: .signup)
|
||||||
}
|
}
|
||||||
case .submit(let request):
|
case .submit(let request):
|
||||||
@@ -53,10 +53,11 @@ extension ViewController.Request {
|
|||||||
return await view {
|
return await view {
|
||||||
await ResultView {
|
await ResultView {
|
||||||
_ = try await database.userProfile.create(profile)
|
_ = try await database.userProfile.create(profile)
|
||||||
let user = try currentUser()
|
let userID = profile.userID
|
||||||
|
// let user = try currentUser()
|
||||||
return (
|
return (
|
||||||
user.id,
|
userID,
|
||||||
try await database.projects.fetch(user.id, .init(page: 1, per: 25))
|
try await database.projects.fetch(userID, .init(page: 1, per: 25))
|
||||||
)
|
)
|
||||||
} onSuccess: { (userID, projects) in
|
} onSuccess: { (userID, projects) in
|
||||||
ProjectsTable(userID: userID, projects: projects)
|
ProjectsTable(userID: userID, projects: projects)
|
||||||
@@ -71,16 +72,11 @@ extension ViewController.Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func view<C: HTML>(
|
|
||||||
@HTMLBuilder inner: () -> C
|
|
||||||
) -> AnySendableHTML where C: Sendable {
|
|
||||||
MainPage(theme: theme) { inner() }
|
|
||||||
}
|
|
||||||
|
|
||||||
func view<C: HTML>(
|
func view<C: HTML>(
|
||||||
@HTMLBuilder inner: () async -> C
|
@HTMLBuilder inner: () async -> C
|
||||||
) async -> AnySendableHTML where C: Sendable {
|
) async -> AnySendableHTML where C: Sendable {
|
||||||
let inner = await inner()
|
let inner = await inner()
|
||||||
|
let theme = await self.theme
|
||||||
|
|
||||||
return MainPage(theme: theme) {
|
return MainPage(theme: theme) {
|
||||||
inner
|
inner
|
||||||
@@ -88,8 +84,11 @@ extension ViewController.Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var theme: Theme? {
|
var theme: Theme? {
|
||||||
nil
|
get async {
|
||||||
// .dracula
|
@Dependency(\.database) var database
|
||||||
|
guard let user = try? currentUser() else { return nil }
|
||||||
|
return try? await database.userProfile.fetch(user.id)?.theme
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,7 +633,7 @@ extension SiteRoute.View.UserRoute.Profile {
|
|||||||
let user = try request.currentUser()
|
let user = try request.currentUser()
|
||||||
return (
|
return (
|
||||||
user,
|
user,
|
||||||
try await database.userProfile.get(user.id)
|
try await database.userProfile.fetch(user.id)
|
||||||
)
|
)
|
||||||
} onSuccess: { (user, profile) in
|
} onSuccess: { (user, profile) in
|
||||||
UserView(user: user, profile: profile)
|
UserView(user: user, profile: profile)
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ import Styleguide
|
|||||||
|
|
||||||
struct Navbar: HTML, Sendable {
|
struct Navbar: HTML, Sendable {
|
||||||
let sidebarToggle: Bool
|
let sidebarToggle: Bool
|
||||||
|
let userProfile: Bool
|
||||||
|
|
||||||
|
init(
|
||||||
|
sidebarToggle: Bool,
|
||||||
|
userProfile: Bool = true
|
||||||
|
) {
|
||||||
|
self.sidebarToggle = sidebarToggle
|
||||||
|
self.userProfile = userProfile
|
||||||
|
}
|
||||||
|
|
||||||
var body: some HTML<HTMLTag.nav> {
|
var body: some HTML<HTMLTag.nav> {
|
||||||
nav(
|
nav(
|
||||||
@@ -41,41 +50,44 @@ struct Navbar: HTML, Sendable {
|
|||||||
.navButton()
|
.navButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
div(.class("flex-none")) {
|
if userProfile {
|
||||||
a(
|
// TODO: Make dropdown
|
||||||
.href(route: .user(.profile(.index))),
|
div(.class("flex-none")) {
|
||||||
) {
|
a(
|
||||||
SVG(.circleUser)
|
.href(route: .user(.profile(.index))),
|
||||||
|
) {
|
||||||
|
SVG(.circleUser)
|
||||||
|
}
|
||||||
|
.navButton()
|
||||||
|
// details(.class("dropdown dropdown-left dropdown-bottom")) {
|
||||||
|
// summary(.class("btn w-fit px-4 py-2")) {
|
||||||
|
// SVG(.circleUser)
|
||||||
|
// }
|
||||||
|
// .navButton()
|
||||||
|
//
|
||||||
|
// ul(
|
||||||
|
// .class(
|
||||||
|
// """
|
||||||
|
// menu dropdown-content bg-base-100
|
||||||
|
// rounded-box z-1 w-fit p-2 shadow-sm
|
||||||
|
// """
|
||||||
|
// )
|
||||||
|
// ) {
|
||||||
|
// li(.class("w-full")) {
|
||||||
|
// // TODO: Save theme to user profile ??
|
||||||
|
// div(.class("flex justify-between p-4 space-x-6")) {
|
||||||
|
// Label("Theme")
|
||||||
|
// input(.type(.checkbox), .class("toggle theme-controller"), .value("light"))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // button(.class("w-fit px-4 py-2")) {
|
||||||
|
// // SVG(.circleUser)
|
||||||
|
// // }
|
||||||
|
// // .navButton()
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
.navButton()
|
|
||||||
// details(.class("dropdown dropdown-left dropdown-bottom")) {
|
|
||||||
// summary(.class("btn w-fit px-4 py-2")) {
|
|
||||||
// SVG(.circleUser)
|
|
||||||
// }
|
|
||||||
// .navButton()
|
|
||||||
//
|
|
||||||
// ul(
|
|
||||||
// .class(
|
|
||||||
// """
|
|
||||||
// menu dropdown-content bg-base-100
|
|
||||||
// rounded-box z-1 w-fit p-2 shadow-sm
|
|
||||||
// """
|
|
||||||
// )
|
|
||||||
// ) {
|
|
||||||
// li(.class("w-full")) {
|
|
||||||
// // TODO: Save theme to user profile ??
|
|
||||||
// div(.class("flex justify-between p-4 space-x-6")) {
|
|
||||||
// Label("Theme")
|
|
||||||
// input(.type(.checkbox), .class("toggle theme-controller"), .value("light"))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // button(.class("w-fit px-4 py-2")) {
|
|
||||||
// // SVG(.circleUser)
|
|
||||||
// // }
|
|
||||||
// // .navButton()
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ struct ProjectForm: HTML, Sendable {
|
|||||||
ModalForm(id: Self.id, dismiss: dismiss) {
|
ModalForm(id: Self.id, dismiss: dismiss) {
|
||||||
h1(.class("text-3xl font-bold pb-6 ps-2")) { "Project" }
|
h1(.class("text-3xl font-bold pb-6 ps-2")) { "Project" }
|
||||||
form(
|
form(
|
||||||
.class("space-y-4 p-4"),
|
.class("grid grid-cols-1 gap-4"),
|
||||||
project == nil
|
project == nil
|
||||||
? .hx.post(route)
|
? .hx.post(route)
|
||||||
: .hx.patch(route),
|
: .hx.patch(route),
|
||||||
@@ -38,36 +38,54 @@ struct ProjectForm: HTML, Sendable {
|
|||||||
input(.class("hidden"), .name("id"), .value("\(project.id)"))
|
input(.class("hidden"), .name("id"), .value("\(project.id)"))
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
LabeledInput(
|
||||||
label(.for("name")) { "Name" }
|
"Name",
|
||||||
Input(id: "name", placeholder: "Name")
|
.name("name"),
|
||||||
.attributes(.type(.text), .required, .autofocus, .value(project?.name))
|
.type(.text),
|
||||||
}
|
.value(project?.name),
|
||||||
div {
|
.placeholder("Project Name"),
|
||||||
label(.for("streetAddress")) { "Address" }
|
.required,
|
||||||
Input(id: "streetAddress", placeholder: "Street Address")
|
.autofocus
|
||||||
.attributes(.type(.text), .required, .value(project?.streetAddress))
|
)
|
||||||
}
|
|
||||||
div {
|
|
||||||
label(.for("city")) { "City" }
|
|
||||||
Input(id: "city", placeholder: "City")
|
|
||||||
.attributes(.type(.text), .required, .value(project?.city))
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
label(.for("state")) { "State" }
|
|
||||||
Input(id: "state", placeholder: "State")
|
|
||||||
.attributes(.type(.text), .required, .value(project?.state))
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
label(.for("zipCode")) { "Zip" }
|
|
||||||
Input(id: "zipCode", placeholder: "Zip code")
|
|
||||||
.attributes(.type(.text), .required, .value(project?.zipCode))
|
|
||||||
}
|
|
||||||
|
|
||||||
div(.class("flex mt-6")) {
|
LabeledInput(
|
||||||
SubmitButton()
|
"Address",
|
||||||
.attributes(.class("btn-block"))
|
.name("streetAddress"),
|
||||||
}
|
.type(.text),
|
||||||
|
.value(project?.streetAddress),
|
||||||
|
.placeholder("Street Address"),
|
||||||
|
.required
|
||||||
|
)
|
||||||
|
|
||||||
|
LabeledInput(
|
||||||
|
"City",
|
||||||
|
.name("city"),
|
||||||
|
.type(.text),
|
||||||
|
.value(project?.city),
|
||||||
|
.placeholder("City"),
|
||||||
|
.required
|
||||||
|
)
|
||||||
|
|
||||||
|
LabeledInput(
|
||||||
|
"State",
|
||||||
|
.name("state"),
|
||||||
|
.type(.text),
|
||||||
|
.value(project?.state),
|
||||||
|
.placeholder("State"),
|
||||||
|
.required
|
||||||
|
)
|
||||||
|
|
||||||
|
LabeledInput(
|
||||||
|
"Zip",
|
||||||
|
.name("zipCode"),
|
||||||
|
.type(.text),
|
||||||
|
.value(project?.zipCode),
|
||||||
|
.placeholder("Zip Code"),
|
||||||
|
.required
|
||||||
|
)
|
||||||
|
|
||||||
|
SubmitButton()
|
||||||
|
.attributes(.class("btn-block my-6"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,37 +57,37 @@ struct UserProfileForm: HTML, Sendable {
|
|||||||
|
|
||||||
label(.class("input w-full")) {
|
label(.class("input w-full")) {
|
||||||
span(.class("label")) { "First Name" }
|
span(.class("label")) { "First Name" }
|
||||||
input(.name("firstName"), .required, .autofocus)
|
input(.name("firstName"), .value(profile?.firstName), .required, .autofocus)
|
||||||
}
|
}
|
||||||
|
|
||||||
label(.class("input w-full")) {
|
label(.class("input w-full")) {
|
||||||
span(.class("label")) { "Last Name" }
|
span(.class("label")) { "Last Name" }
|
||||||
input(.name("lastName"), .required)
|
input(.name("lastName"), .value(profile?.lastName), .required)
|
||||||
}
|
}
|
||||||
|
|
||||||
label(.class("input w-full")) {
|
label(.class("input w-full")) {
|
||||||
span(.class("label")) { "Company" }
|
span(.class("label")) { "Company" }
|
||||||
input(.name("companyName"), .required)
|
input(.name("companyName"), .value(profile?.companyName), .required)
|
||||||
}
|
}
|
||||||
|
|
||||||
label(.class("input w-full")) {
|
label(.class("input w-full")) {
|
||||||
span(.class("label")) { "Address" }
|
span(.class("label")) { "Address" }
|
||||||
input(.name("streetAddress"), .required)
|
input(.name("streetAddress"), .value(profile?.streetAddress), .required)
|
||||||
}
|
}
|
||||||
|
|
||||||
label(.class("input w-full")) {
|
label(.class("input w-full")) {
|
||||||
span(.class("label")) { "City" }
|
span(.class("label")) { "City" }
|
||||||
input(.name("city"), .required)
|
input(.name("city"), .value(profile?.city), .required)
|
||||||
}
|
}
|
||||||
|
|
||||||
label(.class("input w-full")) {
|
label(.class("input w-full")) {
|
||||||
span(.class("label")) { "State" }
|
span(.class("label")) { "State" }
|
||||||
input(.name("state"), .required)
|
input(.name("state"), .value(profile?.state), .required)
|
||||||
}
|
}
|
||||||
|
|
||||||
label(.class("input w-full")) {
|
label(.class("input w-full")) {
|
||||||
span(.class("label")) { "Zip" }
|
span(.class("label")) { "Zip" }
|
||||||
input(.name("zipCode"), .required)
|
input(.name("zipCode"), .value(profile?.zipCode), .required)
|
||||||
}
|
}
|
||||||
|
|
||||||
div(.class("dropdown dropdown-top")) {
|
div(.class("dropdown dropdown-top")) {
|
||||||
|
|||||||
@@ -8,46 +8,50 @@ struct UserView: HTML, Sendable {
|
|||||||
|
|
||||||
var body: some HTML {
|
var body: some HTML {
|
||||||
div {
|
div {
|
||||||
Row {
|
Navbar(sidebarToggle: false, userProfile: false)
|
||||||
h1(.class("text-2xl font-bold")) { "Account" }
|
|
||||||
EditButton()
|
|
||||||
.attributes(.showModal(id: UserProfileForm.id(profile)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if let profile {
|
|
||||||
table(.class("table table-zebra")) {
|
|
||||||
tr {
|
|
||||||
td { Label("Name") }
|
|
||||||
td { "\(profile.firstName) \(profile.lastName)" }
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
td { Label("Company") }
|
|
||||||
td { profile.companyName }
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
td { Label("Street Address") }
|
|
||||||
td { profile.streetAddress }
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
td { Label("City") }
|
|
||||||
td { profile.city }
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
td { Label("State") }
|
|
||||||
td { profile.state }
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
td { Label("Zip Code") }
|
|
||||||
td { profile.zipCode }
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
td { Label("Theme") }
|
|
||||||
td { profile.theme?.rawValue ?? "" }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
div(.class("p-4")) {
|
||||||
|
Row {
|
||||||
|
h1(.class("text-2xl font-bold")) { "Account" }
|
||||||
|
EditButton()
|
||||||
|
.attributes(.showModal(id: UserProfileForm.id(profile)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let profile {
|
||||||
|
table(.class("table table-zebra border rounded-lg")) {
|
||||||
|
tr {
|
||||||
|
td { Label("Name") }
|
||||||
|
td { "\(profile.firstName) \(profile.lastName)" }
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
td { Label("Company") }
|
||||||
|
td { profile.companyName }
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
td { Label("Street Address") }
|
||||||
|
td { profile.streetAddress }
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
td { Label("City") }
|
||||||
|
td { profile.city }
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
td { Label("State") }
|
||||||
|
td { profile.state }
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
td { Label("Zip Code") }
|
||||||
|
td { profile.zipCode }
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
td { Label("Theme") }
|
||||||
|
td { profile.theme?.rawValue ?? "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UserProfileForm(userID: user.id, profile: profile, dismiss: true)
|
||||||
}
|
}
|
||||||
UserProfileForm(userID: user.id, profile: profile, dismiss: true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user