update frontend
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
<script setup lang="ts">
|
||||
import useGetOrder from "~/composables/api/orders/useGetOrder";
|
||||
import useDownloadInvoice from "~/composables/api/orders/useDownloadInvoice";
|
||||
import usePersianDate from "~/composables/global/usePersianDate";
|
||||
|
||||
// meta
|
||||
|
||||
useSeoMeta({
|
||||
title: "پنل کاربری جزئیات سفارش",
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
middleware: "check-is-logged-in",
|
||||
layout: "profile",
|
||||
});
|
||||
|
||||
// state
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const { formatToPersian } = usePersianDate();
|
||||
|
||||
// computed
|
||||
|
||||
const orderId = computed(() => route.params.id as string);
|
||||
|
||||
// queries
|
||||
|
||||
const { data: order, isLoading: orderIsLoading } = useGetOrder(orderId);
|
||||
|
||||
const { downloadFn, downloadIsLoading } = useDownloadInvoice(orderId.value);
|
||||
|
||||
// computed
|
||||
|
||||
const statusVariant = computed(() => {
|
||||
const status = order.value?.status;
|
||||
if (!status) return "neutral";
|
||||
if (["ADMIN_PENDING", "PENDING"].includes(status)) return "warning";
|
||||
if (["POSTED", "RECEIVED"].includes(status)) return "success";
|
||||
if (["CANCELED", "REFUND", "REFUNDED"].includes(status)) return "danger";
|
||||
return "neutral";
|
||||
});
|
||||
|
||||
const statusClass = computed(() => {
|
||||
return {
|
||||
warning: "text-warning-600 bg-warning-100 border-warning-600",
|
||||
success: "text-success-600 bg-success-100 border-success-600",
|
||||
danger: "text-danger-600 bg-danger-100 border-danger-600",
|
||||
neutral: "text-slate-600 bg-slate-100 border-slate-300",
|
||||
}[statusVariant.value];
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full flex flex-col gap-5">
|
||||
<ProfilePageTitle
|
||||
:title="`جزئیات سفارش ${order?.order_id ? `${order.order_id}#` : ''}`"
|
||||
icon="ci:bi-cart"
|
||||
/>
|
||||
|
||||
<div class="w-full flex flex-col gap-5 lg:px-5">
|
||||
<div class="flex items-center justify-between gap-3 flex-wrap">
|
||||
<NuxtLink :to="{ name: 'profile-purchases-and-orders' }">
|
||||
<Button
|
||||
end-icon="ci:bi-arrow-left"
|
||||
size="md"
|
||||
class="rounded-full"
|
||||
>
|
||||
<span class="whitespace-pre">بازگشت به سفارشات</span>
|
||||
</Button>
|
||||
</NuxtLink>
|
||||
|
||||
<Button
|
||||
v-if="order?.is_paid"
|
||||
@click="!downloadIsLoading ? downloadFn() : undefined"
|
||||
:disabled="downloadIsLoading"
|
||||
end-icon="ci:bi-download"
|
||||
size="md"
|
||||
class="rounded-full"
|
||||
>
|
||||
<span class="whitespace-pre">دانلود فاکتور</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="orderIsLoading"
|
||||
class="w-full grid grid-cols-1 lg:grid-cols-3 gap-5"
|
||||
>
|
||||
<Skeleton class="!w-full !h-40 !rounded-xl lg:col-span-2" />
|
||||
<Skeleton class="!w-full !h-40 !rounded-xl" />
|
||||
<Skeleton class="!w-full !h-60 !rounded-xl lg:col-span-2" />
|
||||
<Skeleton class="!w-full !h-60 !rounded-xl" />
|
||||
</div>
|
||||
|
||||
<Placeholder
|
||||
v-else-if="!order"
|
||||
class="!w-full !py-[5rem]"
|
||||
icon="ci:bi-cart"
|
||||
title="سفارشی یافت نشد"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="w-full grid grid-cols-1 lg:grid-cols-3 gap-5"
|
||||
>
|
||||
<div
|
||||
class="lg:col-span-2 w-full flex flex-col gap-4 p-5 border border-slate-200 rounded-xl bg-slate-50"
|
||||
>
|
||||
<div class="flex items-center justify-between gap-3 flex-wrap">
|
||||
<div class="flex items-center gap-3">
|
||||
<Icon
|
||||
name="ci:bi-cart"
|
||||
class="**:fill-black"
|
||||
size="20"
|
||||
/>
|
||||
<span class="text-sm font-semibold">اطلاعات سفارش</span>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-full py-1.5 px-3 text-xs border"
|
||||
:class="statusClass"
|
||||
>
|
||||
{{ order.verbose_status ?? "--" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 text-xs lg:text-sm">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">شماره سفارش:</span>
|
||||
<span class="font-medium text-cyan-600">{{ order.order_id ? `${order.order_id}#` : "--" }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">تاریخ ثبت:</span>
|
||||
<span class="font-medium">
|
||||
{{ order.created_at ? formatToPersian(order.created_at) : "--" }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">تعداد اقلام:</span>
|
||||
<span class="font-medium">{{ order.count ?? "--" }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">وضعیت پرداخت:</span>
|
||||
<span class="font-medium">
|
||||
{{ order.is_paid ? "پرداخت شده" : "پرداخت نشده" }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="w-full flex flex-col gap-4 p-5 border border-slate-200 rounded-xl bg-slate-50"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<Icon
|
||||
name="ci:bi-map"
|
||||
class="**:fill-black"
|
||||
size="20"
|
||||
/>
|
||||
<span class="text-sm font-semibold">آدرس تحویل</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="order.address"
|
||||
class="flex flex-col gap-2 text-xs lg:text-sm"
|
||||
>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">گیرنده:</span>
|
||||
<span class="font-medium">{{ order.address.name ?? "--" }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">شماره تماس:</span>
|
||||
<span class="font-medium">{{ order.address.phone ?? "--" }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">استان / شهر:</span>
|
||||
<span class="font-medium">
|
||||
{{ order.address.province ?? "--" }} / {{ order.address.city ?? "--" }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="text-dynamic-secondary">کد پستی:</span>
|
||||
<span class="font-medium">{{ order.address.postal_code ?? "--" }}</span>
|
||||
</div>
|
||||
<div class="text-dynamic-secondary leading-[180%]">
|
||||
{{ order.address.address ?? "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="text-xs text-dynamic-secondary"
|
||||
>
|
||||
آدرسی ثبت نشده است
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="lg:col-span-2 w-full flex flex-col gap-4 p-5 border border-slate-200 rounded-xl bg-slate-50"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<Icon
|
||||
name="ci:bi-box"
|
||||
class="**:fill-black"
|
||||
size="20"
|
||||
/>
|
||||
<span class="text-sm font-semibold">اقلام سفارش</span>
|
||||
</div>
|
||||
|
||||
<Placeholder
|
||||
v-if="!order.items?.length"
|
||||
class="!w-full !py-10"
|
||||
icon="ci:bi-box"
|
||||
title="کالایی در این سفارش ثبت نشده"
|
||||
/>
|
||||
|
||||
<ul
|
||||
v-else
|
||||
class="w-full flex flex-col divide-y divide-slate-200"
|
||||
>
|
||||
<li
|
||||
v-for="item in order.items"
|
||||
:key="item.id"
|
||||
class="w-full flex items-center gap-3 py-4"
|
||||
>
|
||||
<NuxtImg
|
||||
v-if="item.product?.image"
|
||||
:src="item.product.image"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="size-16 lg:size-20 rounded-100 border border-slate-200 object-cover"
|
||||
/>
|
||||
<div class="flex-1 flex flex-col gap-1">
|
||||
<NuxtLink
|
||||
v-if="item.product?.slug"
|
||||
:to="`/product/${item.product.slug}`"
|
||||
class="text-xs lg:text-sm font-semibold line-clamp-2 hover:text-cyan-600 transition-colors"
|
||||
>
|
||||
{{ item.product.title ?? "--" }}
|
||||
</NuxtLink>
|
||||
<span
|
||||
v-else
|
||||
class="text-xs lg:text-sm font-semibold line-clamp-2"
|
||||
>
|
||||
{{ item.product?.title ?? "--" }}
|
||||
</span>
|
||||
<span class="text-xs text-dynamic-secondary">
|
||||
تعداد: {{ item.quantity }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-end gap-1 text-xs lg:text-sm">
|
||||
<span class="font-medium whitespace-pre">{{ item.final_price }}</span>
|
||||
<span
|
||||
v-if="item.discount_percent && item.discount_percent > 0"
|
||||
class="text-dynamic-secondary line-through whitespace-pre"
|
||||
>
|
||||
{{ item.price }}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="w-full flex flex-col gap-4 p-5 border border-slate-200 rounded-xl bg-slate-50 h-fit"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<Icon
|
||||
name="ci:bi-tag"
|
||||
class="**:fill-black"
|
||||
size="20"
|
||||
/>
|
||||
<span class="text-sm font-semibold">خلاصه فاکتور</span>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-3 text-xs lg:text-sm">
|
||||
<div
|
||||
v-if="order.cart_total"
|
||||
class="flex items-center justify-between gap-2 text-slate-800"
|
||||
>
|
||||
<span>جمع سبد:</span>
|
||||
<span>{{ order.cart_total }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="order.discount_amount"
|
||||
class="flex items-center justify-between gap-2 text-red-700"
|
||||
>
|
||||
<span>تخفیف:</span>
|
||||
<span>{{ order.discount_amount }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="order.special_discount_total"
|
||||
class="flex items-center justify-between gap-2 text-green-700"
|
||||
>
|
||||
<span>تخفیف ویژه:</span>
|
||||
<span>{{ order.special_discount_total }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="order.tax"
|
||||
class="flex items-center justify-between gap-2 text-slate-800"
|
||||
>
|
||||
<span>مالیات:</span>
|
||||
<span>{{ order.tax }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-between gap-2 pt-3 border-t border-slate-200 text-slate-900 font-semibold"
|
||||
>
|
||||
<span>مبلغ نهایی:</span>
|
||||
<span>{{ order.final_price ?? "--" }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user