This commit is contained in:
sam 2024-06-09 15:48:26 +02:00
parent 14f8e77e6a
commit a2f001392b
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
11 changed files with 241 additions and 2 deletions

View 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;
}

View file

@ -0,0 +1,9 @@
export type User = {
id: string;
username: string;
display_name: string | null;
bio: string | null;
member_title: string | null;
avatar_url: string | null;
links: string[];
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

@ -0,0 +1,57 @@
<script lang="ts">
import {
Navbar,
NavbarBrand,
NavbarToggler,
Collapse,
Nav,
Dropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
NavItem,
} from "@sveltestrap/sveltestrap";
import Logo from "./Logo.svelte";
import type { User } from "$lib/api/user";
export let user: User | undefined;
let showMenu = true;
const toggleMenu = () => {
showMenu = !showMenu;
};
let userMenuOpen = false;
</script>
<Navbar>
<NavbarBrand href="/" aria-label="pronouns.cc landing page">
<Logo />
</NavbarBrand>
<NavbarToggler on:click={toggleMenu} aria-label="Toggle menu" />
<Collapse isOpen={showMenu} navbar expand="lg">
<Nav class="ms-auto" navbar>
{#if user}
<NavItem>
<Dropdown nav isOpen={userMenuOpen} toggle={() => (userMenuOpen = !userMenuOpen)}>
<DropdownToggle nav caret>@{user.username}</DropdownToggle>
<DropdownMenu>
<DropdownItem href="/@{user.username}">View profile</DropdownItem>
<DropdownItem href="/settings">Settings</DropdownItem>
<DropdownItem divider />
<DropdownItem href="/logout">Log out</DropdownItem>
</DropdownMenu>
</Dropdown>
</NavItem>
{:else}
<NavItem>
<Dropdown nav isOpen={userMenuOpen} toggle={() => (userMenuOpen = !userMenuOpen)}>
<DropdownToggle nav caret>Not logged in</DropdownToggle>
<DropdownMenu>
<DropdownItem href="/login">Log in</DropdownItem>
</DropdownMenu>
</Dropdown>
</NavItem>
{/if}
</Nav>
</Collapse>
</Navbar>

View file

@ -0,0 +1,72 @@
import { PUBLIC_API_BASE } from "$env/static/public";
export type RequestParams = {
token?: string;
body?: any;
headers?: Record<string, string>;
};
/**
* Fetch a path from the API and parse the response.
* To make sure the request is authenticated in load functions,
* pass `fetch` from the request object into opts.
*
* @param fetchFn A function like `fetch`, such as from the `load` function
* @param method The HTTP method, i.e. GET, POST, PATCH
* @param path The path to request, minus the leading `/api/v2`
* @param params Extra options for this request
* @returns T
* @throws APIError
*/
export default async function request<T>(
fetchFn: typeof fetch,
method: string,
path: string,
params: RequestParams = {},
) {
const url = `${PUBLIC_API_BASE}/v2${path}`;
const resp = await fetchFn(url, {
method,
body: params.body ? JSON.stringify(params.body) : undefined,
headers: {
...params.headers,
...(params.token ? { Authorization: params.token } : {}),
"Content-Type": "application/json",
},
});
if (resp.status < 200 || resp.status >= 400) throw await resp.json();
return (await resp.json()) as T;
}
/**
* Fetch a path from the API and discard the response.
* To make sure the request is authenticated in load functions,
* pass `fetch` from the request object into opts.
*
* @param fetchFn A function like `fetch`, such as from the `load` function
* @param method The HTTP method, i.e. GET, POST, PATCH
* @param path The path to request, minus the leading `/api/v2`
* @param params Extra options for this request
* @returns T
* @throws APIError
*/
export async function fastRequest(
fetchFn: typeof fetch,
method: string,
path: string,
params: RequestParams = {},
): Promise<void> {
const url = `${PUBLIC_API_BASE}/v2${path}`;
const resp = await fetchFn(url, {
method,
body: params.body ? JSON.stringify(params.body) : undefined,
headers: {
...params.headers,
...(params.token ? { Authorization: params.token } : {}),
"Content-Type": "application/json",
},
});
if (resp.status < 200 || resp.status >= 400) throw await resp.json();
}