wire CartDrawer + cart events into LoginPage and RegisterPage

Both pages were rendering the Navbar with cart-count but not
listening for the @cart event or rendering the drawer, so tapping
the cart icon did nothing. Hooked up cartOpen ref, search-add,
qty/remove handlers, goCheckout, and the CartDrawer template — same
pattern as HomePage / ShopPage / CategoryPage / LegalPage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-05-03 19:12:36 +01:00
parent 4ed021280a
commit efbc93d3b8
8 changed files with 78 additions and 7 deletions

View File

@@ -1 +0,0 @@
import{B as e,C as t,G as n,S as r,c as i,ft as a,j as o,l as s,m as c,o as l,p as u,r as d,s as f,u as p,x as m}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{c as h}from"./runtime-dom.esm-bundler-Bg1uJ-W7.js";import{a as g,o as _,t as v}from"./vue-router-Cyqru1db.js";import{t as ee}from"./i18n-Bn6is6OA.js";import{r as y}from"./products-BqW5PUnm.js";import{i as b,p as x,r as S}from"./api-DlB23x7f.js";import{t as C}from"./Navbar-CaHu1JH-.js";import{t as w}from"./Button-D1Rp2Xe1.js";import{t as T}from"./Footer-Bd-isFPT.js";import{t as E}from"./Input-os2-AnNh.js";var D={class:`bg-cream text-ink min-h-svh`},O={class:`mx-auto w-full max-w-md px-6 py-14 sm:px-8 sm:py-20 md:py-24`},k={class:`flex flex-col gap-3 mb-8 text-center`},A={class:`eyebrow`},j={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},M={class:`text-[14px] text-muted`},N={key:1,class:`text-sm text-danger`,role:`alert`,"aria-live":`polite`},P={key:1,class:`rounded-md border border-line bg-paper p-6 md:p-8 flex flex-col gap-3 text-center`},F={class:`font-display text-xl text-brand`},I={class:`text-[14px] text-muted`},L={class:`mt-8 text-center text-[14px] text-muted`},te={__name:`LoginPage`,setup(te){let{t:R}=ee(),z=x(),B=g(),V=_(),H=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],U=e(``),W=e(``),G=e(!1),K=e(``),q=e(!1),J=e(!1),Y=l(()=>U.value?q.value?!1:W.value.length<8:!0);async function X(){K.value=``,G.value=!0;try{if(q.value){await S({email:U.value}),J.value=!0;return}await b({email:U.value,password:W.value});let e=String(B.query.next||`/`);V.push(e)}catch(e){K.value=e?.message||R(`checkout.error.generic`)}finally{G.value=!1}}let Z=e(null),Q=null;function $(){let e=Z.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return r(()=>{if($(),typeof ResizeObserver<`u`&&Z.value){let e=Z.value.$el||Z.value;Q=new ResizeObserver($),Q.observe(e)}window.addEventListener(`resize`,$)}),m(()=>{Q&&Q.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,$)}),(e,r)=>(t(),p(d,null,[c(C,{ref_key:`navRef`,ref:Z,variant:`cream`,layout:`standard`,items:H,"cart-count":n(z).count,products:n(y)},null,8,[`cart-count`,`products`]),f(`main`,D,[f(`div`,O,[f(`header`,k,[f(`p`,A,a(n(R)(`auth.login.eyebrow`)),1),f(`h1`,j,a(q.value?n(R)(`auth.reset.title`):n(R)(`auth.login.title`)),1),f(`p`,M,a(q.value?n(R)(`auth.reset.sub`):n(R)(`auth.login.sub`)),1)]),J.value?(t(),p(`div`,P,[f(`h2`,F,a(n(R)(`auth.reset.sent.title`)),1),f(`p`,I,a(n(R)(`auth.reset.sent.body`)),1),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-center mt-2`,onClick:r[3]||=e=>{q.value=!1,J.value=!1}},a(n(R)(`auth.reset.back`)),1)])):(t(),p(`form`,{key:0,class:`flex flex-col gap-5 rounded-md border border-line bg-paper p-6 md:p-8`,novalidate:``,onSubmit:h(X,[`prevent`])},[c(E,{modelValue:U.value,"onUpdate:modelValue":r[0]||=e=>U.value=e,label:n(R)(`checkout.field.email`),type:`email`,required:``,placeholder:n(R)(`checkout.placeholder.email`)},null,8,[`modelValue`,`label`,`placeholder`]),q.value?s(``,!0):(t(),i(E,{key:0,modelValue:W.value,"onUpdate:modelValue":r[1]||=e=>W.value=e,label:n(R)(`checkout.field.password`),type:`password`,required:``},null,8,[`modelValue`,`label`])),K.value?(t(),p(`p`,N,a(K.value),1)):s(``,!0),c(w,{type:`submit`,variant:`primary`,size:`lg`,block:``,loading:G.value,disabled:Y.value},{default:o(()=>[u(a(q.value?n(R)(`auth.reset.cta`):n(R)(`auth.login.cta`)),1)]),_:1},8,[`loading`,`disabled`]),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-start`,onClick:r[2]||=e=>q.value=!q.value},a(q.value?n(R)(`auth.reset.back`):n(R)(`auth.login.forgot`)),1)],32)),f(`p`,L,[u(a(n(R)(`auth.login.newCustomer`))+` `,1),c(n(v),{to:`/register`,class:`text-brand hover:underline`},{default:o(()=>[u(a(n(R)(`auth.login.cta.register`)),1)]),_:1})])])]),c(T)],64))}};export{te as default};

