overhauled recruiter tools

This commit is contained in:
2025-12-03 15:20:37 -05:00
parent b8f18c060e
commit b79e78c2a6
3 changed files with 106 additions and 42 deletions

View File

@@ -121,7 +121,7 @@ async function handleDeny(id) {
</script> </script>
<template> <template>
<div v-if="!loading" class="max-w-3xl mx-auto"> <div v-if="!loading" class="w-full">
<div v-if="!newApp" class="flex flex-row justify-between items-center py-2 mb-8"> <div v-if="!newApp" class="flex flex-row justify-between items-center py-2 mb-8">
<!-- Application header --> <!-- Application header -->
<div> <div>
@@ -170,5 +170,5 @@ async function handleDeny(id) {
</div> </div>
</div> </div>
<!-- TODO: Implement some kinda loading screen --> <!-- TODO: Implement some kinda loading screen -->
<div v-else>Loading</div> <div v-else class="flex items-center justify-center h-full -mt-40">Loading</div>
</template> </template>

View File

@@ -10,9 +10,10 @@ import {
TableRow, TableRow,
} from '@/components/ui/table' } from '@/components/ui/table'
import Button from '@/components/ui/button/Button.vue'; import Button from '@/components/ui/button/Button.vue';
import { onMounted, ref } from 'vue'; import { onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { CheckIcon, XIcon } from 'lucide-vue-next'; import { CheckIcon, XIcon } from 'lucide-vue-next';
import Application from './Application.vue';
const appList = ref([]); const appList = ref([]);
const now = Date.now(); const now = Date.now();
@@ -61,18 +62,40 @@ async function handleDeny(id) {
const router = useRouter(); const router = useRouter();
function openApplication(id) { function openApplication(id) {
router.push(`./application/${id}`) router.push(`/administration/applications/${id}`)
openPanel.value = true;
} }
function closeApplication() {
router.push('/administration/applications')
openPanel.value = false;
}
const route = useRoute();
watch(() => route.params.id, (newId) => {
if (newId === undefined) {
openPanel.value = false;
}
})
const openPanel = ref(false);
onMounted(async () => { onMounted(async () => {
appList.value = await getAllApplications(); appList.value = await getAllApplications();
//preload application
if (route.params.id != undefined) {
openApplication(route.params.id)
}
}) })
</script> </script>
<template> <template>
<div class="mx-auto w-full max-w-5xl"> <div class="px-20 mx-auto max-w-[100rem] w-full flex mt-5">
<h1 class="my-4">Manage Applications</h1> <!-- application list -->
<div :class="openPanel == false ? 'w-full' : 'w-2/5'" class="pr-9">
<h1 class="scroll-m-20 text-2xl font-semibold tracking-tight">Manage Applications</h1>
<Table> <Table>
<!-- <TableCaption>A list of your recent invoices.</TableCaption> -->
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>User</TableHead> <TableHead>User</TableHead>
@@ -87,7 +110,8 @@ onMounted(async () => {
<TableCell :title="formatExact(app.submitted_at)"> <TableCell :title="formatExact(app.submitted_at)">
{{ formatAgo(app.submitted_at) }} {{ formatAgo(app.submitted_at) }}
</TableCell> </TableCell>
<TableCell v-if="app.app_status === ApplicationStatus.Pending" class="inline-flex items-end gap-2"> <TableCell v-if="app.app_status === ApplicationStatus.Pending"
class="inline-flex items-end gap-2">
<Button variant="success" @click.stop="() => { handleApprove(app.id) }"> <Button variant="success" @click.stop="() => { handleApprove(app.id) }">
<CheckIcon></CheckIcon> <CheckIcon></CheckIcon>
</Button> </Button>
@@ -105,4 +129,44 @@ onMounted(async () => {
</TableBody> </TableBody>
</Table> </Table>
</div> </div>
<div v-if="openPanel" class="pl-9 border-l w-3/5" :key="$route.params.id">
<div class="mb-5 flex justify-between">
<p class="scroll-m-20 text-2xl font-semibold tracking-tight"> Application</p>
<button @click="closeApplication()" class="cursor-pointer">
<XIcon></XIcon>
</button>
</div>
<Application :mode="'view-recruiter'"></Application>
</div>
</div>
</template> </template>
<style scoped>
/* Firefox */
.scrollbar-themed {
scrollbar-width: thin;
scrollbar-color: #555 #1f1f1f;
padding-right: 6px;
}
/* Chrome, Edge, Safari */
.scrollbar-themed::-webkit-scrollbar {
width: 10px;
/* slightly wider to allow padding look */
}
.scrollbar-themed::-webkit-scrollbar-track {
background: #1f1f1f;
margin-left: 6px;
/* ❗ adds space between content + scrollbar */
}
.scrollbar-themed::-webkit-scrollbar-thumb {
background: #555;
border-radius: 9999px;
}
.scrollbar-themed::-webkit-scrollbar-thumb:hover {
background: #777;
}
</style>

View File

@@ -29,7 +29,7 @@ const router = createRouter({
meta: { requiresAuth: true, memberOnly: true, roles: ['staff', 'admin'] }, meta: { requiresAuth: true, memberOnly: true, roles: ['staff', 'admin'] },
children: [ children: [
{ path: 'applications', component: () => import('@/pages/ManageApplications.vue') }, { path: 'applications', component: () => import('@/pages/ManageApplications.vue') },
{ path: 'application/:id', component: () => import('@/pages/Application.vue') }, { path: 'applications/:id', component: () => import('@/pages/ManageApplications.vue') },
{ path: 'rankChange', component: () => import('@/pages/RankChange.vue') }, { path: 'rankChange', component: () => import('@/pages/RankChange.vue') },
{ path: 'applications/:id', component: () => import('@/pages/Application.vue') }, { path: 'applications/:id', component: () => import('@/pages/Application.vue') },
{ path: 'transfer', component: () => import('@/pages/ManageTransfers.vue') }, { path: 'transfer', component: () => import('@/pages/ManageTransfers.vue') },