Added pretty much everything except discussion forums
This commit is contained in:
125
ui/src/components/modRequests/ModRequestList.vue
Normal file
125
ui/src/components/modRequests/ModRequestList.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import type { DiscussionPost } from '@shared/types/discussion';
|
||||
import type { ModRequest } from '@shared/schemas/modRequest';
|
||||
import type { PagedData, pagination } from '@shared/types/pagination';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import Badge from '@/components/ui/badge/Badge.vue';
|
||||
import { getModRequests } from '@/api/modRequests';
|
||||
import Pagination from '../ui/pagination/Pagination.vue';
|
||||
import PaginationContent from '../ui/pagination/PaginationContent.vue';
|
||||
import PaginationPrevious from '../ui/pagination/PaginationPrevious.vue';
|
||||
import PaginationItem from '../ui/pagination/PaginationItem.vue';
|
||||
import PaginationEllipsis from '../ui/pagination/PaginationEllipsis.vue';
|
||||
import PaginationNext from '../ui/pagination/PaginationNext.vue';
|
||||
import { Lock } from 'lucide-vue-next';
|
||||
|
||||
const requests = ref<DiscussionPost<ModRequest>[]>([]);
|
||||
const loading = ref(true);
|
||||
|
||||
async function loadRequests() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await getModRequests(pageNum.value, pageSize.value);
|
||||
|
||||
requests.value = response.data;
|
||||
pageData.value = response.pagination;
|
||||
} catch (error) {
|
||||
console.error("Failed to load requests:", error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadRequests();
|
||||
});
|
||||
|
||||
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;
|
||||
loadRequests();
|
||||
}
|
||||
|
||||
function setPage(pagenum: number) {
|
||||
pageNum.value = pagenum;
|
||||
loadRequests();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mod-request-list">
|
||||
<Table v-if="!loading">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead class="w-1/2">Title</TableHead>
|
||||
<TableHead class="w-1/4">Creator</TableHead>
|
||||
<TableHead class="w-1/4">Date</TableHead>
|
||||
<TableHead class="w-1/5 text-right">Status</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow v-for="post in requests" :key="post.id"
|
||||
class="hover:bg-muted/50 cursor-pointer transition-colors"
|
||||
@click="$router.push(`/discussions/mod-requests/${post.id}`)">
|
||||
<TableCell class="font-medium">{{ post.title }}</TableCell>
|
||||
<TableCell>{{ post.poster_name }}</TableCell>
|
||||
<TableCell class="text-muted-foreground">{{ new Date(post.created_at).toLocaleDateString() }}
|
||||
</TableCell>
|
||||
<TableCell class="text-right">
|
||||
<Badge :variant="post.is_open ? 'secondary' : 'outline'">
|
||||
{{ post.is_open ? 'Open' : 'Locked' }}
|
||||
<Lock v-if="!post.is_open" />
|
||||
</Badge>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div v-else class="flex items-center justify-center py-12">
|
||||
<p class="text-muted-foreground">Loading requests...</p>
|
||||
</div>
|
||||
<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>
|
||||
</template>
|
||||
Reference in New Issue
Block a user