fix: style

This commit is contained in:
2026-03-23 10:12:55 +01:00
parent 12e9e49f9b
commit 0853424c4e
11 changed files with 110 additions and 38 deletions

1
bo/components.d.ts vendored
View File

@@ -11,6 +11,7 @@ export {}
/* prettier-ignore */ /* prettier-ignore */
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
Cart1: typeof import('./src/components/customer/Cart1.vue')['default']
Cs_PrivacyPolicyView: typeof import('./src/components/terms/cs_PrivacyPolicyView.vue')['default'] Cs_PrivacyPolicyView: typeof import('./src/components/terms/cs_PrivacyPolicyView.vue')['default']
Cs_TermsAndConditionsView: typeof import('./src/components/terms/cs_TermsAndConditionsView.vue')['default'] Cs_TermsAndConditionsView: typeof import('./src/components/terms/cs_TermsAndConditionsView.vue')['default']
En_PrivacyPolicyView: typeof import('./src/components/terms/en_PrivacyPolicyView.vue')['default'] En_PrivacyPolicyView: typeof import('./src/components/terms/en_PrivacyPolicyView.vue')['default']

View File

@@ -31,6 +31,9 @@ const authStore = useAuthStore()
<RouterLink :to="{ name: 'cart' }"> <RouterLink :to="{ name: 'cart' }">
Cart Cart
</RouterLink> </RouterLink>
<RouterLink :to="{ name: 'cart1' }">
Cart1
</RouterLink>
<RouterLink :to="{ name: 'products-list' }"> <RouterLink :to="{ name: 'products-list' }">
Products List Products List
</RouterLink> </RouterLink>

View File

@@ -26,7 +26,6 @@
</UButton> </UButton>
</div> </div>
<!-- Loading Overlay -->
<div v-if="translating" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50"> <div v-if="translating" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
<div class="flex flex-col items-center gap-4 p-8 bg-(--main-light) dark:bg-(--main-dark) rounded-lg shadow-xl"> <div class="flex flex-col items-center gap-4 p-8 bg-(--main-light) dark:bg-(--main-dark) rounded-lg shadow-xl">
<UIcon name="svg-spinners:ring-resize" class="text-4xl text-primary" /> <UIcon name="svg-spinners:ring-resize" class="text-4xl text-primary" />

View File

