feat: catalog read cache (api + user apps) and clearer Zarrin accounting errors
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -133,22 +133,26 @@ import type { HomeCategory } from '../stores/configStore'
|
||||
import { useCartStore } from '../stores/cartStore'
|
||||
import { useFiltersStore } from '../stores/filtersStore'
|
||||
import { useReveal } from '../composables/useReveal'
|
||||
import { api } from '../api/client'
|
||||
import type { AdminSlide, GoldPriceQuote, ProductSummary } from '../api/client'
|
||||
import { useCachedReads } from '../api/cachedReads'
|
||||
import { useCatalogStore } from '../stores/catalogStore'
|
||||
import { KEYS } from '../stores/queryCache'
|
||||
|
||||
const router = useRouter()
|
||||
const memory = useConfigStore()
|
||||
const cart = useCartStore()
|
||||
const filters = useFiltersStore()
|
||||
const catalog = useCatalogStore()
|
||||
const reads = useCachedReads()
|
||||
|
||||
const loading = ref(true)
|
||||
const loading = ref(!catalog.loaded)
|
||||
const refreshing = ref(false)
|
||||
const products = ref<ProductSummary[]>([])
|
||||
const goldPrice = ref<GoldPriceQuote | null>(null)
|
||||
const products = computed(() => catalog.products)
|
||||
const goldPrice = ref<GoldPriceQuote | null>(reads.peek<GoldPriceQuote>(KEYS.goldPrice) ?? null)
|
||||
// Admin-managed banner slides (manage/Const.vue "اسلایدر موبایل"). null while
|
||||
// unfetched/unavailable — distinct from "fetched, empty" — so `slides` below
|
||||
// knows whether to wait or fall back to the category-derived hero.
|
||||
const adminSlides = ref<AdminSlide[] | null>(null)
|
||||
const adminSlides = ref<AdminSlide[] | null>(reads.peek<AdminSlide[]>(KEYS.homeSlider) ?? null)
|
||||
|
||||
|
||||
// First-paint entrance: played once, after the first data load, so the
|
||||
@@ -240,31 +244,25 @@ function goSearch() {
|
||||
function goNewest() {
|
||||
router.push({ name: 'newestProduct' })
|
||||
}
|
||||
async function loadData() {
|
||||
try {
|
||||
const [list] = await Promise.all([api.listProducts(), memory.init()])
|
||||
products.value = list
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
// The three reads are independent, so they run side by side. Each one is
|
||||
// cached until pull-to-refresh asks the server again.
|
||||
async function loadData(force = false) {
|
||||
const [catalogResult, priceResult, slidesResult] = await Promise.allSettled([
|
||||
// memory.init() reads the same cached catalogue, so this is one request.
|
||||
memory.init(force),
|
||||
reads.goldPrice({ force }),
|
||||
reads.homeSlider({ force }),
|
||||
])
|
||||
|
||||
try {
|
||||
goldPrice.value = await api.getLatestGoldPrice()
|
||||
} catch {
|
||||
goldPrice.value = null
|
||||
}
|
||||
|
||||
try {
|
||||
adminSlides.value = await api.getHomeSlider()
|
||||
} catch {
|
||||
// No admin slides configured, or the endpoint failed — the category-
|
||||
// derived hero below covers this silently, same as before this existed.
|
||||
adminSlides.value = null
|
||||
}
|
||||
if (catalogResult.status === 'rejected') console.log(catalogResult.reason)
|
||||
goldPrice.value = priceResult.status === 'fulfilled' ? priceResult.value : null
|
||||
// No admin slides configured, or the endpoint failed — the category-derived
|
||||
// hero below covers this silently, same as before this existed.
|
||||
adminSlides.value = slidesResult.status === 'fulfilled' ? slidesResult.value : null
|
||||
}
|
||||
|
||||
async function onRefresh() {
|
||||
await loadData()
|
||||
await loadData(true)
|
||||
refreshing.value = false
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user