Files
tehran_taj/apps/user-app/src/views/user/FavoritesView.vue
T
s.esmaeili e756fbaf85 Redesign orders/cart/search flows and fix RTL/auth edge cases in user-app
- Fix silent redirect-to-home for unauthenticated users on protected routes;
  now redirects to login with a return path
- Restyle OrderCard, SearchInput, Filters, DropDown, and product card image
  sizing/centering to match the app's LESS-token design language
- Fix ant-design Slider handle placement/drag under RTL and seed a valid
  default range so handles actually render
- Fix chip-row edge padding and top spacing across Orders/Cart/Search lists
- Add pull-to-refresh to the dashboard and fix its header/padding to match
  the fixed PageBar pattern
- Remove the floating WhatsApp button from index.html
2026-09-16 01:15:16 +03:30

111 lines
3.1 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
Ported from legacy henza_pwa/src/views/user/src/components/favorits.vue,
restyled into the redesigned design language (see components/home/* and
HomeView).
Real, not stubbed: favorites are the local favoritesStore (per-device, no
backend persistence — see favoritesStore.ts from an earlier batch), filtered
against the real product catalog client-side. No pagination — the whole
catalog is fetched once (same "small catalog" approach as everywhere else).
That logic is carried over unchanged; only the chrome and the card change.
-->
<template>
<div class="favs">
<PageBar title="علاقه‌مندی" back-to="userPage::hasSubRoute" />
<Spinner :spinning="loading" tip="در حال دریافت اطلاعات">
<container class="favs__body">
<template v-if="favoriteProducts.length">
<SectionHead title="ذخیره‌شده‌ها" :subtitle="`${favoriteProducts.length} محصول`" />
<div class="favs__grid">
<ProductCard v-for="item in favoriteProducts" :key="item.id" :value="item" />
</div>
</template>
<section v-else-if="!loading" class="favs__empty">
<Icon icon="vuesax-linear:heart" size="26" />
<p>هنوز محصولی را به علاقه‌مندی‌ها اضافه نکرده‌اید.</p>
<button type="button" class="favs__emptyCta" @click="router.push({ name: 'home' })">
دیدن محصولات
</button>
</section>
</container>
</Spinner>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import Icon from '../../components/icon/Icon.vue'
import PageBar from '../../components/ui/PageBar.vue'
import Spinner from '../../components/Spinner.vue'
import SectionHead from '../../components/home/SectionHead.vue'
import ProductCard from '../../components/product/ProductCard.vue'
import { useFavoritesStore } from '../../stores/favoritesStore'
import { api, type ProductSummary } from '../../api/client'
const router = useRouter()
const favorites = useFavoritesStore()
const loading = ref(false)
const allProducts = ref<ProductSummary[]>([])
const favoriteProducts = computed(() => allProducts.value.filter((p) => favorites.isFavorite(p.id)))
onMounted(async () => {
loading.value = true
try {
allProducts.value = await api.listProducts()
} finally {
loading.value = false
}
})
</script>
<style scoped lang="less">
.favs {
background: @canvas;
min-height: 100vh;
}
.favs__body {
padding-top: 76px;
padding-bottom: 90px;
}
.favs__grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 11px;
}
.favs__empty {
margin-top: 8px;
padding: 38px 20px;
border: 1px dashed @hairline;
border-radius: 18px;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
color: @inkFaint;
}
.favs__empty p {
margin: 0;
font-size: 12.5px;
}
.favs__emptyCta {
margin-top: 4px;
padding: 9px 18px;
border: 0;
cursor: pointer;
border-radius: 999px;
font-family: inherit;
font-size: 12.5px;
font-weight: 700;
color: #fff;
background: @ink;
}
</style>