LOA backend refactor
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
import pool from '../db';
|
||||
|
||||
//post a new LOA
|
||||
router.post("/", async (req, res) => {
|
||||
const { member_id, filed_date, start_date, end_date, reason } = req.body;
|
||||
|
||||
if (!member_id || !filed_date || !start_date || !end_date) {
|
||||
return res.status(400).json({ error: "Missing required fields" });
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`INSERT INTO leave_of_absences
|
||||
(member_id, filed_date, start_date, end_date, reason)
|
||||
VALUES (?, ?, ?, ?, ?)`,
|
||||
[member_id, filed_date, start_date, end_date, reason]
|
||||
);
|
||||
res.sendStatus(201);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send('Something went wrong', error);
|
||||
}
|
||||
});
|
||||
|
||||
//get my current LOA
|
||||
router.get("/me", async (req, res) => {
|
||||
//TODO: implement current user getter
|
||||
const user = 89;
|
||||
|
||||
try {
|
||||
const result = await pool.query("SELECT * FROM leave_of_absences WHERE member_id = ?", [user])
|
||||
res.status(200).json(result)
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send(error);
|
||||
}
|
||||
})
|
||||
|
||||
router.get('/all', async (req, res) => {
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`SELECT loa.*, members.name
|
||||
FROM leave_of_absences AS loa
|
||||
INNER JOIN members ON loa.member_id = members.id;
|
||||
`);
|
||||
res.status(200).json(result)
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send(error);
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router;
|
||||
80
api/src/routes/loa.ts
Normal file
80
api/src/routes/loa.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
import { Request, Response } from 'express';
|
||||
import pool from '../db';
|
||||
import { createNewLOA, getAllLOA, getLoaTypes, getUserLOA } from '../services/loaService';
|
||||
import { LOARequest } from '@app/shared/types/loa';
|
||||
|
||||
//member posts LOA
|
||||
router.post("/", async (req: Request, res: Response) => {
|
||||
let LOARequest = req.body as LOARequest;
|
||||
LOARequest.member_id = req.user.id;
|
||||
LOARequest.created_by = req.user.id;
|
||||
|
||||
console.log(LOARequest);
|
||||
|
||||
try {
|
||||
// const result = await pool.query(
|
||||
// `INSERT INTO leave_of_absences
|
||||
// (member_id, filed_date, start_date, end_date, reason)
|
||||
// VALUES (?, ?, ?, ?, ?)`,
|
||||
// [member_id, filed_date, start_date, end_date, reason]
|
||||
// );
|
||||
await createNewLOA(LOARequest);
|
||||
res.sendStatus(201);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send(error);
|
||||
}
|
||||
});
|
||||
|
||||
//admin posts LOA
|
||||
router.post("/admin", async (req: Request, res: Response) => {
|
||||
let LOARequest = req.body as LOARequest;
|
||||
LOARequest.created_by = req.user.id;
|
||||
|
||||
console.log(LOARequest);
|
||||
|
||||
try {
|
||||
await createNewLOA(LOARequest);
|
||||
res.sendStatus(201);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send(error);
|
||||
}
|
||||
});
|
||||
|
||||
//get my current LOA
|
||||
router.get("/me", async (req: Request, res: Response) => {
|
||||
const user = req.user.id;
|
||||
try {
|
||||
const result = await getUserLOA(user);
|
||||
res.status(200).json(result)
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send(error);
|
||||
}
|
||||
})
|
||||
|
||||
router.get('/all', async (req, res) => {
|
||||
try {
|
||||
const result = await getAllLOA();
|
||||
res.status(200).json(result)
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send(error);
|
||||
}
|
||||
})
|
||||
|
||||
router.get('/types', async (req: Request, res: Response) => {
|
||||
try {
|
||||
let out = await getLoaTypes();
|
||||
res.status(200).json(out);
|
||||
} catch (error) {
|
||||
res.status(500).json(error);
|
||||
console.error(error);
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router;
|
||||
29
api/src/services/loaService.ts
Normal file
29
api/src/services/loaService.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import pool from "../db";
|
||||
import { LOARequest, LOAType } from '@app/shared/types/loa'
|
||||
|
||||
export async function getLoaTypes(): Promise<LOAType[]> {
|
||||
return await pool.query('SELECT * FROM leave_of_absences_types;');
|
||||
}
|
||||
|
||||
export async function getAllLOA(): Promise<LOARequest[]> {
|
||||
let res: LOARequest[] = await pool.query(
|
||||
`SELECT loa.*, members.name, t.name AS type_name
|
||||
FROM leave_of_absences AS loa
|
||||
LEFT JOIN members ON loa.member_id = members.id
|
||||
LEFT JOIN leave_of_absences_types AS t ON loa.type_id = t.id;
|
||||
`) as LOARequest[];
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function getUserLOA(userId: number): Promise<LOARequest[]> {
|
||||
const result: LOARequest[] = await pool.query("SELECT * FROM leave_of_absences WHERE member_id = ?", [userId])
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function createNewLOA(data: LOARequest) {
|
||||
const sql = `INSERT INTO leave_of_absences
|
||||
(member_id, filed_date, start_date, end_date, type_id, reason)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`;
|
||||
await pool.query(sql, [data.member_id, data.filed_date, data.start_date, data.end_date, data.type_id, data.reason])
|
||||
return;
|
||||
}
|
||||
24
shared/types/loa.ts
Normal file
24
shared/types/loa.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export interface LOARequest {
|
||||
id?: number;
|
||||
member_id?: number;
|
||||
filed_date?: string; // ISO 8601 string
|
||||
start_date: string; // ISO 8601 string
|
||||
end_date: string; // ISO 8601 string
|
||||
extended_till?: string;
|
||||
type_id?: number;
|
||||
reason?: string;
|
||||
expired?: boolean;
|
||||
closed?: boolean;
|
||||
closed_by?: number;
|
||||
created_by?: number;
|
||||
|
||||
name?: string; //member name
|
||||
type_name?: string;
|
||||
};
|
||||
|
||||
export interface LOAType {
|
||||
id: number;
|
||||
name: string;
|
||||
max_length_days: number;
|
||||
extendable: boolean;
|
||||
}
|
||||
@@ -1,12 +1,4 @@
|
||||
export type LOARequest = {
|
||||
id?: number;
|
||||
name?: string;
|
||||
member_id: number;
|
||||
filed_date: string; // ISO 8601 string
|
||||
start_date: string; // ISO 8601 string
|
||||
end_date: string; // ISO 8601 string
|
||||
reason?: string;
|
||||
};
|
||||
import { LOARequest, LOAType } from '@shared/types/loa'
|
||||
// @ts-ignore
|
||||
const addr = import.meta.env.VITE_APIHOST;
|
||||
|
||||
@@ -17,6 +9,7 @@ export async function submitLOA(request: LOARequest): Promise<{ id?: number; err
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
@@ -26,6 +19,24 @@ export async function submitLOA(request: LOARequest): Promise<{ id?: number; err
|
||||
}
|
||||
}
|
||||
|
||||
export async function adminSubmitLOA(request: LOARequest): Promise<{ id?: number; error?: string }> {
|
||||
const res = await fetch(`${addr}/loa/admin`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return res.json();
|
||||
} else {
|
||||
return { error: "Failed to submit LOA" };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function getMyLOA(): Promise<LOARequest | null> {
|
||||
const res = await fetch(`${addr}/loa/me`, {
|
||||
method: "GET",
|
||||
@@ -60,3 +71,20 @@ export function getAllLOAs(): Promise<LOARequest[]> {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function getLoaTypes(): Promise<LOAType[]> {
|
||||
const res = await fetch(`${addr}/loa/types`, {
|
||||
method: "GET",
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const out = res.json();
|
||||
if (!out) {
|
||||
return null;
|
||||
}
|
||||
return out;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,8 @@ import { RangeCalendar } from "@/components/ui/range-calendar"
|
||||
import { cn } from "@/lib/utils";
|
||||
import { CalendarIcon } from "lucide-vue-next"
|
||||
import Textarea from "@/components/ui/textarea/Textarea.vue";
|
||||
import { LOARequest, submitLOA } from "@/api/loa"; // <-- import the submit function
|
||||
import { submitLOA } from "@/api/loa"; // <-- import the submit function
|
||||
import { LOARequest } from "@shared/types/loa";
|
||||
|
||||
const members = ref<Member[]>([])
|
||||
const currentMember = ref<Member | null>(null);
|
||||
|
||||
Reference in New Issue
Block a user