Implemented phase 3 for the POC prototype in the Website service.
This commit is contained in:
1 parent
b1ceed7790
commit
0dc3fe6bea
29 files changed
+4089
-66
No files matched your search
@@ -0,0 +1,75 @@
|
||||
import Elementary
|
||||
import Persistence
|
||||
|
||||
/// The seller's answer to an open offer: accept or decline, each a form.
|
||||
struct AnswerOffer: HTML {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The offer answered.
|
||||
let offer: Offer
|
||||
|
||||
/// The path to return to afterwards; accepting leads to the sale record instead.
|
||||
let returnPath: String
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
var body: some HTML {
|
||||
form(
|
||||
.class("answer"),
|
||||
.action(.Route.answer(offer: offer.id)),
|
||||
.method(.post)
|
||||
) {
|
||||
input(
|
||||
.type(.hidden),
|
||||
.name("return"),
|
||||
.value(returnPath)
|
||||
)
|
||||
button(
|
||||
.class("button button--primary button--sm"),
|
||||
.type(.submit),
|
||||
.name("answer"),
|
||||
.custom(name: "value", value: "accept")
|
||||
) {
|
||||
"Accept"
|
||||
}
|
||||
button(
|
||||
.class("button button--sm"),
|
||||
.type(.submit),
|
||||
.name("answer"),
|
||||
.custom(name: "value", value: "decline")
|
||||
) {
|
||||
"Decline"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
||||
extension Offer.Status {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
/// The status in a word.
|
||||
var label: String {
|
||||
switch self {
|
||||
case .open: "Open"
|
||||
case .accepted: "Accepted"
|
||||
case .declined: "Declined"
|
||||
case .expired: "Expired"
|
||||
}
|
||||
}
|
||||
|
||||
/// The chip colouring for the status.
|
||||
var tone: Chip.Tone {
|
||||
switch self {
|
||||
case .open: .warn
|
||||
case .accepted: .good
|
||||
case .declined: .bad
|
||||
case .expired: .neutral
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import Elementary
|
||||
import Persistence
|
||||
|
||||
/// The five steps of a sale's handshake, as dots: done, current, or still to come.
|
||||
struct Handshake: HTML {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The last step taken.
|
||||
let completed: Sale.Step
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
var body: some HTML {
|
||||
ol(
|
||||
.class("handshake"),
|
||||
.custom(name: "aria-label", value: "Handshake: \(completed.label) done")
|
||||
) {
|
||||
for step in Sale.Step.allCases {
|
||||
li(.class(step <= completed ? "handshake__step handshake__step--done" : "handshake__step")) {
|
||||
step.label
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
||||
extension Sale.Step {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
/// The step's name.
|
||||
var label: String {
|
||||
switch self {
|
||||
case .agreed: "Agreed"
|
||||
case .paid: "Paid"
|
||||
case .sent: "Sent"
|
||||
case .received: "Received"
|
||||
case .rated: "Rated"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Sale {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
/// The record's number as shown, e.g. `CCN-48213`.
|
||||
var reference: String {
|
||||
"CCN-\(number)"
|
||||
}
|
||||
|
||||
/// Where the sale stands, in a few words, and whether that is done.
|
||||
var status: (label: String, tone: Chip.Tone) {
|
||||
switch next {
|
||||
case .paid: ("Awaiting payment", .warn)
|
||||
case .sent: ("Awaiting dispatch", .warn)
|
||||
case .received: ("On its way", .warn)
|
||||
case .rated: ("Awaiting ratings", .neutral)
|
||||
default: ("Complete", .good)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,6 +62,8 @@ extension Icon {
|
||||
case document
|
||||
/// Filter lines.
|
||||
case filter
|
||||
/// A circled "i".
|
||||
case info
|
||||
/// A key.
|
||||
case key
|
||||
/// A padlock.
|
||||
@@ -90,6 +92,7 @@ extension Icon.Glyph {
|
||||
case .close: #"<path d="M6 6l12 12M18 6 6 18"></path>"#
|
||||
case .document: #"<rect x="5" y="3" width="14" height="18" rx="1"></rect><path d="M9 8h6M9 12h6M9 16h3"></path>"#
|
||||
case .filter: #"<path d="M4 6h16M7 12h10M10 18h4"></path>"#
|
||||
case .info: #"<circle cx="12" cy="12" r="9"></circle><path d="M12 8v5M12 16h.01"></path>"#
|
||||
case .key: #"<circle cx="7.5" cy="15.5" r="4.5"></circle><path d="M10.7 12.3 21 2"></path><path d="m18 5 3 3"></path><path d="m15 8 3 3"></path>"#
|
||||
case .lock: #"<rect x="5" y="11" width="14" height="10" rx="1"></rect><path d="M8 11V7a4 4 0 0 1 8 0v4"></path>"#
|
||||
case .message: #"<path d="M4 5h16v11H8l-4 4z"></path>"#
|
||||
|
||||
@@ -203,11 +203,13 @@ private extension SiteHeader {
|
||||
unit: "unread",
|
||||
path: .Route.messages
|
||||
)
|
||||
a(
|
||||
.class("site-header__text-link site-header__text-link--strong from-desktop"),
|
||||
.href(.Route.sellerDashboard)
|
||||
) {
|
||||
"My shop"
|
||||
if viewer.hasShop {
|
||||
a(
|
||||
.class("site-header__text-link site-header__text-link--strong from-tablet"),
|
||||
.href(.Route.sellerDashboard)
|
||||
) {
|
||||
"My shop"
|
||||
}
|
||||
}
|
||||
a(
|
||||
.class("site-header__account"),
|
||||
|
||||
Reference in new issue
Block a user