@@ -0,0 +1,66 @@
<template>
<div class="container mx-auto mt-15">
<div
class="bg-(--second-light) dark:bg-(--main-dark) rounded-lg border border-(--border-light) dark:border-(--border-dark) overflow-hidden">
<h2
class="text-lg font-semibold text-black dark:text-white p-4 border-b border-(--border-light) dark:border-(--border-dark)">
{{ t('Cart Items') }}
</h2>
<div v-if="cartStore.items.length > 0" class="divide-y divide-(--border-light) dark:divide-(--border-dark)">
<div v-for="item in cartStore.items" :key="item.id" class="flex items-center justify-between p-4 gap-4">
<div class="flex items-center gap-10 flex-1">
<div
class="w-20 bg-(--second-light) dark:bg-(--main-dark) rounded flex items-center justify-center overflow-hidden">
<img v-if="item.image" :src="item.image" :alt="item.name" class="w-full h-full object-cover" />
<UIcon v-else name="mdi:package-variant" class="text-xl text-gray-400" />
</div>
<div class="flex-1 min-w-0">
<p class="text-black dark:text-white text-sm font-medium truncate">{{ item.name }}</p>
<p class="text-gray-500 dark:text-gray-400 text-sm">
{{ t('Qty') }}: {{ item.quantity }} × ${{ item.price.toFixed(2) }}
</p>
</div>
</div>
<div class="text-right flex-shrink-0">
<p class="text-black dark:text-white font-medium">${{ (item.price * item.quantity).toFixed(2) }}</p>
</div>
</div>
</div>
<div v-else class="p-8 text-center">
<UIcon name="mdi:cart-outline" class="text-5xl text-gray-300 dark:text-gray-600 mb-4 mx-auto" />
<p class="text-gray-500 dark:text-gray-400">{{ t('Your cart is empty') }}</p>
</div>
<div v-if="cartStore.items.length > 0"
class="p-4 border-t border-(--border-light) dark:border-(--border-dark) bg-(--second-light) dark:bg-(--main-dark) flex gap-4 justify-end items-center">
<UButton color="primary" @click="handleContinueToCheckout"
class="bg-(--accent-blue-light) dark:bg-(--accent-blue-dark) text-white hover:bg-(--accent-blue-dark) dark:hover:bg-(--accent-blue-light)">
{{ t('Continue to Checkout') }}
</UButton>
<UButton variant="outline" color="neutral" @click="handleCancel"
class="text-black dark:text-white border-(--border-light) dark:border-(--border-dark) hover:bg-gray-100 dark:hover:bg-gray-700">
{{ t('Cancel') }}
</UButton>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useCartStore } from '@/stores/cart'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
const cartStore = useCartStore()
const { t } = useI18n()
const router = useRouter()
function handleCancel() {
router.back()
}
function handleContinueToCheckout() {
router.push({ name: 'cart' })
}
</script>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="container mx-auto mt-10"> <div class="container mx-auto mt-15">
<div class="flex flex-col gap-5 mb-6"> <div class="flex flex-col gap-5 mb-6">
<h1 class="text-2xl font-bold text-black dark:text-white">{{ t('Addresses') }}</h1> <h1 class="text-2xl font-bold text-black dark:text-white">{{ t('Addresses') }}</h1>
<div class="flex md:flex-row flex-col justify-between items-start md:items-center gap-5 md:gap-0"> <div class="flex md:flex-row flex-col justify-between items-start md:items-center gap-5 md:gap-0">

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="container mx-auto mt-20 px-4 py-8"> <div class="container mx-auto mt-15">
<h1 class="text-2xl font-bold text-black dark:text-white mb-8">{{ t('Shopping Cart') }}</h1> <h1 class="text-2xl font-bold text-black dark:text-white mb-8">{{ t('Shopping Cart') }}</h1>
<div class="flex flex-col lg:flex-row gap-8 mb-8"> <div class="flex flex-col lg:flex-row gap-8 mb-8">
<div class="flex-1"> <div class="flex-1">

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="container mt-14 mx-auto"> <div class="container mt-15 mx-auto">
<div class="flex md:flex-row flex-col justify-between gap-8 mb-6"> <div class="flex md:flex-row flex-col justify-between gap-8 mb-6">
<div class="flex-1"> <div class="flex-1">
<div class="bg-gray-100 dark:bg-gray-800 rounded-lg p-8 flex items-center justify-center min-h-[300px]"> <div class="bg-gray-100 dark:bg-gray-800 rounded-lg p-8 flex items-center justify-center min-h-[300px]">

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="container mx-auto p-6"> <div class="container mx-auto mt-15">
<h1 class="text-2xl font-bold mb-6 text-gray-900 dark:text-white">Products</h1> <h1 class="text-2xl font-bold mb-6 text-gray-900 dark:text-white">Products</h1>
<div v-if="loading" class="text-center py-8"> <div v-if="loading" class="text-center py-8">
<span class="text-gray-600 dark:text-gray-400">Loading products...</span> <span class="text-gray-600 dark:text-gray-400">Loading products...</span>
@@ -13,35 +13,36 @@
<tr> <tr>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider"> class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Product ID Image</th>
</th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider"> class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Reference Product ID</th>
</th>
<th <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider"> class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Price Name</th>
</th> <th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Link</th>
</tr> </tr>
</thead> </thead>
<tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700"> <tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
<tr v-for="product in products" :key="product.product_id" <tr v-for="product in productsList" :key="product.product_id"
class="hover:bg-gray-50 dark:hover:bg-gray-800"> class="hover:bg-gray-50 dark:hover:bg-gray-800">
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white"> <td class="px-6 py-4 whitespace-nowrap">
{{ product.product_id }} <img :src="getImageUrl(product.ImageID, product.LinkRewrite,)" alt="product image"
class="w-16 h-16 object-cover rounded" />
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white"> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">{{
{{ product.reference }} product.product_id }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">{{ product.name }}
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white"> <td class="px-6 py-4 whitespace-nowrap text-sm text-blue-600 dark:text-blue-400">
{{ product.price.toFixed(2) }} {{ product.LinkRewrite }}
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div v-if="productsList.length === 0" class="text-center py-8 text-gray-500 dark:text-gray-400">
<div v-if="products.length === 0" class="text-center py-8 text-gray-500 dark:text-gray-400">
No products found No products found
</div> </div>
</div> </div>
@@ -54,36 +55,36 @@ import { useFetchJson } from '@/composable/useFetchJson'
interface Product { interface Product {
product_id: number product_id: number
reference: string name: string
price: number ImageID: number
LinkRewrite: string
} }
interface ApiResponse { interface ApiResponse {
message: string
items: Product[] items: Product[]
count: number count: number
message: string
} }
const products = ref<Product[]>([]) const productsList = ref<Product[]>([])
const loading = ref(true) const loading = ref(true)
const error = ref<string | null>(null) const error = ref<string | null>(null)
async function fetchProducts() { function getImageUrl(imageID: number, linkRewrite: string, size: string = 'small_default') {
return `https://www.naluconcept.com/${imageID}-${size}/${linkRewrite}.webp`
}
async function fetchProductList() {
loading.value = true loading.value = true
error.value = null error.value = null
try { try {
const response = await useFetchJson<ApiResponse>('/api/v1/restricted/list-products/get-listing?p=3&elems') as unknown as { items: Product[] } const response = await useFetchJson('/api/v1/restricted/list-products/get-listing?p&elems&shopID=1') as ApiResponse
products.value = response.items || [] productsList.value = response.items || []
} catch (e: any) { } catch (e: unknown) {
error.value = e.message || 'Failed to load products' error.value = e instanceof Error ? e.message : 'Failed to load products'
console.error('Error fetching products:', e) console.error(e)
} finally { } finally {
loading.value = false loading.value = false
} }
} }
onMounted(fetchProductList)
onMounted(() => {
fetchProducts()
})
</script> </script>

View File

@@ -30,6 +30,7 @@ const router = createRouter({
{ path: 'product-card-full/', component: () => import('../components/customer/PageProductCardFull.vue'), name: 'product-card-full' }, { path: 'product-card-full/', component: () => import('../components/customer/PageProductCardFull.vue'), name: 'product-card-full' },
{ path: 'addresses', component: () => import('../components/customer/PageAddresses.vue'), name: 'addresses' }, { path: 'addresses', component: () => import('../components/customer/PageAddresses.vue'), name: 'addresses' },
{ path: 'cart', component: () => import('../components/customer/PageCart.vue'), name: 'cart' }, { path: 'cart', component: () => import('../components/customer/PageCart.vue'), name: 'cart' },
{ path: 'cart1', component: () => import('../components/customer/Cart1.vue'), name: 'cart1' },
{ path: 'products-list', component: () => import('../components/customer/PageProductsList.vue'), name: 'products-list' }, { path: 'products-list', component: () => import('../components/customer/PageProductsList.vue'), name: 'products-list' },
], ],
}, },

View File

@@ -65,6 +65,7 @@ export const useCartStore = defineStore('cart', () => {
} }
} }
function removeItem(itemId: number) { function removeItem(itemId: number) {
const index = items.value.findIndex(i => i.id === itemId) const index = items.value.findIndex(i => i.id === itemId)
if (index !== -1) { if (index !== -1) {

View File

@@ -92,6 +92,6 @@ export const useProductStore = defineStore('product', () => {
getProductDescription, getProductDescription,
clearCurrentProduct, clearCurrentProduct,
saveProductDescription, saveProductDescription,
translateProductDescription translateProductDescription,
} }
}) })