1
dist/assets/LoginPage-XNkFwUDv.js vendored Normal file
View File

@@ -0,0 +1 @@
import{B as e,C as t,G as n,S as r,c as i,ft as a,j as o,l as s,m as c,o as l,p as u,r as d,s as f,u as p,x as ee}from"./runtime-core.esm-bundler-DTXUv7Wx.js";import{c as te}from"./runtime-dom.esm-bundler-Bg1uJ-W7.js";import{a as ne,o as re,t as ie}from"./vue-router-Cyqru1db.js";import{t as ae}from"./i18n-Bn6is6OA.js";import{r as oe}from"./products-BqW5PUnm.js";import{c as se,d as ce,f as m,i as h,p as g,r as _}from"./api-DlB23x7f.js";import{t as v}from"./Navbar-CaHu1JH-.js";import{t as y}from"./Button-D1Rp2Xe1.js";import{t as b}from"./Footer-Bd-isFPT.js";import{t as x}from"./CartDrawer-BLXnzE6x.js";import{t as S}from"./Input-os2-AnNh.js";var C={class:`bg-cream text-ink min-h-svh`},w={class:`mx-auto w-full max-w-md px-6 py-14 sm:px-8 sm:py-20 md:py-24`},T={class:`flex flex-col gap-3 mb-8 text-center`},E={class:`eyebrow`},D={class:`font-display font-normal leading-[1.05] tracking-tight text-ink text-headline-md`},O={class:`text-[14px] text-muted`},k={key:1,class:`text-sm text-danger`,role:`alert`,"aria-live":`polite`},A={key:1,class:`rounded-md border border-line bg-paper p-6 md:p-8 flex flex-col gap-3 text-center`},j={class:`font-display text-xl text-brand`},M={class:`text-[14px] text-muted`},N={class:`mt-8 text-center text-[14px] text-muted`},P={__name:`LoginPage`,setup(P){let{t:F}=ae(),I=g(),L=ne(),R=re(),z=e(!1);function B(){z.value=!1,R.push(`/checkout`)}async function V(e){await se(e.id,1),z.value=!0}async function H({productId:e,quantity:t}){await m(e,t)}async function U(e){await ce(e)}let W=[{key:`nav.shop`,href:`/shop`},{key:`nav.bundles`,href:`/#bundles`},{key:`nav.revitalization`,href:`/#revitalize`},{key:`nav.about`,href:`/#about`}],G=e(``),K=e(``),q=e(!1),J=e(``),Y=e(!1),X=e(!1),le=l(()=>G.value?Y.value?!1:K.value.length<8:!0);async function ue(){J.value=``,q.value=!0;try{if(Y.value){await _({email:G.value}),X.value=!0;return}await h({email:G.value,password:K.value});let e=String(L.query.next||`/`);R.push(e)}catch(e){J.value=e?.message||F(`checkout.error.generic`)}finally{q.value=!1}}let Z=e(null),Q=null;function $(){let e=Z.value,t=e&&(e.$el||e);if(!t||typeof window>`u`)return;let n=Math.round(t.getBoundingClientRect().height);document.documentElement.style.setProperty(`--nav-h`,`${n}px`)}return r(()=>{if($(),typeof ResizeObserver<`u`&&Z.value){let e=Z.value.$el||Z.value;Q=new ResizeObserver($),Q.observe(e)}window.addEventListener(`resize`,$)}),ee(()=>{Q&&Q.disconnect(),typeof window<`u`&&window.removeEventListener(`resize`,$)}),(e,r)=>(t(),p(d,null,[c(v,{ref_key:`navRef`,ref:Z,variant:`cream`,layout:`standard`,items:W,"cart-count":n(I).count,products:n(oe),onCart:r[0]||=e=>z.value=!0,onSearch:V},null,8,[`cart-count`,`products`]),f(`main`,C,[f(`div`,w,[f(`header`,T,[f(`p`,E,a(n(F)(`auth.login.eyebrow`)),1),f(`h1`,D,a(Y.value?n(F)(`auth.reset.title`):n(F)(`auth.login.title`)),1),f(`p`,O,a(Y.value?n(F)(`auth.reset.sub`):n(F)(`auth.login.sub`)),1)]),X.value?(t(),p(`div`,A,[f(`h2`,j,a(n(F)(`auth.reset.sent.title`)),1),f(`p`,M,a(n(F)(`auth.reset.sent.body`)),1),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-center mt-2`,onClick:r[4]||=e=>{Y.value=!1,X.value=!1}},a(n(F)(`auth.reset.back`)),1)])):(t(),p(`form`,{key:0,class:`flex flex-col gap-5 rounded-md border border-line bg-paper p-6 md:p-8`,novalidate:``,onSubmit:te(ue,[`prevent`])},[c(S,{modelValue:G.value,"onUpdate:modelValue":r[1]||=e=>G.value=e,label:n(F)(`checkout.field.email`),type:`email`,required:``,placeholder:n(F)(`checkout.placeholder.email`)},null,8,[`modelValue`,`label`,`placeholder`]),Y.value?s(``,!0):(t(),i(S,{key:0,modelValue:K.value,"onUpdate:modelValue":r[2]||=e=>K.value=e,label:n(F)(`checkout.field.password`),type:`password`,required:``},null,8,[`modelValue`,`label`])),J.value?(t(),p(`p`,k,a(J.value),1)):s(``,!0),c(y,{type:`submit`,variant:`primary`,size:`lg`,block:``,loading:q.value,disabled:le.value},{default:o(()=>[u(a(Y.value?n(F)(`auth.reset.cta`):n(F)(`auth.login.cta`)),1)]),_:1},8,[`loading`,`disabled`]),f(`button`,{type:`button`,class:`text-[13px] text-brand hover:underline self-start`,onClick:r[3]||=e=>Y.value=!Y.value},a(Y.value?n(F)(`auth.reset.back`):n(F)(`auth.login.forgot`)),1)],32)),f(`p`,N,[u(a(n(F)(`auth.login.newCustomer`))+` `,1),c(n(ie),{to:`/register`,class:`text-brand hover:underline`},{default:o(()=>[u(a(n(F)(`auth.login.cta.register`)),1)]),_:1})])])]),c(b),c(x,{modelValue:z.value,"onUpdate:modelValue":r[5]||=e=>z.value=e,items:n(I).items,subtotal:n(I).subtotal,count:n(I).count,onUpdateQuantity:H,onRemove:U,onCheckout:B},null,8,[`modelValue`,`items`,`subtotal`,`count`])],64))}};export{P as default};

1
dist/assets/RegisterPage-UShFM_fH.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/index.html vendored
View File

@@ -12,7 +12,7 @@
href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,200;0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,200;1,9..144,400;1,9..144,600&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&display=swap"
rel="stylesheet"
/>
<script type="module" crossorigin src="/assets/index-DSgweLra.js"></script>
<script type="module" crossorigin src="/assets/index-DoLqdbBe.js"></script>
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BOai-rQB.js">
<link rel="modulepreload" crossorigin href="/assets/preload-helper-DzyYoeor.js">
<link rel="modulepreload" crossorigin href="/assets/runtime-core.esm-bundler-DTXUv7Wx.js">

View File

@@ -11,7 +11,15 @@ import Navbar from '@/design-system/components/Navbar.vue'
import Footer from '@/design-system/components/Footer.vue'
import Input from '@/design-system/components/Input.vue'
import Button from '@/design-system/components/Button.vue'
import { products, signIn, requestPasswordReset } from '@/api/index.js'
import CartDrawer from '@/design-system/components/CartDrawer.vue'
import {
products,
signIn,
requestPasswordReset,
addToCart,
updateCartItem,
removeFromCart,
} from '@/api/index.js'
import { useCartStore } from '@/stores/cart.js'
import { useI18n } from '@/i18n/index.js'
@@ -19,6 +27,22 @@ const { t } = useI18n()
const cart = useCartStore()
const route = useRoute()
const router = useRouter()
const cartOpen = ref(false)
function goCheckout() {
cartOpen.value = false
router.push('/checkout')
}
async function onSearchSelect(product) {
await addToCart(product.id, 1)
cartOpen.value = true
}
async function onQty({ productId, quantity }) {
await updateCartItem(productId, quantity)
}
async function onRemove(productId) {
await removeFromCart(productId)
}
const navItems = [
{ key: 'nav.shop', href: '/shop' },
@@ -92,6 +116,8 @@ onBeforeUnmount(() => {
:items="navItems"
:cart-count="cart.count"
:products="products"
@cart="cartOpen = true"
@search="onSearchSelect"
/>
<main class="bg-cream text-ink min-h-svh">
@@ -179,4 +205,14 @@ onBeforeUnmount(() => {
</main>
<Footer />
<CartDrawer
v-model="cartOpen"
:items="cart.items"
:subtotal="cart.subtotal"
:count="cart.count"
@update-quantity="onQty"
@remove="onRemove"
@checkout="goCheckout"
/>
</template>

View File

@@ -12,7 +12,14 @@ import Footer from '@/design-system/components/Footer.vue'
import Input from '@/design-system/components/Input.vue'
import Button from '@/design-system/components/Button.vue'
import Icon from '@/design-system/components/Icon.vue'
import { products, register } from '@/api/index.js'
import CartDrawer from '@/design-system/components/CartDrawer.vue'
import {
products,
register,
addToCart,
updateCartItem,
removeFromCart,
} from '@/api/index.js'
import { useCartStore } from '@/stores/cart.js'
import { useI18n } from '@/i18n/index.js'
@@ -20,6 +27,22 @@ const { t } = useI18n()
const cart = useCartStore()
const route = useRoute()
const router = useRouter()
const cartOpen = ref(false)
function goCheckout() {
cartOpen.value = false
router.push('/checkout')
}
async function onSearchSelect(product) {
await addToCart(product.id, 1)
cartOpen.value = true
}
async function onQty({ productId, quantity }) {
await updateCartItem(productId, quantity)
}
async function onRemove(productId) {
await removeFromCart(productId)
}
const navItems = [
{ key: 'nav.shop', href: '/shop' },
@@ -103,6 +126,8 @@ onBeforeUnmount(() => {
:items="navItems"
:cart-count="cart.count"
:products="products"
@cart="cartOpen = true"
@search="onSearchSelect"
/>
<main class="bg-cream text-ink min-h-svh">
@@ -229,4 +254,14 @@ onBeforeUnmount(() => {
</main>
<Footer />
<CartDrawer
v-model="cartOpen"
:items="cart.items"
:subtotal="cart.subtotal"
:count="cart.count"
@update-quantity="onQty"
@remove="onRemove"
@checkout="goCheckout"
/>
</template>