Files
tehran_taj/apps/user-app/src/components/home/SectionHead.vue
T
s.esmaeiliandClaude Opus 5 f2d83c53df user-app: redesigned home screen and product detail
Design language introduced here and reused across both screens:
  - LESS colour tokens (@ink/@inkSoft/@inkMuted/@inkFaint, @wine/@wineSoft,
    @canvas/@canvasSoft, @hairline/@hairlineSoft) added to
    themeConfig/colors.json and injected globally via vite's modifyVars, so
    scoped <style lang="less"> blocks resolve them with no import
  - BEM-ish scoped class names, hairline-bordered cards at 14-18px radii,
    ink surfaces with a wine accent, dashed-border empty states
  - components/home/: SectionHead, ShowcaseCard, ShowcaseSlider, CategoryRail,
    RateStrip, AccountStrip

Data honesty is deliberate throughout: no rial price is printed for a piece,
because a finished item's price is the live gold rate x weight plus wage,
computed at order time and never stored on the product. Only genuinely
present fields are shown (weight, making-charge percent, stock, category,
brand). Categories and the hero are derived from the real catalogue, so an
empty catalogue renders an empty state rather than placeholder tiles.

Also fixes a real bug in the product detail view: it ran, at module scope,
history.pushState + window.onpopstate = () => history.go(1). Because the
drawer mounts its slot eagerly, that fired for every product card on the
home screen and permanently hijacked the back button for the session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 23:05:29 +03:30

60 lines
1.2 KiB
Vue

<!-- Section heading with an optional "see all" affordance. -->
<template>
<header class="sec">
<div class="sec__text">
<h2 class="sec__title">{{ title }}</h2>
<p v-if="subtitle" class="sec__sub">{{ subtitle }}</p>
</div>
<button v-if="actionLabel" type="button" class="sec__action" @click="emit('action')">
{{ actionLabel }}
<Icon icon="vuesax-linear:arrow-left-2" size="15" />
</button>
</header>
</template>
<script setup lang="ts">
import Icon from '../icon/Icon.vue'
defineProps<{ title: string; subtitle?: string; actionLabel?: string }>()
const emit = defineEmits<{ (e: 'action'): void }>()
</script>
<style scoped lang="less">
.sec {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 12px;
padding-bottom: 13px;
}
.sec__title {
margin: 0;
font-size: 15px;
font-weight: 800;
color: @ink;
letter-spacing: -0.1px;
}
.sec__sub {
margin: 5px 0 0;
font-size: 11.5px;
color: @inkFaint;
}
.sec__action {
display: inline-flex;
align-items: center;
gap: 4px;
border: 0;
background: none;
cursor: pointer;
padding: 0;
font-family: inherit;
font-size: 11.5px;
font-weight: 700;
color: @wine;
white-space: nowrap;
}
</style>