Add guest/account auth flows, order tracking, and order history UI
- Wire up Better Auth (email/password + Google/Apple SSO) with a sign-in/sign-up UI, header account menu, and a basket that follows the signed-in-or-guest state. - Give the order status page a vertical timeline per preparation step (with a distinct customer-facing name separate from the machine tag, a done/in-progress/queued/pending look, and a sonar-ping highlight on the active step), a formatted ETA (relative under 3h, absolute clock time beyond that), and Buy again / Get help / Cancel actions. - Expand Pizza's recipe into 6 steps across a shared prep station and the existing oven/assembly stations, with matching schema, seed, and domain changes plus updated/added test coverage. - Add an Orders list (account orders via session, guest orders via a locally remembered access-token list) with a shared getOrdersForCustomer domain summary, and remember a guest's name/contact after their first order so checkout doesn't ask again. - Improve page transitions with the View Transitions API: a shared element morph between an order card and its detail page, a stable (non-jumping) header across navigations, and reduced-motion handling. - Add a Ghost Kitchen wordmark (Space Grotesk, faded "Ghost", ghost icon standing in for the "o") and shrink the basket icon to match the rest of the header controls. - Add a run-ghost-kitchen agent skill documenting local setup, the dev-server driver, and the gotchas hit along the way. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,31 @@
|
||||
padding: $space-5 $space-3;
|
||||
}
|
||||
|
||||
.backLink {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: $space-1;
|
||||
margin: 0 0 $space-3;
|
||||
color: $color-text-muted;
|
||||
font-size: 0.85rem;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: $color-primary;
|
||||
|
||||
.backArrow {
|
||||
transform: translateX(-3px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.backArrow {
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
flex-shrink: 0;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.heading {
|
||||
margin: 0 0 $space-1;
|
||||
}
|
||||
@@ -48,22 +73,117 @@
|
||||
color: $color-text-muted;
|
||||
}
|
||||
|
||||
.steps {
|
||||
.timeline {
|
||||
margin: 0 0 $space-2;
|
||||
padding-left: $space-4;
|
||||
font-size: 0.85rem;
|
||||
color: $color-text-muted;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.step {
|
||||
&[data-status='done'] {
|
||||
text-decoration: line-through;
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: $space-3 1fr;
|
||||
column-gap: $space-2;
|
||||
padding-bottom: $space-3;
|
||||
font-size: 0.85rem;
|
||||
color: $color-text-muted;
|
||||
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.stepMarker {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.stepDot {
|
||||
position: relative;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: 3px;
|
||||
border: 2px solid $color-border;
|
||||
border-radius: 50%;
|
||||
background: $color-background;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.stepMarker::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: -$space-3;
|
||||
left: 50%;
|
||||
width: 2px;
|
||||
background: $color-border;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.step:last-child .stepMarker::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.stepContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $space-1;
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
.stepMeta {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.step[data-status='done'] {
|
||||
.stepDot {
|
||||
border-color: $color-primary;
|
||||
background: $color-primary;
|
||||
}
|
||||
|
||||
&[data-status='in_progress'] {
|
||||
color: $color-primary;
|
||||
font-weight: 600;
|
||||
.stepMarker::after {
|
||||
background: $color-primary;
|
||||
}
|
||||
|
||||
.stepLabel {
|
||||
color: $color-text;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
||||
.step[data-status='in_progress'] {
|
||||
.stepDot {
|
||||
border-color: $color-success;
|
||||
background: $color-success;
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 50%;
|
||||
background: $color-success;
|
||||
animation: sonarPing 1.6s ease-out infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sonarPing {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(2.8);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.step[data-status='pending'] {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.eta {
|
||||
@@ -75,12 +195,16 @@
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: $space-2;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
button,
|
||||
a {
|
||||
padding: $space-1 $space-3;
|
||||
border: 1px solid $color-border;
|
||||
border-radius: $radius;
|
||||
background: $color-background;
|
||||
color: $color-text;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:disabled {
|
||||
@@ -88,4 +212,17 @@
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.cancelButton {
|
||||
padding: $space-1 $space-2;
|
||||
border: none;
|
||||
background: none;
|
||||
color: $color-text-muted;
|
||||
font-size: 0.85rem;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
color: $color-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user