Files
hossein-por-shop/frontend/pages/profile/tickets/index.vue
T
2025-02-27 20:50:28 +03:30

211 lines
7.7 KiB
Vue

<script setup lang="ts">
// imports
import useGetAllTickets, {
type GetAllTicketsFilters,
} from "~/composables/api/tickets/useGetAllTickets";
// meta
definePageMeta({
middleware: "check-is-logged-in",
layout: "profile",
});
// state
const params: GetAllTicketsFilters = 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",
},
]);
const statusFilters = ref([
{
title: "پاسخ داده شده",
value: "resolved",
},
{
title: "در حال پردازش",
value: "in_progress",
},
{
title: "بسته شده",
value: "closed",
},
]);
// provide / inject
provide("params", params);
// queries
const { data, isPending: ticketsIsPending } = useGetAllTickets(filters);
// computed
const tickets = computed(() => {
return data.value?.results.flat();
});
const hasTickets = computed(() => data.value?.count > 0);
const paginationData = computed(() => {
return data.value?.results.map((_, i: number) => {
return { type: "page", value: i };
});
});
</script>
<template>
<div class="w-full flex flex-col gap-5">
<ProfilePageTitle title="تیکت های شما" icon="bi:ticket" />
<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>
<NuxtLink :to="{ name: 'profile-tickets-new' }">
<Button end-icon="bi:plus" size="md" class="rounded-full">
<span class="font-bold whitespace-pre">
تیکت جدید
</span>
</Button>
</NuxtLink>
</div>
<Placeholder
v-if="!hasTickets && !ticketsIsPending"
class="!w-full !py-[5rem]"
icon="bi:ticket"
title="تیکتی یافت نشد"
/>
<Table v-else>
<template #thead>
<th
v-for="(tableHead, index) in tableHeads"
:key="index"
scope="col"
:class="
[0, 1, 2].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="ticketsIsPending">
<TicketsTableRowLoading v-for="i in 5" />
</template>
<template v-else>
<TicketsTableRow
v-for="(ticket, index) in tickets"
:key="index"
:data="ticket"
/>
</template>
</template>
</Table>
<div v-if="data?.count > 7" class="w-full flex-center py-10">
<Pagination :items="paginationData" :total="data?.count" />
</div>
</div>
</div>
</template>
<style scoped></style>