admin cp baby steps
This commit is contained in:
parent
3f1b833c82
commit
d0eb8eec10
14 changed files with 144 additions and 9 deletions
41
package-lock.json
generated
41
package-lock.json
generated
|
@ -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",
|
||||||
|
|
|
@ -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": {}
|
||||||
|
|
|
@ -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 ?? '/'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
11
src/routes/(admin-panel)/admin/+page.server.ts
Normal file
11
src/routes/(admin-panel)/admin/+page.server.ts
Normal 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;
|
|
@ -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}
|
||||||
|
|
11
src/routes/(admin-panel)/admin/sites/[site]/+layout.svelte
Normal file
11
src/routes/(admin-panel)/admin/sites/[site]/+layout.svelte
Normal 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 />
|
12
src/routes/(admin-panel)/admin/sites/[site]/+layout.ts
Normal file
12
src/routes/(admin-panel)/admin/sites/[site]/+layout.ts
Normal 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;
|
7
src/routes/(admin-panel)/admin/sites/[site]/+page.svelte
Normal file
7
src/routes/(admin-panel)/admin/sites/[site]/+page.svelte
Normal 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>
|
9
src/routes/(admin-panel)/admin/sites/[site]/+page.ts
Normal file
9
src/routes/(admin-panel)/admin/sites/[site]/+page.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import type { PageLoad } from './$types';
|
||||||
|
|
||||||
|
export const load = (async ({ parent }) => {
|
||||||
|
const site = await parent();
|
||||||
|
|
||||||
|
return {
|
||||||
|
site
|
||||||
|
};
|
||||||
|
}) satisfies PageLoad;
|
|
@ -0,0 +1 @@
|
||||||
|
<header><h2>New post</h2></header>
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue