Improve code quality with the help of Biome
This commit is contained in:
17 files changed
+125
-59
No files matched your search
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
|
||||
"css": {
|
||||
"parser": {
|
||||
"tailwindDirectives": true
|
||||
}
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ErrorBoundary, type JSX } from "solid-js";
|
||||
import { t } from "../lib/i18n";
|
||||
import { AppError } from "../types/api";
|
||||
import Error from "./Error";
|
||||
import ErrorComponent from "./ErrorComponent";
|
||||
|
||||
export default function AppErrorBoundaryComponent(props: {
|
||||
children: JSX.Element;
|
||||
@@ -10,7 +10,7 @@ export default function AppErrorBoundaryComponent(props: {
|
||||
return (
|
||||
<ErrorBoundary
|
||||
fallback={(e, reset) => {
|
||||
let text;
|
||||
let text: string;
|
||||
let canReset = true;
|
||||
if (e instanceof TypeError) {
|
||||
text = t("error.networkError");
|
||||
@@ -26,7 +26,7 @@ export default function AppErrorBoundaryComponent(props: {
|
||||
}
|
||||
|
||||
return (
|
||||
<Error
|
||||
<ErrorComponent
|
||||
text={text}
|
||||
fillScreen={true}
|
||||
reset={canReset ? reset : undefined}
|
||||
|
||||
@@ -107,24 +107,25 @@ function App(props: ParentProps) {
|
||||
<Show when={user()}>
|
||||
{(u) => (
|
||||
<li class="dropdown dropdown-top dropdown-center w-full">
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
class="flex flex-row items-center gap-2 max-w-full"
|
||||
>
|
||||
<img
|
||||
src={u()["picture"]}
|
||||
alt="Picture"
|
||||
alt={u().name}
|
||||
class="w-6 h-6 rounded"
|
||||
></img>
|
||||
<span class="truncate max-w-xs">{u()["name"]}</span>
|
||||
</div>
|
||||
<span class="truncate max-w-xs">{u().name}</span>
|
||||
</button>
|
||||
<ul
|
||||
tabindex="-1"
|
||||
class="dropdown-content menu bg-base-100 rounded-box z-1 w-full p-2 shadow-sm"
|
||||
>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
(window.location.href = `${BASE_URL}/logout`)
|
||||
}
|
||||
|
||||
@@ -23,12 +23,20 @@ export default function ErrorComponent({
|
||||
<div class="flex flex-row gap-2">
|
||||
<Show when={reset}>
|
||||
{(reset) => (
|
||||
<button onClick={() => reset()()} class="btn btn-soft mt-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => reset()()}
|
||||
class="btn btn-soft mt-4"
|
||||
>
|
||||
{t("panel.tryAgain")}
|
||||
</button>
|
||||
)}
|
||||
</Show>
|
||||
<button onClick={() => navigate(-1)} class="btn btn-soft mt-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate(-1)}
|
||||
class="btn btn-soft mt-4"
|
||||
>
|
||||
{t("panel.goBack")}
|
||||
</button>
|
||||
</div>
|
||||
@@ -11,8 +11,11 @@ export default function RolePickerComponent({
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<label class="label">{t("panel.users.role")}</label>
|
||||
<label for="role" class="label">
|
||||
{t("panel.users.role")}
|
||||
</label>
|
||||
<select
|
||||
id="role"
|
||||
value={role() ?? ""}
|
||||
onChange={(e) => setRole(e.target.value as Role)}
|
||||
class="select w-full"
|
||||
|
||||
@@ -15,7 +15,7 @@ export default function TotpComponent({
|
||||
const [fatalError, setFatalError] = createSignal<Error | null>(null);
|
||||
|
||||
async function submit() {
|
||||
let redirectUrl;
|
||||
let redirectUrl: string;
|
||||
try {
|
||||
redirectUrl = await loginApi.totp(code(), rememberMe(), loginChallenge);
|
||||
} catch (err) {
|
||||
@@ -30,7 +30,7 @@ export default function TotpComponent({
|
||||
setError(err.message);
|
||||
return;
|
||||
}
|
||||
window.location.href = redirectUrl!;
|
||||
window.location.href = redirectUrl;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -47,8 +47,11 @@ export default function TotpComponent({
|
||||
}}
|
||||
>
|
||||
<fieldset class="fieldset">
|
||||
<label class="label">{t("totp.code")}</label>
|
||||
<label for="code" class="label">
|
||||
{t("totp.code")}
|
||||
</label>
|
||||
<input
|
||||
id="code"
|
||||
type="text"
|
||||
class="input validator w-full"
|
||||
placeholder={t("totp.code")}
|
||||
|
||||
@@ -64,6 +64,7 @@ export const dict = {
|
||||
glitchtip: "Glitchtip",
|
||||
roundcube: "Roundcube",
|
||||
},
|
||||
icon: "icon",
|
||||
},
|
||||
tryAgain: "Try again",
|
||||
goBack: "Go back",
|
||||
|
||||
+2
-2
@@ -28,8 +28,8 @@ export const consentApi = {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
consent: consent,
|
||||
consentChallenge: consentChallenge,
|
||||
consent,
|
||||
consentChallenge,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
+2
-2
@@ -38,12 +38,12 @@ export const inviteApi = {
|
||||
return await response.json();
|
||||
},
|
||||
|
||||
create: async (userData: CreateInviteData): Promise<InviteData> => {
|
||||
create: async (inviteData: CreateInviteData): Promise<InviteData> => {
|
||||
const response = await fetch(`${BASE_URL}/invite`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(userData),
|
||||
body: JSON.stringify(inviteData),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
+5
-5
@@ -29,7 +29,7 @@ export const loginApi = {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
...credentials,
|
||||
loginChallenge: loginChallenge,
|
||||
loginChallenge,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ export const loginApi = {
|
||||
const response = await fetch(`${BASE_URL}/login/minecraftcheck`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ loginChallenge: loginChallenge }),
|
||||
body: JSON.stringify({ loginChallenge }),
|
||||
});
|
||||
|
||||
if (!response.ok)
|
||||
@@ -67,9 +67,9 @@ export const loginApi = {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
code: code,
|
||||
rememberMe: rememberMe,
|
||||
loginChallenge: loginChallenge,
|
||||
code,
|
||||
rememberMe,
|
||||
loginChallenge,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
+4
-4
@@ -28,7 +28,7 @@ export const setupApi = {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
...details,
|
||||
token: token,
|
||||
token,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ export const setupApi = {
|
||||
const response = await fetch(`${BASE_URL}/setup/minecraftcheck`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ token: token }),
|
||||
body: JSON.stringify({ token }),
|
||||
});
|
||||
|
||||
if (!response.ok)
|
||||
@@ -58,7 +58,7 @@ export const setupApi = {
|
||||
const response = await fetch(`${BASE_URL}/setup/totpsetup`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ token: token }),
|
||||
body: JSON.stringify({ token }),
|
||||
});
|
||||
|
||||
if (!response.ok)
|
||||
@@ -73,7 +73,7 @@ export const setupApi = {
|
||||
const response = await fetch(`${BASE_URL}/setup/totpverify`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ code: code, token: token }),
|
||||
body: JSON.stringify({ code, token }),
|
||||
});
|
||||
|
||||
if (!response.ok)
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function ConsentPage() {
|
||||
|
||||
async function consent(consent: boolean, consentChallenge: string) {
|
||||
const redirectUrl = await consentApi.consent(consent, consentChallenge);
|
||||
window.location.href = redirectUrl!;
|
||||
window.location.href = redirectUrl;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -37,7 +37,7 @@ export default function ConsentPage() {
|
||||
<div class="flex min-h-screen items-center justify-center">
|
||||
<div class="card bg-base-200 border-2 border-base-300 w-full max-w-md shrink-0 shadow-2xl">
|
||||
<div class="card-body">
|
||||
<img src="/logo.webp"></img>
|
||||
<img src="/logo.webp" alt="TrueOG"></img>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<h1 class="text-2xl font-bold">{t("consent.title")}</h1>
|
||||
|
||||
@@ -50,15 +50,15 @@ export default function ConsentPage() {
|
||||
<For each={consentData()?.scopes}>
|
||||
{(scope) => (
|
||||
<li>
|
||||
{scopeMap.has(scope)
|
||||
? scopeMap.get(scope)!()
|
||||
: t("consent.scopes.default", { scope: scope })}
|
||||
{scopeMap.get(scope)?.() ??
|
||||
t("consent.scopes.default", { scope })}
|
||||
</li>
|
||||
)}
|
||||
</For>
|
||||
</ul>
|
||||
<div class="w-full py-2 flex flex-col gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
consent(true, params.consent_challenge as string)
|
||||
}
|
||||
@@ -67,6 +67,7 @@ export default function ConsentPage() {
|
||||
{t("consent.allow")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
consent(false, params.consent_challenge as string)
|
||||
}
|
||||
|
||||
+5
-1
@@ -57,7 +57,11 @@ export default function HomePage() {
|
||||
<a href={app.link} target="_blank" rel="noopener noreferrer">
|
||||
<div class="card bg-base-200 hover:bg-base-300 transition-colors border-2 border-base-300 shadow-2xl">
|
||||
<div class="card-body flex items-center justify-center">
|
||||
<img class="w-44 h-44" src={app.icon}></img>
|
||||
<img
|
||||
class="w-44 h-44"
|
||||
src={app.icon}
|
||||
alt={`${app.name} ${t("panel.home.icon")}`}
|
||||
></img>
|
||||
<h2 class="card-title">{app.name}</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+21
-9
@@ -30,6 +30,7 @@ function InviteRow({ invite }: { invite: InviteData }) {
|
||||
}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-ghost"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(link);
|
||||
@@ -56,6 +57,7 @@ function InviteRow({ invite }: { invite: InviteData }) {
|
||||
</td>
|
||||
<th>
|
||||
<button
|
||||
type="button"
|
||||
onClick={async () => {
|
||||
setDeleting(true);
|
||||
await inviteApi.delete(invite.id.toString());
|
||||
@@ -101,7 +103,7 @@ export default function InvitesPage() {
|
||||
const [userId, setUserId] = createSignal<string>();
|
||||
const [fatalError, setFatalError] = createSignal<Error | null>(null);
|
||||
|
||||
let modalRef: HTMLDialogElement;
|
||||
let modalRef!: HTMLDialogElement;
|
||||
|
||||
async function create() {
|
||||
setError(null);
|
||||
@@ -109,9 +111,9 @@ export default function InvitesPage() {
|
||||
setUpdating(true);
|
||||
try {
|
||||
await inviteApi.create({
|
||||
invitedUserId: userId()!,
|
||||
invitedUserId: userId() as string,
|
||||
});
|
||||
modalRef!.close();
|
||||
modalRef.close();
|
||||
revalidate("invites");
|
||||
} catch (err) {
|
||||
if (!(err instanceof AppError)) {
|
||||
@@ -134,7 +136,11 @@ export default function InvitesPage() {
|
||||
<section class="p-8">
|
||||
<div class="flex justify-between">
|
||||
<h1 class="text-2xl font-bold mb-4">{t("panel.invites.title")}</h1>
|
||||
<button onClick={() => modalRef!.showModal()} class="btn btn-soft">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => modalRef.showModal()}
|
||||
class="btn btn-soft"
|
||||
>
|
||||
<FiPlus class="text-lg" />
|
||||
{t("panel.invites.createNew")}
|
||||
</button>
|
||||
@@ -157,18 +163,21 @@ export default function InvitesPage() {
|
||||
|
||||
<dialog
|
||||
onTransitionEnd={(e) => {
|
||||
if (e.propertyName === "opacity" && !modalRef!.open) {
|
||||
if (e.propertyName === "opacity" && !modalRef.open) {
|
||||
setUserId(undefined);
|
||||
setError(null);
|
||||
}
|
||||
}}
|
||||
ref={modalRef!}
|
||||
ref={modalRef}
|
||||
id="create_invite_modal"
|
||||
class="modal"
|
||||
>
|
||||
<div class="modal-box">
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
|
||||
>
|
||||
<FiX class="text-lg" />
|
||||
</button>
|
||||
</form>
|
||||
@@ -181,8 +190,11 @@ export default function InvitesPage() {
|
||||
}}
|
||||
>
|
||||
<fieldset class="fieldset">
|
||||
<label class="label">{t("panel.invites.user")}</label>
|
||||
<label for="user" class="label">
|
||||
{t("panel.invites.user")}
|
||||
</label>
|
||||
<select
|
||||
id="user"
|
||||
value={userId() ?? ""}
|
||||
onChange={(e) => setUserId(e.target.value as string)}
|
||||
class="select w-full"
|
||||
@@ -207,7 +219,7 @@ export default function InvitesPage() {
|
||||
</form>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>Close</button>
|
||||
<button type="button">Close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
</>
|
||||
|
||||
+2
-2
@@ -23,14 +23,14 @@ export default function LoginPage() {
|
||||
const data = loginData();
|
||||
if (!data) return;
|
||||
if (data.skip) {
|
||||
window.location.href = data.redirectUri!;
|
||||
window.location.href = data.redirectUri as string;
|
||||
}
|
||||
});
|
||||
|
||||
const stage = createMemo(() => {
|
||||
const data = loginData();
|
||||
if (!data || data.skip) return;
|
||||
const stage = getStage(data.currentStage!);
|
||||
const stage = getStage(data.currentStage as string);
|
||||
if (stage instanceof AppError) throw stage;
|
||||
return stage;
|
||||
});
|
||||
|
||||
+19
-4
@@ -145,7 +145,11 @@ function User() {
|
||||
|
||||
<div class="flex flex-col w-full xl:w-1/2">
|
||||
<div class="flex flex-row items-center mb-4">
|
||||
<button onClick={() => navigate(-1)} class="btn btn-ghost mr-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate(-1)}
|
||||
class="btn btn-ghost mr-2"
|
||||
>
|
||||
<FiChevronLeft class="text-2xl" />
|
||||
</button>
|
||||
<img
|
||||
@@ -163,8 +167,11 @@ function User() {
|
||||
}}
|
||||
>
|
||||
<fieldset class="fieldset">
|
||||
<label class="label">{t("panel.users.email")}</label>
|
||||
<label for="email" class="label">
|
||||
{t("panel.users.email")}
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="text"
|
||||
class="input w-full"
|
||||
placeholder={t("panel.users.email")}
|
||||
@@ -173,8 +180,11 @@ function User() {
|
||||
required
|
||||
/>
|
||||
|
||||
<label class="label">{t("panel.users.minecraftUuid")}</label>
|
||||
<label for="minecraftUuid" class="label">
|
||||
{t("panel.users.minecraftUuid")}
|
||||
</label>
|
||||
<input
|
||||
id="minecraftUuid"
|
||||
type="text"
|
||||
class="input validator w-full"
|
||||
placeholder={t("panel.users.minecraftUuid")}
|
||||
@@ -199,8 +209,11 @@ function User() {
|
||||
<RolePicker role={role} setRole={setRole} />
|
||||
</div>
|
||||
|
||||
<label class="label">{t("panel.users.setUp")}</label>
|
||||
<label for="setUp" class="label">
|
||||
{t("panel.users.setUp")}
|
||||
</label>
|
||||
<input
|
||||
id="setUp"
|
||||
type="text"
|
||||
class="input w-full"
|
||||
placeholder={t("panel.users.setUp")}
|
||||
@@ -232,6 +245,7 @@ function User() {
|
||||
}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const deactivated = user()?.deactivated;
|
||||
if (deactivated === undefined) return;
|
||||
@@ -257,6 +271,7 @@ function User() {
|
||||
}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={deleteUser}
|
||||
class="btn btn-error w-full"
|
||||
disabled={
|
||||
|
||||
+24
-11
@@ -72,7 +72,7 @@ export default function UsersPage() {
|
||||
const [role, setRole] = createSignal<Role>();
|
||||
const [fatalError, setFatalError] = createSignal<Error | null>(null);
|
||||
|
||||
let modalRef: HTMLDialogElement;
|
||||
let modalRef!: HTMLDialogElement;
|
||||
|
||||
async function create() {
|
||||
setError(null);
|
||||
@@ -81,10 +81,10 @@ export default function UsersPage() {
|
||||
try {
|
||||
await userApi.create({
|
||||
email: email(),
|
||||
role: role()!,
|
||||
minecraftUuid: minecraftUuid()!,
|
||||
role: role() as Role,
|
||||
minecraftUuid: minecraftUuid(),
|
||||
});
|
||||
modalRef!.close();
|
||||
modalRef.close();
|
||||
revalidate("users");
|
||||
} catch (err) {
|
||||
if (!(err instanceof AppError)) {
|
||||
@@ -109,7 +109,11 @@ export default function UsersPage() {
|
||||
<section class="p-8">
|
||||
<div class="flex justify-between">
|
||||
<h1 class="text-2xl font-bold mb-4">{t("panel.users.title")}</h1>
|
||||
<button onClick={() => modalRef!.showModal()} class="btn btn-soft">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => modalRef.showModal()}
|
||||
class="btn btn-soft"
|
||||
>
|
||||
<FiPlus class="text-lg" />
|
||||
{t("panel.users.createNew")}
|
||||
</button>
|
||||
@@ -130,20 +134,23 @@ export default function UsersPage() {
|
||||
|
||||
<dialog
|
||||
onTransitionEnd={(e) => {
|
||||
if (e.propertyName === "opacity" && !modalRef!.open) {
|
||||
if (e.propertyName === "opacity" && !modalRef.open) {
|
||||
setEmail("");
|
||||
setMinecraftUuid("");
|
||||
setRole();
|
||||
setError(null);
|
||||
}
|
||||
}}
|
||||
ref={modalRef!}
|
||||
ref={modalRef}
|
||||
id="create_user_modal"
|
||||
class="modal"
|
||||
>
|
||||
<div class="modal-box">
|
||||
<form method="dialog">
|
||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
|
||||
>
|
||||
<FiX class="text-lg" />
|
||||
</button>
|
||||
</form>
|
||||
@@ -156,8 +163,11 @@ export default function UsersPage() {
|
||||
}}
|
||||
>
|
||||
<fieldset class="fieldset">
|
||||
<label class="label">{t("panel.users.email")}</label>
|
||||
<label for="email" class="label">
|
||||
{t("panel.users.email")}
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="text"
|
||||
class="input w-full"
|
||||
placeholder={t("panel.users.email")}
|
||||
@@ -166,8 +176,11 @@ export default function UsersPage() {
|
||||
required
|
||||
/>
|
||||
|
||||
<label class="label">{t("panel.users.minecraftUuid")}</label>
|
||||
<label for="minecraftUuid" class="label">
|
||||
{t("panel.users.minecraftUuid")}
|
||||
</label>
|
||||
<input
|
||||
id="minecraftUuid"
|
||||
type="text"
|
||||
class="input validator w-full"
|
||||
placeholder={t("panel.users.minecraftUuid")}
|
||||
@@ -196,7 +209,7 @@ export default function UsersPage() {
|
||||
</form>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>Close</button>
|
||||
<button type="button">Close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
</>
|
||||
|
||||
Reference in new issue
Block a user