switch to another frontend framework wheeeeeeeeeeee
This commit is contained in:
parent
fa3c1ccaa7
commit
c4adf6918c
58 changed files with 6246 additions and 1703 deletions
28
Foxnouns.Frontend/app/lib/api/error.ts
Normal file
28
Foxnouns.Frontend/app/lib/api/error.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export type ApiError = {
|
||||
status: number;
|
||||
message: string;
|
||||
code: ErrorCode;
|
||||
errors?: ValidationError[];
|
||||
};
|
||||
|
||||
export enum ErrorCode {
|
||||
InternalServerError = "INTERNAL_SERVER_ERROR",
|
||||
Forbidden = "FORBIDDEN",
|
||||
BadRequest = "BAD_REQUEST",
|
||||
AuthenticationError = "AUTHENTICATION_ERROR",
|
||||
AuthenticationRequired = "AUTHENTICATION_REQUIRED",
|
||||
MissingScopes = "MISSING_SCOPES",
|
||||
GenericApiError = "GENERIC_API_ERROR",
|
||||
UserNotFound = "USER_NOT_FOUND",
|
||||
MemberNotFound = "MEMBER_NOT_FOUND",
|
||||
}
|
||||
|
||||
export type ValidationError = {
|
||||
message: string;
|
||||
min_length?: number;
|
||||
max_length?: number;
|
||||
actual_length?: number;
|
||||
allowed_values?: any[];
|
||||
actual_value?: any;
|
||||
};
|
11
Foxnouns.Frontend/app/lib/api/meta.ts
Normal file
11
Foxnouns.Frontend/app/lib/api/meta.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
export default interface Meta {
|
||||
version: string;
|
||||
hash: string;
|
||||
users: {
|
||||
total: number;
|
||||
active_month: number;
|
||||
active_week: number;
|
||||
active_day: number;
|
||||
};
|
||||
members: number;
|
||||
}
|
13
Foxnouns.Frontend/app/lib/api/user.ts
Normal file
13
Foxnouns.Frontend/app/lib/api/user.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
export type User = {
|
||||
id: string;
|
||||
username: string;
|
||||
display_name: string | null;
|
||||
bio: string | null;
|
||||
member_title: string | null;
|
||||
avatar_url: string | null;
|
||||
links: string[];
|
||||
};
|
||||
|
||||
export type UserSettings = {
|
||||
dark_mode: boolean | null;
|
||||
};
|
66
Foxnouns.Frontend/app/lib/request.server.ts
Normal file
66
Foxnouns.Frontend/app/lib/request.server.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { parse as parseCookie, serialize as serializeCookie } from "cookie";
|
||||
import { API_BASE } from "~/env.server";
|
||||
import { ApiError, ErrorCode } from "./api/error";
|
||||
|
||||
export type RequestParams = {
|
||||
token?: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
body?: any;
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
|
||||
export default async function serverRequest<T>(
|
||||
method: string,
|
||||
path: string,
|
||||
params: RequestParams = {},
|
||||
) {
|
||||
const url = `${API_BASE}/v2${path}`;
|
||||
const resp = await fetch(url, {
|
||||
method,
|
||||
body: params.body ? JSON.stringify(params.body) : undefined,
|
||||
headers: {
|
||||
...params.headers,
|
||||
...(params.token ? { Authorization: params.token } : {}),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (resp.headers.get("Content-Type")?.indexOf("application/json") === -1) {
|
||||
// If we don't get a JSON response, the server almost certainly encountered an internal error it couldn't recover from
|
||||
// (that, or the reverse proxy, which should also be treated as a 500 error)
|
||||
throw {
|
||||
status: 500,
|
||||
code: ErrorCode.InternalServerError,
|
||||
message: "Internal server error",
|
||||
} as ApiError;
|
||||
}
|
||||
|
||||
if (resp.status < 200 || resp.status >= 400)
|
||||
throw (await resp.json()) as ApiError;
|
||||
return (await resp.json()) as T;
|
||||
}
|
||||
|
||||
export function getCookie(
|
||||
req: Request,
|
||||
cookieName: string,
|
||||
): string | undefined {
|
||||
const header = req.headers.get("Cookie");
|
||||
if (!header) return undefined;
|
||||
|
||||
const cookie = parseCookie(header);
|
||||
return cookieName in cookie ? cookie[cookieName] : undefined;
|
||||
}
|
||||
|
||||
const YEAR = 365 * 86400;
|
||||
|
||||
export const writeCookie = (
|
||||
cookieName: string,
|
||||
value: string,
|
||||
maxAge: number | undefined = YEAR,
|
||||
) =>
|
||||
serializeCookie(cookieName, value, {
|
||||
maxAge,
|
||||
path: "/",
|
||||
sameSite: "lax",
|
||||
httpOnly: true,
|
||||
});
|
23
Foxnouns.Frontend/app/lib/settings.server.ts
Normal file
23
Foxnouns.Frontend/app/lib/settings.server.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { UserSettings } from "./api/user";
|
||||
import { getCookie } from "./request.server";
|
||||
|
||||
export default function getLocalSettings(req: Request): UserSettings {
|
||||
const settings = { dark_mode: null } as UserSettings;
|
||||
const theme = getCookie(req, "pronounscc-theme");
|
||||
|
||||
switch (theme) {
|
||||
case "auto":
|
||||
settings.dark_mode = null;
|
||||
break;
|
||||
case "light":
|
||||
settings.dark_mode = false;
|
||||
break;
|
||||
case "dark":
|
||||
settings.dark_mode = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue