diff --git a/nix/module.nix b/nix/module.nix
index 449aeb8..b365480 100644
--- a/nix/module.nix
+++ b/nix/module.nix
@@ -100,7 +100,6 @@ in
User = cfg.user;
Group = cfg.group;
Restart = "always";
- WorkingDirectory = "${cfg.package}/web-app";
};
script = ''
diff --git a/nix/package.nix b/nix/package.nix
index 08f5a3d..efa8d60 100644
--- a/nix/package.nix
+++ b/nix/package.nix
@@ -32,23 +32,12 @@ let
cp -r db/migrations/* $out/rest-api/db/migrations
'';
};
-
- templates = stdenv.mkDerivation {
- inherit pname version;
- name = "archtika-templates";
- src = ../templates;
- installPhase = ''
- mkdir -p $out/templates
- cp -r * $out/templates
- '';
- };
in
symlinkJoin {
name = pname;
paths = [
web
api
- templates
];
meta = with lib; {
diff --git a/templates/blog/article.html b/templates/blog/article.html
deleted file mode 100644
index cbe7888..0000000
--- a/templates/blog/article.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
- Document
-
-
-
-
- {{cover_image}}
- {{title}}
- {{publication_date}}
-
-
- {{main_content}}
-
-
-
-
\ No newline at end of file
diff --git a/templates/blog/index.html b/templates/blog/index.html
deleted file mode 100644
index ecd8b3c..0000000
--- a/templates/blog/index.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
- Document
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/templates/blog/styles.css b/templates/blog/styles.css
deleted file mode 100644
index 983fa49..0000000
--- a/templates/blog/styles.css
+++ /dev/null
@@ -1,18 +0,0 @@
-:root {
- color-scheme: light dark;
-}
-
-body {
- margin-inline: auto;
- inline-size: min(100% - 2rem, 75ch);
- line-height: 1.5;
- font-family: system-ui, sans-serif;
-}
-
-img,
-picture,
-svg,
-video {
- max-inline-size: 100%;
- block-size: auto;
-}
\ No newline at end of file
diff --git a/web-app/src/lib/templates/blog/BlogArticle.svelte b/web-app/src/lib/templates/blog/BlogArticle.svelte
new file mode 100644
index 0000000..c5ac578
--- /dev/null
+++ b/web-app/src/lib/templates/blog/BlogArticle.svelte
@@ -0,0 +1,42 @@
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+ {title}
+ {publicationDate}
+
+
+
+ {@html mainContent}
+
+
+
diff --git a/web-app/src/lib/templates/blog/BlogIndex.svelte b/web-app/src/lib/templates/blog/BlogIndex.svelte
new file mode 100644
index 0000000..3d8f76e
--- /dev/null
+++ b/web-app/src/lib/templates/blog/BlogIndex.svelte
@@ -0,0 +1,57 @@
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+ {#if articles.length > 0}
+
+ Articles
+
+ {#each articles as article}
+ {@const articleFileName = article.title.toLowerCase().split(" ").join("-")}
+
+
+ {article.publication_date}
+
+ {article.meta_description ?? "No description provided"}
+
+ {/each}
+
+ {/if}
+
+
+
diff --git a/web-app/src/routes/(authenticated)/+error.svelte b/web-app/src/routes/(authenticated)/+error.svelte
new file mode 100644
index 0000000..3f9b2c2
--- /dev/null
+++ b/web-app/src/routes/(authenticated)/+error.svelte
@@ -0,0 +1,7 @@
+Not found or access denied
+
+
diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/+layout.server.ts b/web-app/src/routes/(authenticated)/website/[websiteId]/+layout.server.ts
index af51676..b07969b 100644
--- a/web-app/src/routes/(authenticated)/website/[websiteId]/+layout.server.ts
+++ b/web-app/src/routes/(authenticated)/website/[websiteId]/+layout.server.ts
@@ -1,5 +1,6 @@
import type { LayoutServerLoad } from "./$types";
import { API_BASE_PREFIX } from "$lib/utils";
+import { error } from "@sveltejs/kit";
export const load: LayoutServerLoad = async ({ params, fetch, cookies }) => {
const websiteData = await fetch(`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}`, {
@@ -11,6 +12,10 @@ export const load: LayoutServerLoad = async ({ params, fetch, cookies }) => {
}
});
+ if (!websiteData.ok) {
+ throw error(404, "Website not found");
+ }
+
const homeData = await fetch(`${API_BASE_PREFIX}/home?website_id=eq.${params.websiteId}`, {
method: "GET",
headers: {
diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/publish/+page.server.ts b/web-app/src/routes/(authenticated)/website/[websiteId]/publish/+page.server.ts
index cf6cca6..d5b4e2c 100644
--- a/web-app/src/routes/(authenticated)/website/[websiteId]/publish/+page.server.ts
+++ b/web-app/src/routes/(authenticated)/website/[websiteId]/publish/+page.server.ts
@@ -1,10 +1,13 @@
-import { readFile, mkdir, writeFile } from "node:fs/promises";
+import { mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { md } from "$lib/utils";
import type { Actions, PageServerLoad } from "./$types";
import { API_BASE_PREFIX, NGINX_BASE_PREFIX } from "$lib/utils";
+import { render } from "svelte/server";
+import BlogIndex from "$lib/templates/blog/BlogIndex.svelte";
+import BlogArticle from "$lib/templates/blog/BlogArticle.svelte";
-export const load: PageServerLoad = async ({ params, fetch, cookies, locals }) => {
+export const load: PageServerLoad = async ({ params, fetch, cookies }) => {
const websiteOverviewData = await fetch(
`${API_BASE_PREFIX}/website_overview?id=eq.${params.websiteId}`,
{
@@ -41,56 +44,18 @@ export const actions: Actions = {
};
const generateStaticFiles = async (websiteData: any, isPreview: boolean = true) => {
- const templatePath = join(
- process.cwd(),
- "..",
- "templates",
- websiteData.content_type.toLowerCase()
- );
-
- const indexFile = await readFile(join(templatePath, "index.html"), { encoding: "utf-8" });
- const articleFile = await readFile(join(templatePath, "article.html"), {
- encoding: "utf-8"
+ const { head, body } = render(BlogIndex, {
+ props: {
+ title: websiteData.title,
+ logoType: websiteData.logo_type,
+ logo: websiteData.logo_text,
+ mainContent: md.render(websiteData.main_content ?? ""),
+ articles: websiteData.articles ?? [],
+ footerAdditionalText: websiteData.additional_text ?? ""
+ }
});
- const stylesFile = await readFile(join(templatePath, "styles.css"), { encoding: "utf-8" });
- const indexFileContents = indexFile
- .replace(
- "{{logo}}",
- websiteData.logo_type === "text"
- ? `${websiteData.logo_text}`
- : `
`
- )
- .replace("{{title}}", `${websiteData.title}
`)
- .replace("{{main_content}}", md.render(websiteData.main_content ?? ""))
- .replace(
- "{{articles}}",
- Array.isArray(websiteData.articles) && websiteData.articles.length > 0
- ? `
- Articles
- ${websiteData.articles
- .map(
- (article: { title: string; publication_date: string; meta_description: string }) => {
- const articleFileName = article.title.toLowerCase().split(" ").join("-");
-
- return `
-
- ${article.publication_date}
-
- ${article.meta_description ?? "No description provided"}
-
- `;
- }
- )
- .join("")}
- `
- : "Articles
No articles available at this time.
"
- )
- .replace("{{additional_text}}", md.render(websiteData.additional_text ?? ""));
+ const indexFileContents = head.concat(body);
let uploadDir = "";
@@ -109,32 +74,26 @@ const generateStaticFiles = async (websiteData: any, isPreview: boolean = true)
}
await mkdir(uploadDir, { recursive: true });
-
await writeFile(join(uploadDir, "index.html"), indexFileContents);
-
await mkdir(join(uploadDir, "articles"), { recursive: true });
for (const article of websiteData.articles ?? []) {
const articleFileName = article.title.toLowerCase().split(" ").join("-");
- const articleFileContents = articleFile
- .replace(
- "{{logo}}",
- websiteData.logo_type === "text"
- ? `${websiteData.logo_text}`
- : `
`
- )
- .replace(
- "{{cover_image}}",
- `
`
- )
- .replace("{{title}}", `${article.title}
`)
- .replace("{{publication_date}}", `${article.publication_date}
`)
- .replace("{{main_content}}", md.render(article.main_content ?? ""))
- .replace("{{additional_text}}", md.render(websiteData.additional_text ?? ""));
+ const { head, body } = render(BlogArticle, {
+ props: {
+ title: article.title,
+ logoType: websiteData.logo_type,
+ logo: websiteData.logo_text,
+ coverImage: `${API_BASE_PREFIX}/rpc/retrieve_file?id=${article.cover_image}`,
+ publicationDate: article.publication_date,
+ mainContent: md.render(article.main_content ?? ""),
+ footerAdditionalText: websiteData.additional_text ?? ""
+ }
+ });
+
+ const articleFileContents = head.concat(body);
await writeFile(join(uploadDir, "articles", `${articleFileName}.html`), articleFileContents);
}
-
- await writeFile(join(uploadDir, "styles.css"), stylesFile);
};
diff --git a/web-app/src/routes/+layout.svelte b/web-app/src/routes/+layout.svelte
index aad4108..5abf5c5 100644
--- a/web-app/src/routes/+layout.svelte
+++ b/web-app/src/routes/+layout.svelte
@@ -6,7 +6,7 @@
const { data, children } = $props<{ data: LayoutServerData; children: Snippet }>();
- const isProjectRoute = $derived($page.url.pathname.startsWith("/website"));
+ const isProjectRoute = $derived($page.url.pathname.startsWith("/website") && !$page.error);
const routeName = $derived(
$page.url.pathname === "/"
? "Dashboard"
@@ -39,7 +39,7 @@
-{#if !isProjectRoute}
+{#if !isProjectRoute && !$page.error}