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
This commit is contained in:
s.esmaeili
2026-09-16 01:15:16 +03:30
parent 0e5f9ccd7b
commit e756fbaf85
30 changed files with 890 additions and 365 deletions
+23 -29
View File
@@ -35,6 +35,11 @@
</div>
</header>
<PullRefresh v-model="refreshing" @refresh="onRefresh">
<template #pulling><Loading size="18" /></template>
<template #loosing><Loading size="18" /></template>
<template #loading><Loading size="18" /></template>
<template #success><span /></template>
<container class="home__body">
<RateStrip :quote="goldPrice" class="home__rate" />
@@ -85,11 +90,6 @@
<p>هنوز محصولی در مجموعه ثبت نشده است.</p>
</section>
<section class="home__section">
<SectionHead title="حساب من" subtitle="موجودی و دسترسی‌های شما" />
<AccountStrip :customer="customer" @go="onAccountNav" @login="goLogin" />
</section>
<div class="home__trust">
<div class="home__trustItem">
<Icon icon="vuesax-linear:shield-tick" size="18" />
@@ -105,6 +105,7 @@
</div>
</div>
</container>
</PullRefresh>
<Drawer
v-model:visible="productDrawer"
@@ -123,6 +124,7 @@
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { Drawer } from 'ant-design-vue'
import { Loading, PullRefresh } from 'vant'
import Icon from '../components/icon/Icon.vue'
import SingleProduct from '../components/product/SingleProduct.vue'
import RateStrip from '../components/home/RateStrip.vue'
@@ -131,25 +133,22 @@ import type { ShowcaseSlide } from '../components/home/ShowcaseSlider.vue'
import CategoryRail from '../components/home/CategoryRail.vue'
import ShowcaseCard from '../components/home/ShowcaseCard.vue'
import SectionHead from '../components/home/SectionHead.vue'
import AccountStrip from '../components/home/AccountStrip.vue'
import { useConfigStore } from '../stores/configStore'
import type { HomeCategory } from '../stores/configStore'
import { useCartStore } from '../stores/cartStore'
import { useFiltersStore } from '../stores/filtersStore'
import { useSessionStore } from '../stores/session'
import { api } from '../api/client'
import type { CustomerDetail, GoldPriceQuote, ProductSummary } from '../api/client'
import type { GoldPriceQuote, ProductSummary } from '../api/client'
const router = useRouter()
const memory = useConfigStore()
const cart = useCartStore()
const filters = useFiltersStore()
const session = useSessionStore()
const loading = ref(true)
const refreshing = ref(false)
const products = ref<ProductSummary[]>([])
const goldPrice = ref<GoldPriceQuote | null>(null)
const customer = ref<CustomerDetail | null>(null)
const productDrawer = ref(false)
const activeProductId = ref<string | null>(null)
@@ -203,28 +202,18 @@ function onSlide(slide: ShowcaseSlide) {
router.push({ name: 'search' })
}
function onAccountNav(routeName: string) {
router.push({ name: routeName })
}
function goSearch() {
router.push({ name: 'search' })
}
function goNewest() {
router.push({ name: 'newestProduct' })
}
function goLogin() {
router.push({ name: 'login' })
}
onMounted(async () => {
async function loadData() {
try {
const [list] = await Promise.all([api.listProducts(), memory.init()])
products.value = list
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
try {
@@ -232,14 +221,16 @@ onMounted(async () => {
} catch {
goldPrice.value = null
}
}
if (session.customerId) {
try {
customer.value = await api.getCustomer(session.customerId)
} catch {
customer.value = null
}
}
async function onRefresh() {
await loadData()
refreshing.value = false
}
onMounted(async () => {
await loadData()
loading.value = false
})
</script>
@@ -250,8 +241,10 @@ onMounted(async () => {
}
.home__bar {
position: sticky;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 20;
background: rgba(255, 255, 255, 0.88);
backdrop-filter: blur(14px);
@@ -303,6 +296,7 @@ onMounted(async () => {
}
.home__body {
padding-top: 62px;
padding-bottom: 90px;
}