Split desktop and mobile layouts with shared page data so APIs fetch once per context.

Add layout shells, desktop views, module-level page caches, and UI fixes for auth, home, wallet, transactions, address, and related pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-14 10:08:46 +03:30
co-authored by Cursor
parent 4404b4cb92
commit a5e458ed25
234 changed files with 18425 additions and 5503 deletions
@@ -0,0 +1,82 @@
import { ref } from 'vue'
import { getProvince, tableAddress } from '@/api/address'
import type { Address } from '@/models/address'
import { loading, loadingMore } from '@/utils'
import { runOnceAsync, resetOnceAsyncByPrefix } from '@/composables/useOnceAsync'
/**
* Shared address page datasets — mobile and desktop views read this module state only.
*/
let initPromise: Promise<void> | null = null
const initialized = ref(false)
export const addressItems = ref<Address[]>([])
export const addressProvinceList = ref<any[]>([])
export function isAddressPageDataInitialized() {
return initialized.value
}
export async function refreshAddressItems() {
try {
loading.value = true
const data = await tableAddress({ page: 0, limit: 150 })
addressItems.value = data.rows
} catch (error) {
console.error('Address list refresh error:', error)
} finally {
loading.value = false
loadingMore.value = false
}
}
async function loadAddressItems() {
const data = await tableAddress({ page: 0, limit: 150 })
addressItems.value = data.rows
}
async function loadProvinces() {
addressProvinceList.value = await getProvince()
}
export async function initAddressPageData(force = false) {
if (!force && initialized.value) {
return
}
if (!force && initPromise) {
return initPromise
}
initPromise = (async () => {
try {
if (force) {
resetAddressPageData()
}
loading.value = true
await Promise.all([
runOnceAsync('address:items', () => loadAddressItems(), force),
runOnceAsync('address:provinces', () => loadProvinces(), force),
])
initialized.value = true
} catch (error) {
console.error('Address page initialization error:', error)
} finally {
loading.value = false
initPromise = null
}
})()
return initPromise
}
export function resetAddressPageData() {
initialized.value = false
initPromise = null
resetOnceAsyncByPrefix('address:')
addressItems.value = []
addressProvinceList.value = []
}