Skip to content

Commit

Permalink
add skeleton rendering product card item
Browse files Browse the repository at this point in the history
  • Loading branch information
thuongtruong1009 committed Jun 6, 2022
1 parent b7960d0 commit e127880
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 275 deletions.
6 changes: 5 additions & 1 deletion src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ declare module 'vue' {
CarbonLanguage: typeof import('~icons/carbon/language')['default']
CarbonMoon: typeof import('~icons/carbon/moon')['default']
CarbonSun: typeof import('~icons/carbon/sun')['default']
CarbonWarning: typeof import('~icons/carbon/warning')['default']
CASellerList: typeof import('./components/admin/CASellerList.vue')['default']
CBAccount: typeof import('./components/buyer/CBAccount.vue')['default']
CBBanner: typeof import('./components/buyer/CBBanner.vue')['default']
Expand Down Expand Up @@ -44,7 +45,8 @@ declare module 'vue' {
CMap: typeof import('./components/CMap.vue')['default']
Counter: typeof import('./components/Counter.vue')['default']
CPagination: typeof import('./components/CPagination.vue')['default']
CProductCard: typeof import('./components/CProductCard.vue')['default']
CProductCardFlow: typeof import('./components/CProductCardFlow.vue')['default']
CProductCardGrid: typeof import('./components/CProductCardGrid.vue')['default']
CProgress: typeof import('./components/CProgress.vue')['default']
CSChooseCategory: typeof import('./components/seller/CSChooseCategory.vue')['default']
CSFooter: typeof import('./components/seller/CSFooter.vue')['default']
Expand Down Expand Up @@ -175,6 +177,8 @@ declare module 'vue' {
PSRegister: typeof import('./components/partterns/seller/PSRegister.vue')['default']
README: typeof import('./components/README.md')['default']
RMenu: typeof import('./components/header/RMenu.vue')['default']
RProductCardGrid: typeof import('./components/rendering/RProductCardGrid.vue')['default']
RProductSearch: typeof import('./components/rendering/RProductSearch.vue')['default']
SHead: typeof import('./components/seller/SHead.vue')['default']
SLMenu: typeof import('./components/seller/SLMenu.vue')['default']
}
Expand Down
199 changes: 199 additions & 0 deletions src/components/CProductCardFlow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
<script setup>
import { useRouter } from 'vue-router'
import { useLoading } from '~/stores/loading'
import { toast } from '~/stores/toast'
import { useSeller } from '~/stores/seller'
import { useProduct } from '~/stores/product'
import { handleError } from '~/helpers/error'
import { handleDate } from '~/utils/date'
import { productStatus } from '~/utils/status'
import { sliceText } from '~/utils/textHandle'
import { getResources } from '~/utils/resources'
import ShopRequest from '~/services/shop-request'
import ProductRequest from '~/services/product-request'
import AccountRequest from '~/services/account-request'
import CartRequest from '~/services/cart-request'
import OrderRequest from '~/services/order-request'
const { t } = useI18n()
const router = useRouter()
const useToast = toast()
const product = useProduct()
const props = defineProps({
card: Object,
})
const productPrice = ref()
const productStock = ref()
// ------------------------------------------
watchEffect(async() => {
// get price min-max
const valuesPrice = props.card.models.map(i => i.price)
const maxPrice = Math.max(...valuesPrice)
const minPrice = Math.min(...valuesPrice)
if (maxPrice === minPrice)
productPrice.value = `$${maxPrice}`
else
productPrice.value = `$${minPrice} - $${maxPrice}`
// get stock min-max
const valuesStock = props.card.models.map(i => i.stock)
const maxStock = Math.max(...valuesStock)
const minStock = Math.min(...valuesStock)
if (minStock === maxStock)
productStock.value = `${maxStock}`
else
productStock.value = `${minStock} - ${maxStock}`
})
// ------------------- VISIST PRODUCT DETAIL --------------
const onVisitProduct = (prod_id, shop_id) => {
product.productRequestID = prod_id
product.shopRequestID = shop_id
router.push(`/product/${encodeURIComponent(prod_id)}`)
}
// -----------------------------------------
const isPopup = ref(false)
const onOpenPopup = () => {
const body = document.body
body.style.overflowY = 'hidden'
isPopup.value = true
}
const onClosePopup = () => {
const body = document.body
body.style.overflowY = ''
isPopup.value = false
}
</script>

<template>
<div>
<div class="relative z-1">
<div class="card-type flex justify-between absolute w-full p-5">
<span class="bg-green-600 text-white font-bold capitalize text-xs rounded p-0.75">-10%</span>
<span class="bg-orange-400 text-white font-bold capitalize text-xs rounded p-0.75">{{ t('search.new') }}</span>
</div>
<div class="card-img max-w-full max-h-7/12" @click="onVisitProduct(props.card.id, props.card.shop_id)">
<img class="first-img rounded-xl w-full" :src="`${getResources(props.card.images[0])}_tn`" alt="product_img">
</div>
<!-- <div class="split third rounded-lg shadow-md" @click="onVisitProduct(props.card.id, props.card.shop_id)">
<div class="cover">
<img class="first-img rounded-t-lg w-full max-h-80" :src="`${getResources(props.card.images[0])}_tn`" alt="product_img">
</div>
</div> -->
</div>
<div class="product-description text-left p-2">
<div class="px-2">
<p class="card-title cursor-pointer duration-200 ease-linear hover:text-[#FF6600]" @click="onVisitProduct(props.card.id, props.card.shop_id)">
{{ props.card.name }}
</p>
<div class="star-rating flex justify-start py-2">
<img v-for="i in 5" :key="i" src="https://img.icons8.com/fluency/48/ffffff/star.png" class="max-w-4 max-h-4">
</div>
<div class="flex items-center justify-start">
<h6 class="card-price font-bold tracking-tighter mr-2 black text[#9B9B9B] text-decoration line-through">
$999
</h6>
<h6 class="font-bold tracking-tighter text-red-500">
{{ productPrice }}
</h6>
</div>
</div>

<div class="product-infor py-5 text-sm leading-6">
<p v-for="(line, i) in sliceText(props.card.description)?.split('\\n')" :key="i">
{{ line }}
</p>
</div>

<div class="product-quantity">
<p>{{ t('search.availability') }}: <span class="text-[#10A391]">{{ productStock }} In Stock</span></p>
</div>

<div class="py-5 flex justify-start">
<h3 class="uppercase py-2.5 px-10 rounded-md bg-black text-white font-medium text-sm cursor-pointer hover:bg-[#F33535] duration-200" @click="onOpenPopup">
{{ t('search.add-to-cart') }}
</h3>
</div>

<div v-if="isPopup === true" class="popup-modal z-3 fixed w-screen h-screen top-0 left-0 flex justify-center items-center ease-linear">
<div class="bg-white w-284 z-20 rounded-lg" @click="onClosePopup">
<div class="text-white flex justify-center items-center bg-black rounded-t-lg gap-2 relative py-2">
<ICheck />
<h5 class="text-lg" style="font-family: 'Gilroy-Medium'">
{{ t('search.add-success-message') }}
</h5>
<span class="cursor-pointer text-4xl absolute right-3 -top-1" @click="onClosePopup">&times;</span>
</div>
<div class="grid grid-cols-7 px-10 pt-10 pb-5 divide-1 divide-solid divide-gray-200 divide-x">
<div class="flex col-span-3 gap-2">
<img src="/img/product/shoes/3.webp" alt="new_product" class="max-w-50 max-h-50">
<div class="text-md font-semibold">
<h6 class="pb-3">
New Balance Running Arishi trainers in triple
</h6>
<p>$29.00</p>
<p>{{ t('search.dimension') }}: <span class="text-sm font-normal">40x60cm</span></p>
<p>{{ t('search.quantity') }}: 1</p>
</div>
</div>
<div class="col-span-4 px-10 text-sm font-semibold">
<p class="py-0.5 font-normal">
{{ t('search.there-is') }} 1 {{ t('search.item-in-your-cart') }}.
</p>
<p class="py-0.5">
{{ t('search.total-products') }}: <span class="font-normal">$123.72</span>
</p>
<p class="py-0.5">
{{ t('search.total-shipping') }}: <span class="font-normal">$7.00</span>
</p>
<p class="py-0.5">
{{ t('search.taxes') }} <span class="font-normal">$0.00</span>
</p>
<p class="py-0.5">
{{ t('search.total') }}: <span class="font-normal">$130.72 (tax excl.)</span>
</p>
<div class="uppercase flex text-white font-medium text-sm py-5">
<h6 class="bg-black rounded-md py-2 px-6 mr-2 hover:bg-red-500 cursor-pointer duration-200">
{{ t('search.continue-shopping') }}
</h6>
<h6 class="bg-black rounded-md py-2 px-6 hover:bg-red-500 cursor-pointer duration-200 flex gap-2 items-center">
<ICheck />{{ t('search.proceed-checkout') }}
</h6>
</div>
</div>
</div>
</div>
<div v-if="isPopup === true" class="fixed w-screen h-screen bg-black opacity-50 top-0 left-0" @click="onClosePopup" />
</div>
</div>
</div>
</template>

<style scoped>
.split.third {
display: block;
overflow: hidden;
cursor: pointer;
}
.split.third img {
width: 100%;
height: auto;
-webkit-transition: -webkit-transform 0.8s ease;
transition: -webkit-transform 0.8s ease;
transition: transform 0.8s ease;
transition: transform 0.8s ease, -webkit-transform 1s ease;
}
.split.third:hover img {
-webkit-transform: scale(1.15);
transform: scale(1.15);
}
/* ************************ POPUP MODAL **************************** */
.popup-modal{
animation: popup-animate 0.1s linear;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const onVisitProduct = (prod_id, shop_id) => {
</div>
<div class="split third rounded-lg shadow-md" @click="onVisitProduct(props.card.id, props.card.shop_id)">
<div class="cover">
<img class="first-img rounded-t-lg w-full max-h-80" :src="`${getResources(props.card.images[0])}_tn`" alt="thumbnail">
<img class="first-img rounded-t-lg w-full max-h-80" :src="`${getResources(props.card.images[0])}_tn`" alt="product_img">
</div>
</div>
<div class="product-description text-left p-2">
Expand Down
4 changes: 3 additions & 1 deletion src/components/head/CBSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ const useKeyword = keyword()
const key = ref(useKeyword.savedKeyword)
const router = useRouter()
const go = async() => {
if (key.value) {
await router.push(`/search/keyword=${encodeURIComponent(key.value)}`)
await router.push(`/search/${encodeURIComponent(key.value)}`)
await location.reload()
key.value = ''
}
}
</script>

<template>
Expand Down
21 changes: 21 additions & 0 deletions src/components/rendering/RProductCardGrid.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<div class="rendering_container animate-pulse duration-200 ease-linear rounded-lg w-60 shadow-md">
<div class="split third rounded-lg shadow-md">
<img class="first-img rounded-t-lg w-full max-h-80" src="/img/product/1.jpg" alt="thumbnail">
</div>
<div class="product-description text-left p-2">
<div class="flex flex-col gap-2 my-2">
<p class="w-[80%] h-3 rounded-lg bg-$light-rendering" />
<p class="w-[50%] h-3 rounded-lg bg-$light-rendering" />
</div>
<div class="flex items-center justify-between my-2">
<h6 class="w-[30%] h-2 rounded-lg bg-$light-rendering" />
<h6 class="w-[30%] h-2 rounded-lg bg-$light-rendering" />
</div>
<div class="flex justify-between">
<h6 class="w-[40%] h-2 rounded-lg bg-$light-rendering" />
<h6 class="w-[30%] h-2 rounded-lg bg-$light-rendering" />
</div>
</div>
</div>
</template>
2 changes: 1 addition & 1 deletion src/pages/buyer/account/orders.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ watch(async() => {
})
const trackOrder = (order_id) => {
order.savedOrder = order_id
router.push(`/buyer/order/id=${encodeURIComponent(order_id)}`)
router.push(`/buyer/order/${encodeURIComponent(order_id)}`)
}
</script>

Expand Down
6 changes: 5 additions & 1 deletion src/pages/buyer/order/[order].vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ meta:
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { useOrder } from '~/stores/order'
import { useLoading} from '~/stores/loading'
import { handleDate } from '~/utils/date'
import { useProduct } from '~/stores/product'
import { getResources } from '~/utils/resources'
Expand All @@ -15,6 +16,7 @@ import IBOrderArrowRight from '~/components/icons/account/IBOrderArrowRight.vue'
const router = useRouter()
const order = useOrder()
const product = useProduct()
const loading = useLoading()
const { t } = useI18n()
useHead({
title: `order | ${order.savedOrder}`,
Expand All @@ -33,13 +35,15 @@ const statusPercent = (status_id: number) => {
case 5:
return 99
default:
return 0
return 10
}
}
const payget = ref([])
const orderImg = ref('')
onMounted(async() => {
loading.isLoading = true
const { data: orderData } = await OrderRequest.getOrdersById(order.savedOrder)
loading.isLoading = false
payget.value = orderData
order.orderVariation = orderData.product.variations[0]
order.orderAddress = orderData.received_address
Expand Down
Loading

0 comments on commit e127880

Please sign in to comment.