Files
ccn/Services/Website/Sources/Library/Internal/Pages/WelcomePage.swift
T

151 lines
4.8 KiB
Swift
Raw Normal View History

import Elementary
import Foundation
import Infrastructure
/// The first sign-in: shown once, to a new account, for the one thing sign-up never asked — a display name. Drawn bare, like the sign-in.
struct WelcomePage {
// MARK: Properties
let analytics: Analytics?
let assetVersion: String?
let locale: Locale
/// The name the field is filled with.
let displayName: String
/// What is wrong with the name, or `nil` when nothing is.
let problem: String?
/// The path the visitor continues to.
let returnPath: String
// MARK: Initializers
/// Creates the first-sign-in screen.
/// - Parameters:
/// - displayName: the name the field is filled with.
/// - returnPath: the path the visitor continues to.
/// - problem: what is wrong with the name, or `nil` (the default) when nothing is.
/// - assetVersion: the version token appended to the page's asset URLs, or `nil` (the default) to leave them unversioned.
/// - analytics: the analytics tracker embedded in the document head, or `nil` (the default) to omit it.
init(
displayName: String,
returnPath: String,
problem: String? = nil,
assetVersion: String? = nil,
analytics: Analytics? = nil
) {
self.analytics = analytics
self.assetVersion = assetVersion
self.displayName = displayName
self.locale = .init(identifier: "en")
self.problem = problem
self.returnPath = returnPath
}
}
// MARK: - Page
extension WelcomePage: Page {
// MARK: Computed
var content: some HTML {
div(.class("gate")) {
header(.class("gate__bar")) {
span(.class("gate__wordmark")) {
"CCN"
}
}
main(.class("gate__main")) {
div(.class("gate__intro")) {
p(.class("type-eyebrow")) {
"Shown once, on first sign-in"
}
h1(.class("type-h1")) {
"You're in."
}
p(.class("gate__lead")) {
"One thing before sellers and buyers see you."
}
}
form(
.class("gate__form"),
.action(.Route.welcome),
.method(.post)
) {
input(
.type(.hidden),
.name("return"),
.value(returnPath)
)
div(.class("field")) {
label(
.class("field__label"),
.for("name")
) {
"Display name"
}
input(
.class("input input--lg"),
.id("name"),
.type(.text),
.name("name"),
.value(displayName),
.required,
.placeholder("How sellers and buyers will see you"),
.custom(name: "autocomplete", value: "nickname"),
.custom(name: "maxlength", value: "40")
)
FieldNote(
name: "name",
hint: "You can open a shop later from your account — no need to decide now.",
problem: problem
)
}
div(.class("gate__nudge")) {
Icon(.key, size: 20)
div {
p(.class("gate__nudge-title")) {
"Keep a second way in"
}
p {
"A passkey lives on the device that made it. Add a backup from another device on your account page, so a lost phone doesn't lock you out of open orders."
}
}
}
button(
.class("button button--primary button--xl button--block"),
.type(.submit)
) {
"Continue"
}
}
}
}
}
@HTMLBuilder
var metadata: some HTML {
meta(
.name("robots"),
.content("noindex")
)
siteMetadata
}
var scripts: [any Asset] {
[StaticFile.shared]
}
var stylesheets: [any Asset] {
[StaticFile.shared, StaticFile.signIn]
}
var title: String {
"Welcome — CCN"
}
}