All files / src/app AppHeader.vue

0% Statements 0/27
0% Branches 0/26
0% Functions 0/12
0% Lines 0/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72                                                                                                                                               
<script setup lang="ts">
import { computed, watch } from "vue";
import { RouterLink } from "vue-router";
import { PjPageContainer } from "@plain-journal/ui";
 
import {
  type AccountCartAccessContext,
  useAccountCartStore,
} from "../entities/account-cart";
import { useBagStore } from "../entities/guest-bag";
import { useSessionStore } from "../features/customer-session";
 
const bag = useBagStore();
const session = useSessionStore();
const accountCart = useAccountCartStore();
const accountAccess = computed<AccountCartAccessContext>(() => ({
  authenticated: session.authenticated,
  ownerId: session.profile?.id ?? null,
  accessToken: session.accessToken,
}));
const visibleBagCount = computed(() => session.authenticated
  ? accountCart.itemCount
  : bag.itemCount);
const bagLabel = computed(() => visibleBagCount.value > 0
  ? `购物袋 ${visibleBagCount.value}`
  : "购物袋");
 
watch(
  () => [
    session.authenticated,
    session.profile?.id ?? null,
    session.accessToken,
    session.bagMergeStatus,
  ] as const,
  async ([authenticated, , , mergeStatus]) => {
    if (!authenticated) {
      await accountCart.load(accountAccess.value);
      return;
    }
    if (!["idle", "succeeded", "unknown", "failed", "ownership-conflict"].includes(mergeStatus)) {
      return;
    }
    try {
      await accountCart.load(accountAccess.value, {
        force: mergeStatus === "succeeded" || mergeStatus === "unknown",
      });
    } catch {
      // The bag page owns the detailed retry state.
    }
  },
  { immediate: true },
);
</script>
 
<template>
  <header class="storefront-header">
    <PjPageContainer class="storefront-header__inner">
      <RouterLink class="brand-link" to="/" aria-label="素简记首页">
        <span>素简记</span>
        <small>Plain Journal</small>
      </RouterLink>
      <nav class="header-actions" aria-label="全局入口">
        <RouterLink to="/search">查找</RouterLink>
        <RouterLink to="/bag">{{ bagLabel }}</RouterLink>
        <RouterLink v-if="session.authenticated" to="/account">账户</RouterLink>
        <RouterLink v-else to="/login">登录</RouterLink>
        <RouterLink to="/index">索引</RouterLink>
      </nav>
    </PjPageContainer>
  </header>
</template>