From 82c9681dfa70404e91666ed318f0f5cafbc9de91 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Mon, 15 Dec 2025 12:23:29 -0500 Subject: [PATCH 1/6] Removed approve/deny buttons from the app list --- ui/src/pages/ManageApplications.vue | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/ui/src/pages/ManageApplications.vue b/ui/src/pages/ManageApplications.vue index bc5a347..d54b48a 100644 --- a/ui/src/pages/ManageApplications.vue +++ b/ui/src/pages/ManageApplications.vue @@ -52,16 +52,6 @@ function formatExact(iso) { return isNaN(d) ? '' : exactFmt.format(d) } -async function handleApprove(id) { - await approveApplication(id); - appList.value = await getAllApplications(); -} - -async function handleDeny(id) { - await denyApplication(id); - appList.value = await getAllApplications(); -} - const router = useRouter(); function openApplication(id) { router.push(`/administration/applications/${id}`) @@ -102,7 +92,7 @@ onMounted(async () => { User - Date Submitted + Date Submitted Status @@ -117,20 +107,10 @@ onMounted(async () => { - + {{ formatAgo(app.submitted_at) }} - - - - - showCoC.value, async () => { Have you ever served in the military?
- + Yes (checked) / No (unchecked)
From a73431f62290f3245eda12d75d7cd732ad34e781 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Mon, 15 Dec 2025 12:47:00 -0500 Subject: [PATCH 3/6] fixed error when opening application from recruiter view when sidepanel is closed --- ui/src/pages/Application.vue | 4 ++-- ui/src/pages/ManageApplications.vue | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/src/pages/Application.vue b/ui/src/pages/Application.vue index 6092ab1..30f944a 100644 --- a/ui/src/pages/Application.vue +++ b/ui/src/pages/Application.vue @@ -105,7 +105,6 @@ async function postApp(appData) { } async function handleApprove(id) { - console.log("hi"); await approveApplication(id); } @@ -164,7 +163,8 @@ async function handleDeny(id) {

Discussion

- +
diff --git a/ui/src/pages/ManageApplications.vue b/ui/src/pages/ManageApplications.vue index d54b48a..907a023 100644 --- a/ui/src/pages/ManageApplications.vue +++ b/ui/src/pages/ManageApplications.vue @@ -11,7 +11,7 @@ import { TableRow, } from '@/components/ui/table' import Button from '@/components/ui/button/Button.vue'; -import { onMounted, ref, watch } from 'vue'; +import { computed, onMounted, ref, watch } from 'vue'; import { useRoute, useRouter } from 'vue-router'; import { CheckIcon, XIcon } from 'lucide-vue-next'; import Application from './Application.vue'; @@ -54,24 +54,24 @@ function formatExact(iso) { const router = useRouter(); function openApplication(id) { + if (!id) return; 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); +// const openPanel = ref(false); +const openPanel = computed(() => route.params.id !== undefined) + onMounted(async () => { appList.value = await getAllApplications(); From 7f98d526345cbe8f32bd45a935b1f14c032b54c5 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Mon, 15 Dec 2025 13:12:48 -0500 Subject: [PATCH 4/6] fixed error on approve/deny applications --- api/src/routes/applications.ts | 19 ++++++------------- api/src/services/applicationService.ts | 21 +++++++++++++-------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/api/src/routes/applications.ts b/api/src/routes/applications.ts index 3c78aeb..6183c2a 100644 --- a/api/src/routes/applications.ts +++ b/api/src/routes/applications.ts @@ -155,21 +155,13 @@ router.post('/approve/:id', [requireLogin, requireRole("Recruiter")], async (req try { const app = await getApplicationByID(appID); - const result = await approveApplication(appID); - - //guard against failures - if (result.affectedRows != 1) { - throw new Error("Something went wrong approving the application"); - } + await approveApplication(appID, approved_by); //update user profile await setUserState(app.member_id, MemberState.Member); await pool.query('CALL sp_accept_new_recruit_validation(?, ?, ?, ?)', [Number(process.env.CONFIG_ID), app.member_id, approved_by, approved_by]) - // let nextRank = await getRankByName('Recruit') - // await insertMemberRank(app.member_id, nextRank.id); - // //assign user to "pending basic" - // await assignUserToStatus(app.member_id, 1); + res.sendStatus(200); } catch (err) { console.error('Approve failed:', err); @@ -178,12 +170,13 @@ router.post('/approve/:id', [requireLogin, requireRole("Recruiter")], async (req }); // POST /application/deny/:id -router.post('/deny/:id', [requireLogin, requireRole("Recruiter")], async (req, res) => { - const appID = req.params.id; +router.post('/deny/:id', [requireLogin, requireRole("Recruiter")], async (req: Request, res: Response) => { + const appID = Number(req.params.id); + const approver = Number(req.user.id); try { const app = await getApplicationByID(appID); - await denyApplication(appID); + await denyApplication(appID, approver); await setUserState(app.member_id, MemberState.Denied); res.sendStatus(200); } catch (err) { diff --git a/api/src/services/applicationService.ts b/api/src/services/applicationService.ts index dceaad3..85615bc 100644 --- a/api/src/services/applicationService.ts +++ b/api/src/services/applicationService.ts @@ -59,30 +59,35 @@ export async function getAllMemberApplications(memberID: number): Promise Date: Mon, 15 Dec 2025 13:14:30 -0500 Subject: [PATCH 5/6] Added visual feedback when application is approved --- ui/src/api/application.ts | 6 ++++-- ui/src/pages/Application.vue | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ui/src/api/application.ts b/ui/src/api/application.ts index f814b15..e6d41bf 100644 --- a/ui/src/api/application.ts +++ b/ui/src/api/application.ts @@ -94,16 +94,18 @@ export async function approveApplication(id: Number) { const res = await fetch(`${addr}/application/approve/${id}`, { method: 'POST', credentials: 'include' }) if (!res.ok) { - console.error("Something went wrong approving the application") + throw new Error("Something went wrong approving the application"); } + return; } export async function denyApplication(id: Number) { const res = await fetch(`${addr}/application/deny/${id}`, { method: 'POST', credentials: 'include' }) if (!res.ok) { - console.error("Something went wrong denying the application") + throw new Error("Something went wrong denyting the application"); } + return; } export async function restartApplication() { diff --git a/ui/src/pages/Application.vue b/ui/src/pages/Application.vue index 30f944a..98e7ff7 100644 --- a/ui/src/pages/Application.vue +++ b/ui/src/pages/Application.vue @@ -105,11 +105,21 @@ async function postApp(appData) { } async function handleApprove(id) { - await approveApplication(id); + try { + await approveApplication(id); + loadData(await loadApplication(Number(route.params.id), true)) + } catch (error) { + console.error(error); + } } async function handleDeny(id) { - await denyApplication(id); + try { + await denyApplication(id); + loadData(await loadApplication(Number(route.params.id), true)) + } catch (error) { + console.error(error); + } } From 1dfdb6bd0e7782d17ecc4c08a4ee39c580e6162e Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Mon, 15 Dec 2025 13:31:04 -0500 Subject: [PATCH 6/6] Tweaked application sorting method Close #79 --- api/src/services/applicationService.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/src/services/applicationService.ts b/api/src/services/applicationService.ts index 85615bc..5692b4c 100644 --- a/api/src/services/applicationService.ts +++ b/api/src/services/applicationService.ts @@ -31,7 +31,7 @@ export async function getApplicationByID(appID: number): Promise return app[0]; } -export async function getApplicationList(): Promise { +export async function getApplicationList(page: number = 1, pageSize: number = 25): Promise { const sql = `SELECT member.name AS member_name, app.id, @@ -40,9 +40,11 @@ export async function getApplicationList(): Promise { app.app_status FROM applications AS app LEFT JOIN members AS member - ON member.id = app.member_id;` + ON member.id = app.member_id + ORDER BY app.submitted_at DESC + LIMIT ? OFFSET ?;` - const rows: ApplicationListRow[] = await pool.query(sql); + const rows: ApplicationListRow[] = await pool.query(sql, [pageSize, page]); return rows; }