Began implementation for getting promotion history
This commit is contained in:
175
ui/src/components/promotions/promotionList.vue
Normal file
175
ui/src/components/promotions/promotionList.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<script setup lang="ts">
|
||||
import { pagination } from '@shared/types/pagination';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const expanded = ref<number | null>(null);
|
||||
const hoverID = ref<number | null>(null);
|
||||
|
||||
const pageNum = ref<number>(1);
|
||||
const pageData = ref<pagination>();
|
||||
|
||||
const pageSize = ref<number>(15)
|
||||
const pageSizeOptions = [10, 15, 30]
|
||||
|
||||
function setPageSize(size: number) {
|
||||
pageSize.value = size
|
||||
pageNum.value = 1;
|
||||
// loadLOAs();
|
||||
}
|
||||
|
||||
function setPage(pagenum: number) {
|
||||
pageNum.value = pagenum;
|
||||
// loadLOAs();
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<Dialog :open="isExtending" @update:open="(val) => isExtending = val">
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Extend {{ targetLOA.name }}'s Leave of Absence </DialogTitle>
|
||||
</DialogHeader>
|
||||
<div class="flex gap-5">
|
||||
<Calendar v-model="extendTo" class="rounded-md border shadow-sm w-min" layout="month-and-year"
|
||||
:min-value="toCalendarDate(targetEnd)"
|
||||
:max-value="toCalendarDate(targetEnd).add({ years: 1 })" />
|
||||
<div class="flex flex-col w-full gap-3 px-2">
|
||||
<p>Quick Options</p>
|
||||
<Button variant="outline" @click="extendTo = toCalendarDate(targetEnd).add({ days: 7 })">1
|
||||
Week</Button>
|
||||
<Button variant="outline" @click="extendTo = toCalendarDate(targetEnd).add({ months: 1 })">1
|
||||
Month</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4">
|
||||
<Button variant="outline" @click="isExtending = false">Cancel</Button>
|
||||
<Button @click="commitExtend">Extend</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<div class="max-w-7xl w-full mx-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Member</TableHead>
|
||||
<TableHead>Type</TableHead>
|
||||
<TableHead>Start</TableHead>
|
||||
<TableHead>End</TableHead>
|
||||
<!-- <TableHead class="w-[500px]">Reason</TableHead> -->
|
||||
<TableHead>Posted on</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<template v-for="post in LOAList" :key="post.id">
|
||||
<TableRow class="hover:bg-muted/50 cursor-pointer" @click="expanded = post.id"
|
||||
@mouseenter="hoverID = post.id" @mouseleave="hoverID = null" :class="{
|
||||
'border-b-0': expanded === post.id,
|
||||
'bg-muted/50': hoverID === post.id
|
||||
}">
|
||||
<TableCell class="font-medium">
|
||||
<MemberCard :member-id="post.member_id"></MemberCard>
|
||||
</TableCell>
|
||||
<TableCell>{{ post.type_name }}</TableCell>
|
||||
<TableCell>{{ formatDate(post.start_date) }}</TableCell>
|
||||
<TableCell>{{ post.extended_till ? formatDate(post.extended_till) :
|
||||
formatDate(post.end_date) }}
|
||||
</TableCell>
|
||||
<!-- <TableCell>{{ post.reason }}</TableCell> -->
|
||||
<TableCell>{{ formatDate(post.filed_date) }}</TableCell>
|
||||
<TableCell>
|
||||
<Badge v-if="loaStatus(post) === 'Upcoming'" class="bg-blue-400">Upcoming</Badge>
|
||||
<Badge v-else-if="loaStatus(post) === 'Active'" class="bg-green-500">Active</Badge>
|
||||
<Badge v-else-if="loaStatus(post) === 'Overdue'" class="bg-yellow-400">Overdue</Badge>
|
||||
<Badge v-else class="bg-gray-400">Ended</Badge>
|
||||
</TableCell>
|
||||
<TableCell @click.stop="" class="text-right">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="cursor-pointer">
|
||||
<Button variant="ghost">
|
||||
<Ellipsis class="size-6"></Ellipsis>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem v-if="!post.closed && props.adminMode"
|
||||
@click="isExtending = true; targetLOA = post">
|
||||
Extend
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem v-if="!post.closed" :variant="'destructive'"
|
||||
@click="cancelAndReload(post.id)">{{ loaStatus(post) === 'Upcoming' ?
|
||||
'Cancel' :
|
||||
'End' }}
|
||||
</DropdownMenuItem>
|
||||
<!-- Fallback: no actions available -->
|
||||
<p v-if="post.closed || (!props.adminMode && post.closed)"
|
||||
class="p-2 text-center text-sm">
|
||||
No actions
|
||||
</p>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Button v-if="expanded === post.id" @click.stop="expanded = null" variant="ghost">
|
||||
<ChevronUp class="size-6" />
|
||||
</Button>
|
||||
<Button v-else @click.stop="expanded = post.id" variant="ghost">
|
||||
<ChevronDown class="size-6" />
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow v-if="expanded === post.id" @mouseenter="hoverID = post.id"
|
||||
@mouseleave="hoverID = null" :class="{ 'bg-muted/50 border-t-0': hoverID === post.id }">
|
||||
<TableCell :colspan="8" class="p-0">
|
||||
<div class="w-full p-3 mb-6 space-y-3">
|
||||
<div class="flex justify-between items-start gap-4">
|
||||
<div class="flex-1">
|
||||
<!-- Title -->
|
||||
<p class="text-md font-semibold text-foreground">
|
||||
Reason
|
||||
</p>
|
||||
|
||||
<!-- Content -->
|
||||
<p
|
||||
class="mt-1 text-md whitespace-pre-wrap leading-relaxed text-muted-foreground">
|
||||
{{ post.reason }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
</template>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div class="mt-5 flex justify-between">
|
||||
<div></div>
|
||||
<Pagination v-slot="{ page }" :items-per-page="pageData?.pageSize || 10" :total="pageData?.total || 10"
|
||||
:default-page="2" :page="pageNum" @update:page="setPage">
|
||||
<PaginationContent v-slot="{ items }">
|
||||
<PaginationPrevious />
|
||||
<template v-for="(item, index) in items" :key="index">
|
||||
<PaginationItem v-if="item.type === 'page'" :value="item.value"
|
||||
:is-active="item.value === page">
|
||||
{{ item.value }}
|
||||
</PaginationItem>
|
||||
</template>
|
||||
<PaginationEllipsis :index="4" />
|
||||
<PaginationNext />
|
||||
</PaginationContent>
|
||||
</Pagination>
|
||||
<div class="flex items-center gap-3 text-sm">
|
||||
<p class="text-muted-foreground text-nowrap">Per page:</p>
|
||||
|
||||
<button v-for="size in pageSizeOptions" :key="size" @click="setPageSize(size)"
|
||||
class="px-2 py-1 rounded transition-colors" :class="{
|
||||
'bg-muted font-semibold': pageSize === size,
|
||||
'hover:bg-muted/50': pageSize !== size
|
||||
}">
|
||||
{{ size }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user