Merge branch 'main' into database-view-updates
This commit is contained in:
@@ -1,80 +1,11 @@
|
||||
export type ApplicationDto = Partial<{
|
||||
age: number | string
|
||||
name: string
|
||||
playtime: number | string
|
||||
hobbies: string
|
||||
military: boolean
|
||||
communities: string
|
||||
joinReason: string
|
||||
milsimAttraction: string
|
||||
referral: string
|
||||
steamProfile: string
|
||||
timezone: string
|
||||
canAttendSaturday: boolean
|
||||
interests: string
|
||||
aknowledgeRules: boolean
|
||||
}>
|
||||
|
||||
export interface ApplicationData {
|
||||
dob: string;
|
||||
name: string;
|
||||
playtime: number;
|
||||
hobbies: string;
|
||||
military: boolean;
|
||||
communities: string;
|
||||
joinReason: string;
|
||||
milsimAttraction: string;
|
||||
referral: string;
|
||||
steamProfile: string;
|
||||
timezone: string;
|
||||
canAttendSaturday: boolean;
|
||||
interests: string;
|
||||
aknowledgeRules: boolean;
|
||||
}
|
||||
|
||||
//reflects how applications are stored in the database
|
||||
export interface ApplicationRow {
|
||||
id: number;
|
||||
member_id: number;
|
||||
app_version: number;
|
||||
app_data: ApplicationData;
|
||||
|
||||
submitted_at: string; // ISO datetime from DB (e.g., "2025-08-25T18:04:29.000Z")
|
||||
updated_at: string | null;
|
||||
approved_at: string | null;
|
||||
denied_at: string | null;
|
||||
|
||||
app_status: ApplicationStatus; // generated column
|
||||
decision_at: string | null; // generated column
|
||||
|
||||
// present when you join members (e.g., SELECT a.*, m.name AS member_name)
|
||||
member_name: string;
|
||||
}
|
||||
export interface CommentRow {
|
||||
comment_id: number;
|
||||
post_content: string;
|
||||
poster_id: number;
|
||||
post_time: string;
|
||||
last_modified: string | null;
|
||||
poster_name: string;
|
||||
}
|
||||
|
||||
export interface ApplicationFull {
|
||||
application: ApplicationRow;
|
||||
comments: CommentRow[];
|
||||
}
|
||||
import { ApplicationFull } from "@shared/types/application";
|
||||
|
||||
|
||||
export enum ApplicationStatus {
|
||||
Pending = "Pending",
|
||||
Accepted = "Accepted",
|
||||
Denied = "Denied",
|
||||
}
|
||||
// @ts-ignore
|
||||
const addr = import.meta.env.VITE_APIHOST;
|
||||
|
||||
export async function loadApplication(id: number | string): Promise<ApplicationFull | null> {
|
||||
const res = await fetch(`${addr}/application/${id}`, { credentials: 'include' })
|
||||
export async function loadApplication(id: number | string, asAdmin: boolean = false): Promise<ApplicationFull | null> {
|
||||
const res = await fetch(`${addr}/application/${id}?admin=${asAdmin}`, { credentials: 'include' })
|
||||
if (res.status === 204) return null
|
||||
if (!res.ok) throw new Error('Failed to load application')
|
||||
const json = await res.json()
|
||||
@@ -104,6 +35,22 @@ export async function postChatMessage(message: any, post_id: number) {
|
||||
|
||||
const response = await fetch(`${addr}/application/${post_id}/comment`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(out),
|
||||
})
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
export async function postAdminChatMessage(message: any, post_id: number) {
|
||||
const out = {
|
||||
message: message
|
||||
}
|
||||
|
||||
const response = await fetch(`${addr}/application/${post_id}/adminComment`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(out),
|
||||
})
|
||||
@@ -121,8 +68,28 @@ export async function getAllApplications(): Promise<ApplicationFull> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadMyApplications(): Promise<ApplicationFull> {
|
||||
const res = await fetch(`${addr}/application/meList`, { credentials: 'include' })
|
||||
|
||||
if (res.ok) {
|
||||
return res.json()
|
||||
} else {
|
||||
console.error("Something went wrong approving the application")
|
||||
}
|
||||
}
|
||||
|
||||
export async function getMyApplication(id: number): Promise<ApplicationFull> {
|
||||
const res = await fetch(`${addr}/application/me/${id}`, { credentials: 'include' })
|
||||
if (res.status === 204) return null
|
||||
if (res.status === 403) throw new Error("Unauthorized");
|
||||
if (!res.ok) throw new Error('Failed to load application')
|
||||
const json = await res.json()
|
||||
// Accept either the object at root or under `application`
|
||||
return json;
|
||||
}
|
||||
|
||||
export async function approveApplication(id: Number) {
|
||||
const res = await fetch(`${addr}/application/approve/${id}`, { method: 'POST' })
|
||||
const res = await fetch(`${addr}/application/approve/${id}`, { method: 'POST', credentials: 'include' })
|
||||
|
||||
if (!res.ok) {
|
||||
console.error("Something went wrong approving the application")
|
||||
@@ -130,9 +97,36 @@ export async function approveApplication(id: Number) {
|
||||
}
|
||||
|
||||
export async function denyApplication(id: Number) {
|
||||
const res = await fetch(`${addr}/application/deny/${id}`, { method: 'POST' })
|
||||
const res = await fetch(`${addr}/application/deny/${id}`, { method: 'POST', credentials: 'include' })
|
||||
|
||||
if (!res.ok) {
|
||||
console.error("Something went wrong denying the application")
|
||||
}
|
||||
}
|
||||
|
||||
export async function restartApplication() {
|
||||
const res = await fetch(`${addr}/application/restart`, {
|
||||
method: 'POST',
|
||||
credentials: 'include'
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
console.error("Something went wrong restarting your application")
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCoC(): Promise<string> {
|
||||
const res = await fetch(`${addr}/application/coc`, {
|
||||
method: "GET",
|
||||
credentials: 'include',
|
||||
});
|
||||
if (res.ok) {
|
||||
const out = res.json();
|
||||
if (!out) {
|
||||
return null;
|
||||
}
|
||||
return out;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -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,24 @@ export async function submitLOA(request: LOARequest): Promise<{ id?: number; err
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(request),
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return;
|
||||
} else {
|
||||
throw new Error("Failed to submit LOA");
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -26,6 +36,7 @@ export async function submitLOA(request: LOARequest): Promise<{ id?: number; err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function getMyLOA(): Promise<LOARequest | null> {
|
||||
const res = await fetch(`${addr}/loa/me`, {
|
||||
method: "GET",
|
||||
@@ -60,3 +71,84 @@ export function getAllLOAs(): Promise<LOARequest[]> {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getMyLOAs(): Promise<LOARequest[]> {
|
||||
return fetch(`${addr}/loa/history`, {
|
||||
method: "GET",
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then((res) => {
|
||||
if (res.ok) {
|
||||
return res.json();
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
export async function getLoaPolicy(): Promise<string> {
|
||||
const res = await fetch(`${addr}/loa/policy`, {
|
||||
method: "GET",
|
||||
credentials: 'include',
|
||||
});
|
||||
if (res.ok) {
|
||||
const out = res.json();
|
||||
if (!out) {
|
||||
return null;
|
||||
}
|
||||
return out;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function cancelLOA(id: number, admin: boolean = false) {
|
||||
let route = admin ? 'adminCancel' : 'cancel';
|
||||
const res = await fetch(`${addr}/loa/${route}/${id}`, {
|
||||
method: "POST",
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return
|
||||
} else {
|
||||
throw new Error("Could not cancel LOA");
|
||||
}
|
||||
}
|
||||
|
||||
export async function extendLOA(id: number, to: Date) {
|
||||
const res = await fetch(`${addr}/loa/extend/${id}`, {
|
||||
method: "POST",
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ to }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return
|
||||
} else {
|
||||
throw new Error("Could not extend LOA");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user