new purchase page structure
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
// meta
|
||||
|
||||
definePageMeta({
|
||||
middleware: "check-is-logged-in",
|
||||
layout: "profile",
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full flex flex-col gap-5">
|
||||
<ProfilePageTitle title="خرید ها و سفارش های شما" icon="bi:cart" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,256 @@
|
||||
<script setup lang="ts">
|
||||
import useGetAllOrders, {
|
||||
type GetAllOrdersRequest,
|
||||
} from "~/composables/api/orders/useGetAllOrders";
|
||||
|
||||
// meta
|
||||
|
||||
definePageMeta({
|
||||
middleware: "check-is-logged-in",
|
||||
layout: "profile",
|
||||
});
|
||||
|
||||
// state
|
||||
|
||||
const params: GetAllOrdersRequest = useUrlSearchParams("history");
|
||||
|
||||
const filters = computed(() => {
|
||||
return {
|
||||
sort: params.sort ?? "created_at",
|
||||
status: params.status ?? "",
|
||||
page: params.page ?? 1,
|
||||
};
|
||||
});
|
||||
|
||||
const tableHeads = ref([
|
||||
"شماره سفارش",
|
||||
"تاریخ ثبت",
|
||||
"تعداد اقلام",
|
||||
"مبلغ",
|
||||
"وضعیت",
|
||||
"عملیات",
|
||||
]);
|
||||
|
||||
const sortFilters = ref([
|
||||
{
|
||||
title: "جدید ترین",
|
||||
value: "created_at",
|
||||
},
|
||||
{
|
||||
title: "قدیمی ترین",
|
||||
value: "-created_at",
|
||||
},
|
||||
{
|
||||
title: "گران ترین",
|
||||
value: "final_price",
|
||||
},
|
||||
{
|
||||
title: "ارزان ترین",
|
||||
value: "-final_price",
|
||||
},
|
||||
]);
|
||||
|
||||
const statusFilters = ref([
|
||||
{
|
||||
title: "در انتظار تایید",
|
||||
value: "ADMIN_PENDING",
|
||||
},
|
||||
{
|
||||
title: "در حال پردازش",
|
||||
value: "PENDING",
|
||||
},
|
||||
{
|
||||
title: "ارسال شده",
|
||||
value: "POSTED",
|
||||
},
|
||||
{
|
||||
title: "تحویل داده شده",
|
||||
value: "RECEIVED",
|
||||
},
|
||||
{
|
||||
title: "لغو شده",
|
||||
value: "CANCELED",
|
||||
},
|
||||
{
|
||||
title: "مرجوع شده",
|
||||
value: "REFUND",
|
||||
},
|
||||
]);
|
||||
|
||||
// provide / inject
|
||||
|
||||
provide("params", params);
|
||||
|
||||
// queries
|
||||
|
||||
const { data, isPending: purchasesIsPending } = useGetAllOrders(filters);
|
||||
|
||||
// computed
|
||||
|
||||
const purchases = computed(() => {
|
||||
return data.value?.results.flat();
|
||||
});
|
||||
|
||||
const hasPurchases = computed(() => data.value?.count > 0);
|
||||
|
||||
const hasFilters = computed(() =>
|
||||
Object.keys(params)
|
||||
.filter((key) => key != "page")
|
||||
.some((key) => params[key] != undefined)
|
||||
);
|
||||
|
||||
const paginationData = computed(() => {
|
||||
return data.value?.results.map((_, i: number) => {
|
||||
return { type: "page", value: i };
|
||||
});
|
||||
});
|
||||
|
||||
// methods
|
||||
|
||||
const clearFilters = () => {
|
||||
params.sort = undefined;
|
||||
params.status = undefined;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full flex flex-col gap-5">
|
||||
<ProfilePageTitle title="خرید ها و سفارش های شما" icon="bi:cart" />
|
||||
|
||||
<div class="w-full flex flex-col gap-5">
|
||||
<div class="w-full flex items-center justify-between px-5">
|
||||
<div class="flex items-center justify-start gap-8">
|
||||
<div class="flex items-center justify-start gap-3">
|
||||
<span class="text-sm">ترتیب بر اساس</span>
|
||||
<Select
|
||||
v-model="params.sort!"
|
||||
triggerRootClass="!py-2.5"
|
||||
class="w-[6rem]"
|
||||
>
|
||||
<template #content>
|
||||
<SelectGroup>
|
||||
<SelectItem
|
||||
v-for="(category, index) in sortFilters"
|
||||
:key="index"
|
||||
class="text-xs leading-none w-full rounded-sm py-5 flex items-center justify-between h-[25px] pr-[12px] relative select-none data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-slate-300 data-[highlighted]:text-black"
|
||||
:value="category.value"
|
||||
>
|
||||
<SelectItemIndicator
|
||||
class="absolute left-0 w-[25px] inline-flex items-center justify-center"
|
||||
>
|
||||
<Icon name="bi:check" size="20" />
|
||||
</SelectItemIndicator>
|
||||
<SelectItemText
|
||||
class="text-end font-iran-yekan-x text-sm"
|
||||
>
|
||||
{{ category.title }}
|
||||
</SelectItemText>
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</template>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="flex items-center justify-start gap-3">
|
||||
<span class="text-sm">وضعیت</span>
|
||||
<Select
|
||||
v-model="params.status!"
|
||||
triggerRootClass="!py-2.5"
|
||||
class="w-[6rem]"
|
||||
>
|
||||
<template #content>
|
||||
<SelectGroup>
|
||||
<SelectItem
|
||||
v-for="(
|
||||
category, index
|
||||
) in statusFilters"
|
||||
:key="index"
|
||||
class="text-xs leading-none w-full rounded-sm py-5 flex items-center justify-between h-[25px] pr-[12px] relative select-none data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-slate-300 data-[highlighted]:text-black"
|
||||
:value="category.value"
|
||||
>
|
||||
<SelectItemIndicator
|
||||
class="absolute left-0 w-[25px] inline-flex items-center justify-center"
|
||||
>
|
||||
<Icon name="bi:check" size="20" />
|
||||
</SelectItemIndicator>
|
||||
<SelectItemText
|
||||
class="text-end font-iran-yekan-x text-sm"
|
||||
>
|
||||
{{ category.title }}
|
||||
</SelectItemText>
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</template>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-center gap-4">
|
||||
<Button
|
||||
v-if="hasFilters"
|
||||
end-icon="bi:x"
|
||||
@click="clearFilters"
|
||||
size="md"
|
||||
class="rounded-full"
|
||||
>
|
||||
<span class="whitespace-pre"> حذف فیلتر ها </span>
|
||||
</Button>
|
||||
|
||||
<NuxtLink :to="{ name: 'products' }">
|
||||
<Button
|
||||
end-icon="bi:plus"
|
||||
size="md"
|
||||
class="rounded-full"
|
||||
>
|
||||
<span class="whitespace-pre"> خرید جدید </span>
|
||||
</Button>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Placeholder
|
||||
v-if="!hasPurchases && !purchasesIsPending"
|
||||
class="!w-full !py-[5rem]"
|
||||
icon="bi:cart"
|
||||
title="خرید یا سفارشی یافت نشد"
|
||||
/>
|
||||
|
||||
<Table v-else>
|
||||
<template #thead>
|
||||
<th
|
||||
v-for="(tableHead, index) in tableHeads"
|
||||
:key="index"
|
||||
scope="col"
|
||||
:class="
|
||||
[0, 1].includes(index)
|
||||
? 'w-3/12'
|
||||
: tableHeads.length - 1 == index
|
||||
? 'w-1/2'
|
||||
: 'w-2/12'
|
||||
"
|
||||
class="px-6 py-5 text-sm font-normal"
|
||||
>
|
||||
{{ tableHead }}
|
||||
</th>
|
||||
</template>
|
||||
<template #tbody>
|
||||
<template v-if="purchasesIsPending">
|
||||
<PurchasesTableRowLoading v-for="i in 5" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<PurchasesTableRow
|
||||
v-for="(purchase, index) in purchases"
|
||||
:key="index"
|
||||
:data="purchase"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</Table>
|
||||
|
||||
<div v-if="data?.count > 10" class="w-full flex-center py-10">
|
||||
<Pagination :items="paginationData" :total="data?.count" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user