admin cp baby steps

This commit is contained in:
Hamcha 2023-07-30 14:09:27 +02:00
parent 3f1b833c82
commit d0eb8eec10
Signed by: hamcha
GPG key ID: 1669C533B8CF6D89
14 changed files with 144 additions and 9 deletions

41
package-lock.json generated
View file

@ -17,6 +17,7 @@
"eslint-plugin-svelte": "^2.32.4", "eslint-plugin-svelte": "^2.32.4",
"prettier": "^3.0.0", "prettier": "^3.0.0",
"prettier-plugin-svelte": "^3.0.3", "prettier-plugin-svelte": "^3.0.3",
"sass": "^1.64.1",
"svelte": "^4.1.1", "svelte": "^4.1.1",
"svelte-check": "^3.4.6", "svelte-check": "^3.4.6",
"sveltekit-adapter-deno": "^0.10.2", "sveltekit-adapter-deno": "^0.10.2",
@ -1770,6 +1771,12 @@
"node": ">= 4" "node": ">= 4"
} }
}, },
"node_modules/immutable": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz",
"integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==",
"dev": true
},
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -2569,6 +2576,23 @@
"rimraf": "bin.js" "rimraf": "bin.js"
} }
}, },
"node_modules/sass": {
"version": "1.64.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.64.1.tgz",
"integrity": "sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==",
"dev": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
"sass": "sass.js"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/semver": { "node_modules/semver": {
"version": "7.5.4", "version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@ -4264,6 +4288,12 @@
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true "dev": true
}, },
"immutable": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz",
"integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==",
"dev": true
},
"import-fresh": { "import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -4794,6 +4824,17 @@
} }
} }
}, },
"sass": {
"version": "1.64.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.64.1.tgz",
"integrity": "sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==",
"dev": true,
"requires": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
}
},
"semver": { "semver": {
"version": "7.5.4", "version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",

View file

@ -26,10 +26,11 @@
"prettier-plugin-svelte": "^3.0.3", "prettier-plugin-svelte": "^3.0.3",
"svelte": "^4.1.1", "svelte": "^4.1.1",
"svelte-check": "^3.4.6", "svelte-check": "^3.4.6",
"sveltekit-adapter-deno": "^0.10.2",
"tslib": "^2.6.1", "tslib": "^2.6.1",
"typescript": "^5.1.6", "typescript": "^5.1.6",
"vite": "^4.4.7", "vite": "^4.4.7",
"sveltekit-adapter-deno": "^0.10.2" "sass": "^1.64.1"
}, },
"type": "module", "type": "module",
"dependencies": {} "dependencies": {}

View file

@ -76,7 +76,8 @@ export function passthroughSession(response: Response, cookies: Cookies) {
sameSite: 'strict', sameSite: 'strict',
domain: PUBLIC_DOMAIN, domain: PUBLIC_DOMAIN,
expires: info.options.Expires, expires: info.options.Expires,
maxAge: info.options['Max-Age'] maxAge: info.options['Max-Age'],
path: info.options.Path ?? '/'
}); });
} }
} }

View file

@ -1,3 +1,4 @@
import type { Cookies } from '@sveltejs/kit';
import type { Collection } from './collections'; import type { Collection } from './collections';
import { callJSON } from './request'; import { callJSON } from './request';
@ -14,4 +15,14 @@ export interface Site {
deleted_at: string | null; deleted_at: string | null;
} }
export interface SiteShortInfo {
name: string;
title: string;
description: string | null;
created_at: string;
}
export const getSiteInfo = (name: string) => callJSON<Site>('GET', `sites/${name}`); export const getSiteInfo = (name: string) => callJSON<Site>('GET', `sites/${name}`);
export const getSitesForCurrentUser = (cookies: Cookies) =>
callJSON<SiteShortInfo[]>('GET', 'users/@current/sites', undefined, cookies);

View file

@ -1,3 +1,12 @@
<h2>cenere!!!</h2> <svelte:head>
<title>Cenere Dashboard</title>
</svelte:head>
<header><h2><a href="/admin">Cenere</a></h2></header>
<slot /> <slot />
<style lang="scss">
header {
}
</style>

View file

@ -0,0 +1,11 @@
import { getSitesForCurrentUser } from '$lib/api/sites';
import { must } from '$lib/errors';
import type { PageServerLoad } from '../login/$types';
export const load = (async ({ cookies }) => {
const sites = await must(getSitesForCurrentUser(cookies));
return {
sites
};
}) satisfies PageServerLoad;

View file

@ -1 +1,17 @@
aaaa <script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
</script>
Your sites:
{#if data.sites}
<ul>
{#each data.sites as site}
<li><a href="/admin/sites/{site.name}">{site.title}</a></li>
{/each}
</ul>
{:else}
<!-- TODO Zero state here -->
{/if}

View file

@ -0,0 +1,11 @@
<script lang="ts">
import type { LayoutData } from './$types';
export let data: LayoutData;
</script>
<header>
<h3><a href="/admin/sites/{data.siteInfo.name}">{data.siteInfo.title}</a></h3>
</header>
<slot />

View file

@ -0,0 +1,12 @@
import type { LayoutLoad } from './$types';
import { must } from '$lib/errors';
import { getSiteInfo } from '$lib/api/sites';
export const load = (async ({ params, url }) => {
const siteInfo = await must(getSiteInfo(params.site));
return {
siteInfo,
base: url.pathname
};
}) satisfies LayoutLoad;

View file

@ -0,0 +1,7 @@
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
</script>
<a href="{data.site.base}/posts/new">New post</a>

View file

@ -0,0 +1,9 @@
import type { PageLoad } from './$types';
export const load = (async ({ parent }) => {
const site = await parent();
return {
site
};
}) satisfies PageLoad;

View file

@ -0,0 +1 @@
<header><h2>New post</h2></header>

View file

@ -1,4 +1,4 @@
import { HttpError, redirect } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types'; import type { Actions, PageServerLoad } from './$types';
import { APIError } from '$lib/api/request'; import { APIError } from '$lib/api/request';
import { getLoggedInUser, login, logout } from '$lib/api/auth'; import { getLoggedInUser, login, logout } from '$lib/api/auth';
@ -8,14 +8,15 @@ export const load = async function ({ url, cookies }) {
// Check that login is valid // Check that login is valid
if (session) { if (session) {
let user: string | null = null;
try { try {
const user = await getLoggedInUser(cookies); user = await getLoggedInUser(cookies);
if (user) {
throw redirect(302, url.searchParams.get('then') || '/admin');
}
} catch (e) { } catch (e) {
// do nothing if not logged in // do nothing if not logged in
} }
if (user) {
throw redirect(302, url.searchParams.get('then') || '/admin');
}
} }
} satisfies PageServerLoad; } satisfies PageServerLoad;

View file

@ -4,6 +4,10 @@
export let data: PageData; export let data: PageData;
</script> </script>
<svelte:head>
<title>{data.site.title}</title>
</svelte:head>
{#if data.pages} {#if data.pages}
{#each data.pages.items as post} {#each data.pages.items as post}
<article> <article>