mirror of
https://github.com/thiloho/archtika.git
synced 2025-11-22 10:51:36 +01:00
Create fetch utility function
This commit is contained in:
@@ -30,3 +30,13 @@ export const handle = async ({ event, resolve }) => {
|
|||||||
|
|
||||||
return await resolve(event);
|
return await resolve(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const handleFetch = async ({ event, request, fetch }) => {
|
||||||
|
const sessionToken = event.cookies.get("session_token");
|
||||||
|
|
||||||
|
if (sessionToken) {
|
||||||
|
request.headers.set("Authorization", `Bearer ${sessionToken}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(request);
|
||||||
|
};
|
||||||
|
|||||||
@@ -9,3 +9,48 @@ export const REGISTRATION_IS_DISABLED = dev
|
|||||||
: process.env.REGISTRATION_IS_DISABLED
|
: process.env.REGISTRATION_IS_DISABLED
|
||||||
? JSON.parse(process.env.REGISTRATION_IS_DISABLED)
|
? JSON.parse(process.env.REGISTRATION_IS_DISABLED)
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
|
export const apiRequest = async (
|
||||||
|
customFetch: typeof fetch,
|
||||||
|
url: string,
|
||||||
|
method: "HEAD" | "GET" | "POST" | "PATCH" | "DELETE",
|
||||||
|
options: {
|
||||||
|
headers?: Record<string, string>;
|
||||||
|
body?: any;
|
||||||
|
successMessage?: string;
|
||||||
|
returnData?: boolean;
|
||||||
|
} = {
|
||||||
|
headers: {},
|
||||||
|
body: undefined,
|
||||||
|
successMessage: "Operation was successful",
|
||||||
|
returnData: false
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options.headers
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await customFetch(url, {
|
||||||
|
method,
|
||||||
|
headers,
|
||||||
|
...(!["HEAD", "GET", "DELETE"].includes(method) && {
|
||||||
|
body: options.body instanceof ArrayBuffer ? options.body : JSON.stringify(options.body)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json();
|
||||||
|
return { success: false, message: errorData.message };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.returnData) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: options.successMessage,
|
||||||
|
data: method === "HEAD" ? response : await response.json()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success: true, message: options.successMessage };
|
||||||
|
};
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ export const handleImagePaste = async (event: ClipboardEvent, API_BASE_PREFIX: s
|
|||||||
const response = await request.json();
|
const response = await request.json();
|
||||||
|
|
||||||
if (JSON.parse(response.data)[1]) {
|
if (JSON.parse(response.data)[1]) {
|
||||||
const fileId = JSON.parse(response.data)[3];
|
const fileId = JSON.parse(response.data)[4];
|
||||||
const fileUrl = `${API_BASE_PREFIX}/rpc/retrieve_file?id=${fileId}`;
|
const fileUrl = `${API_BASE_PREFIX}/rpc/retrieve_file?id=${fileId}`;
|
||||||
|
|
||||||
const target = event.target as HTMLTextAreaElement;
|
const target = event.target as HTMLTextAreaElement;
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
import type { Actions } from "./$types";
|
import type { Actions } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
default: async ({ request, cookies, fetch }) => {
|
default: async ({ request, cookies, fetch }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/rpc/login`, {
|
const response = await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/login`, "POST", {
|
||||||
method: "POST",
|
body: {
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: data.get("username"),
|
username: data.get("username"),
|
||||||
pass: data.get("password")
|
pass: data.get("password")
|
||||||
})
|
},
|
||||||
|
returnData: true,
|
||||||
|
successMessage: "Successfully logged in, you can refresh the page"
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await res.json();
|
if (!response.success) {
|
||||||
|
return response;
|
||||||
if (!res.ok) {
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cookies.set("session_token", response.token, { path: "/" });
|
cookies.set("session_token", response.data.token, { path: "/" });
|
||||||
return { success: true, message: "Successfully logged in" };
|
return response;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX, REGISTRATION_IS_DISABLED } from "$lib/server/utils";
|
import { API_BASE_PREFIX, REGISTRATION_IS_DISABLED, apiRequest } from "$lib/server/utils";
|
||||||
|
|
||||||
export const load: PageServerLoad = async () => {
|
export const load: PageServerLoad = async () => {
|
||||||
return {
|
return {
|
||||||
@@ -11,21 +11,12 @@ export const actions: Actions = {
|
|||||||
default: async ({ request, fetch }) => {
|
default: async ({ request, fetch }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/rpc/register`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/register`, "POST", {
|
||||||
method: "POST",
|
body: {
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: data.get("username"),
|
username: data.get("username"),
|
||||||
pass: data.get("password")
|
pass: data.get("password")
|
||||||
})
|
},
|
||||||
|
successMessage: "Successfully registered, you can now login"
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await res.json();
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully registered, you can now login" };
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
|
import { apiRequest } from "$lib/server/utils";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX } from "$lib/server/utils";
|
||||||
import { rm } from "node:fs/promises";
|
import { rm } from "node:fs/promises";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import type { Website, WebsiteInput } from "$lib/db-schema";
|
import type { Website } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ fetch, cookies, url, locals }) => {
|
export const load: PageServerLoad = async ({ fetch, url, locals }) => {
|
||||||
const searchQuery = url.searchParams.get("website_search_query");
|
const searchQuery = url.searchParams.get("website_search_query");
|
||||||
const filterBy = url.searchParams.get("website_filter");
|
const filterBy = url.searchParams.get("website_filter");
|
||||||
|
|
||||||
@@ -27,28 +28,22 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, locals }) => {
|
|||||||
|
|
||||||
const constructedFetchUrl = `${baseFetchUrl}&${params.toString()}`;
|
const constructedFetchUrl = `${baseFetchUrl}&${params.toString()}`;
|
||||||
|
|
||||||
const totalWebsitesData = await fetch(baseFetchUrl, {
|
const totalWebsites = await apiRequest(fetch, baseFetchUrl, "HEAD", {
|
||||||
method: "HEAD",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Prefer: "count=exact"
|
Prefer: "count=exact"
|
||||||
}
|
},
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalWebsiteCount = Number(
|
const totalWebsiteCount = Number(
|
||||||
totalWebsitesData.headers.get("content-range")?.split("/").at(-1)
|
totalWebsites.data.headers.get("content-range")?.split("/").at(-1)
|
||||||
);
|
);
|
||||||
|
|
||||||
const websiteData = await fetch(constructedFetchUrl, {
|
const websites: Website[] = (
|
||||||
method: "GET",
|
await apiRequest(fetch, constructedFetchUrl, "GET", {
|
||||||
headers: {
|
returnData: true
|
||||||
"Content-Type": "application/json",
|
})
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
).data;
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const websites: Website[] = await websiteData.json();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalWebsiteCount,
|
totalWebsiteCount,
|
||||||
@@ -57,91 +52,63 @@ export const load: PageServerLoad = async ({ fetch, cookies, url, locals }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
createWebsite: async ({ request, fetch, cookies }) => {
|
createWebsite: async ({ request, fetch }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/rpc/create_website`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/create_website`, "POST", {
|
||||||
method: "POST",
|
body: {
|
||||||
headers: {
|
content_type: data.get("content-type"),
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
content_type: data.get("content-type") as string,
|
|
||||||
title: data.get("title") as string
|
|
||||||
} satisfies WebsiteInput)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully created website" };
|
|
||||||
},
|
|
||||||
updateWebsite: async ({ request, cookies, fetch }) => {
|
|
||||||
const data = await request.formData();
|
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/website?id=eq.${data.get("id")}`, {
|
|
||||||
method: "PATCH",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
title: data.get("title")
|
title: data.get("title")
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully updated website" };
|
|
||||||
},
|
},
|
||||||
deleteWebsite: async ({ request, cookies, fetch }) => {
|
successMessage: "Successfully created website"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateWebsite: async ({ request, fetch }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const oldDomainPrefixData = await fetch(
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/website?id=eq.${data.get("id")}`, "PATCH", {
|
||||||
`${API_BASE_PREFIX}/domain_prefix?website_id=eq.${data.get("id")}`,
|
body: {
|
||||||
{
|
title: data.get("title")
|
||||||
method: "GET",
|
},
|
||||||
|
successMessage: "Successfully updated website"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteWebsite: async ({ request, fetch }) => {
|
||||||
|
const data = await request.formData();
|
||||||
|
const id = data.get("id");
|
||||||
|
|
||||||
|
const oldDomainPrefix = (
|
||||||
|
await apiRequest(fetch, `${API_BASE_PREFIX}/domain_prefix?website_id=eq.${id}`, "GET", {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
}
|
},
|
||||||
}
|
returnData: true
|
||||||
);
|
})
|
||||||
const oldDomainPrefix = await oldDomainPrefixData.json();
|
).data;
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/website?id=eq.${data.get("id")}`, {
|
const deleteWebsite = await apiRequest(
|
||||||
method: "DELETE",
|
fetch,
|
||||||
headers: {
|
`${API_BASE_PREFIX}/website?id=eq.${id}`,
|
||||||
"Content-Type": "application/json",
|
"DELETE",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
await rm(join("/", "var", "www", "archtika-websites", "previews", data.get("id") as string), {
|
|
||||||
recursive: true,
|
|
||||||
force: true
|
|
||||||
});
|
|
||||||
|
|
||||||
await rm(
|
|
||||||
join("/", "var", "www", "archtika-websites", oldDomainPrefix.prefix ?? data.get("id")),
|
|
||||||
{
|
{
|
||||||
recursive: true,
|
successMessage: "Successfully deleted website"
|
||||||
force: true
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return { success: true, message: "Successfully deleted website" };
|
if (!deleteWebsite.success) {
|
||||||
|
return deleteWebsite;
|
||||||
|
}
|
||||||
|
|
||||||
|
await rm(join("/", "var", "www", "archtika-websites", "previews", id as string), {
|
||||||
|
recursive: true,
|
||||||
|
force: true
|
||||||
|
});
|
||||||
|
|
||||||
|
await rm(join("/", "var", "www", "archtika-websites", oldDomainPrefix?.prefix ?? id), {
|
||||||
|
recursive: true,
|
||||||
|
force: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return deleteWebsite;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ locals }) => {
|
export const load: PageServerLoad = async ({ locals }) => {
|
||||||
return {
|
return {
|
||||||
@@ -16,24 +16,18 @@ export const actions: Actions = {
|
|||||||
deleteAccount: async ({ request, fetch, cookies }) => {
|
deleteAccount: async ({ request, fetch, cookies }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/rpc/delete_account`, {
|
const response = await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/delete_account`, "POST", {
|
||||||
method: "POST",
|
body: {
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
pass: data.get("password")
|
pass: data.get("password")
|
||||||
})
|
},
|
||||||
|
successMessage: "Successfully deleted account"
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await res.json();
|
if (!response.success) {
|
||||||
|
return response;
|
||||||
if (!res.ok) {
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cookies.delete("session_token", { path: "/" });
|
cookies.delete("session_token", { path: "/" });
|
||||||
return { success: true, message: "Successfully deleted account" };
|
return response;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,36 +1,35 @@
|
|||||||
import type { LayoutServerLoad } from "./$types";
|
import type { LayoutServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
import type { Website, Home, User } from "$lib/db-schema";
|
import type { Website, Home, User } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: LayoutServerLoad = async ({ params, fetch, cookies }) => {
|
export const load: LayoutServerLoad = async ({ params, fetch }) => {
|
||||||
const websiteData = await fetch(
|
const websiteData = await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}&select=*,user!user_id(username)`,
|
`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}&select=*,user!user_id(username)`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
}
|
},
|
||||||
|
returnData: true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!websiteData.ok) {
|
const website: Website & { user: { username: User["username"] } } = websiteData.data;
|
||||||
|
|
||||||
|
if (!websiteData.success) {
|
||||||
throw error(404, "Website not found");
|
throw error(404, "Website not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const homeData = await fetch(`${API_BASE_PREFIX}/home?website_id=eq.${params.websiteId}`, {
|
const home: Home = (
|
||||||
method: "GET",
|
await apiRequest(fetch, `${API_BASE_PREFIX}/home?website_id=eq.${params.websiteId}`, "GET", {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
}
|
},
|
||||||
});
|
returnData: true
|
||||||
|
})
|
||||||
const website: Website & { user: { username: User["username"] } } = await websiteData.json();
|
).data;
|
||||||
const home: Home = await homeData.json();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
website,
|
website,
|
||||||
|
|||||||
@@ -1,41 +1,40 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX } from "$lib/server/utils";
|
||||||
|
import { apiRequest } from "$lib/server/utils";
|
||||||
import type { Settings, Header, Footer } from "$lib/db-schema";
|
import type { Settings, Header, Footer } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ params, fetch, cookies }) => {
|
export const load: PageServerLoad = async ({ params, fetch }) => {
|
||||||
const globalSettingsData = await fetch(
|
const globalSettings: Settings = (
|
||||||
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/settings?website_id=eq.${params.websiteId}`,
|
`${API_BASE_PREFIX}/settings?website_id=eq.${params.websiteId}`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
|
},
|
||||||
|
returnData: true
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
);
|
).data;
|
||||||
|
|
||||||
const headerData = await fetch(`${API_BASE_PREFIX}/header?website_id=eq.${params.websiteId}`, {
|
const header: Header = (
|
||||||
method: "GET",
|
await apiRequest(fetch, `${API_BASE_PREFIX}/header?website_id=eq.${params.websiteId}`, "GET", {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
}
|
},
|
||||||
});
|
returnData: true
|
||||||
|
})
|
||||||
|
).data;
|
||||||
|
|
||||||
const footerData = await fetch(`${API_BASE_PREFIX}/footer?website_id=eq.${params.websiteId}`, {
|
const footer: Footer = (
|
||||||
method: "GET",
|
await apiRequest(fetch, `${API_BASE_PREFIX}/footer?website_id=eq.${params.websiteId}`, "GET", {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
}
|
},
|
||||||
});
|
returnData: true
|
||||||
|
})
|
||||||
const globalSettings: Settings = await globalSettingsData.json();
|
).data;
|
||||||
const header: Header = await headerData.json();
|
|
||||||
const footer: Footer = await footerData.json();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
globalSettings,
|
globalSettings,
|
||||||
@@ -46,13 +45,12 @@ export const load: PageServerLoad = async ({ params, fetch, cookies }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
updateGlobal: async ({ request, fetch, cookies, params }) => {
|
updateGlobal: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
const faviconFile = data.get("favicon") as File;
|
const faviconFile = data.get("favicon") as File;
|
||||||
|
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
"Content-Type": "application/octet-stream",
|
"Content-Type": "application/octet-stream",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json",
|
Accept: "application/vnd.pgrst.object+json",
|
||||||
"X-Website-Id": params.websiteId
|
"X-Website-Id": params.websiteId
|
||||||
};
|
};
|
||||||
@@ -62,48 +60,36 @@ export const actions: Actions = {
|
|||||||
headers["X-Original-Filename"] = faviconFile.name;
|
headers["X-Original-Filename"] = faviconFile.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadedImageData = await fetch(`${API_BASE_PREFIX}/rpc/upload_file`, {
|
const uploadedImage = await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/upload_file`, "POST", {
|
||||||
method: "POST",
|
|
||||||
headers,
|
headers,
|
||||||
body: faviconFile ? await faviconFile.arrayBuffer() : null
|
body: faviconFile ? await faviconFile.arrayBuffer() : null,
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const uploadedImage = await uploadedImageData.json();
|
if (!uploadedImage.success && (faviconFile?.size ?? 0 > 0)) {
|
||||||
|
return uploadedImage;
|
||||||
if (!uploadedImageData.ok && (faviconFile?.size ?? 0 > 0)) {
|
|
||||||
return { success: false, message: uploadedImage.message };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/settings?website_id=eq.${params.websiteId}`, {
|
return await apiRequest(
|
||||||
method: "PATCH",
|
fetch,
|
||||||
headers: {
|
`${API_BASE_PREFIX}/settings?website_id=eq.${params.websiteId}`,
|
||||||
"Content-Type": "application/json",
|
"PATCH",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
{
|
||||||
},
|
body: {
|
||||||
body: JSON.stringify({
|
|
||||||
accent_color_light_theme: data.get("accent-color-light"),
|
accent_color_light_theme: data.get("accent-color-light"),
|
||||||
accent_color_dark_theme: data.get("accent-color-dark"),
|
accent_color_dark_theme: data.get("accent-color-dark"),
|
||||||
favicon_image: uploadedImage.file_id
|
favicon_image: uploadedImage.data?.file_id
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: "Successfully updated global settings"
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
updateHeader: async ({ request, fetch, cookies, params }) => {
|
successMessage: "Successfully updated global settings"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
updateHeader: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
const logoImage = data.get("logo-image") as File;
|
const logoImage = data.get("logo-image") as File;
|
||||||
|
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
"Content-Type": "application/octet-stream",
|
"Content-Type": "application/octet-stream",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json",
|
Accept: "application/vnd.pgrst.object+json",
|
||||||
"X-Website-Id": params.websiteId
|
"X-Website-Id": params.websiteId
|
||||||
};
|
};
|
||||||
@@ -113,109 +99,75 @@ export const actions: Actions = {
|
|||||||
headers["X-Original-Filename"] = logoImage.name;
|
headers["X-Original-Filename"] = logoImage.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadedImageData = await fetch(`${API_BASE_PREFIX}/rpc/upload_file`, {
|
const uploadedImage = await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/upload_file`, "POST", {
|
||||||
method: "POST",
|
|
||||||
headers,
|
headers,
|
||||||
body: logoImage ? await logoImage.arrayBuffer() : null
|
body: logoImage ? await logoImage.arrayBuffer() : null,
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const uploadedImage = await uploadedImageData.json();
|
if (!uploadedImage.success && (logoImage?.size ?? 0 > 0)) {
|
||||||
|
|
||||||
if (!uploadedImageData.ok && (logoImage?.size ?? 0 > 0)) {
|
|
||||||
return { success: false, message: uploadedImage.message };
|
return { success: false, message: uploadedImage.message };
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/header?website_id=eq.${params.websiteId}`, {
|
return await apiRequest(
|
||||||
method: "PATCH",
|
fetch,
|
||||||
headers: {
|
`${API_BASE_PREFIX}/header?website_id=eq.${params.websiteId}`,
|
||||||
"Content-Type": "application/json",
|
"PATCH",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
{
|
||||||
},
|
body: {
|
||||||
body: JSON.stringify({
|
|
||||||
logo_type: data.get("logo-type"),
|
logo_type: data.get("logo-type"),
|
||||||
logo_text: data.get("logo-text"),
|
logo_text: data.get("logo-text"),
|
||||||
logo_image: uploadedImage.file_id
|
logo_image: uploadedImage.data?.file_id
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: "Successfully updated header"
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
updateHome: async ({ request, fetch, cookies, params }) => {
|
successMessage: "Successfully updated header"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
updateHome: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/home?website_id=eq.${params.websiteId}`, {
|
return await apiRequest(
|
||||||
method: "PATCH",
|
fetch,
|
||||||
headers: {
|
`${API_BASE_PREFIX}/home?website_id=eq.${params.websiteId}`,
|
||||||
"Content-Type": "application/json",
|
"PATCH",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
{
|
||||||
},
|
body: {
|
||||||
body: JSON.stringify({
|
|
||||||
main_content: data.get("main-content")
|
main_content: data.get("main-content")
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully updated home" };
|
|
||||||
},
|
},
|
||||||
updateFooter: async ({ request, fetch, cookies, params }) => {
|
successMessage: "Successfully updated home"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
updateFooter: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/footer?website_id=eq.${params.websiteId}`, {
|
return await apiRequest(
|
||||||
method: "PATCH",
|
fetch,
|
||||||
headers: {
|
`${API_BASE_PREFIX}/footer?website_id=eq.${params.websiteId}`,
|
||||||
"Content-Type": "application/json",
|
"PATCH",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
{
|
||||||
},
|
body: {
|
||||||
body: JSON.stringify({
|
|
||||||
additional_text: data.get("additional-text")
|
additional_text: data.get("additional-text")
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: "Successfully updated footer"
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
pasteImage: async ({ request, fetch, cookies, params }) => {
|
successMessage: "Successfully updated footer"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
pasteImage: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
const file = data.get("file") as File;
|
const file = data.get("file") as File;
|
||||||
|
|
||||||
const fileData = await fetch(`${API_BASE_PREFIX}/rpc/upload_file`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/upload_file`, "POST", {
|
||||||
method: "POST",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/octet-stream",
|
"Content-Type": "application/octet-stream",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json",
|
Accept: "application/vnd.pgrst.object+json",
|
||||||
"X-Website-Id": params.websiteId,
|
"X-Website-Id": params.websiteId,
|
||||||
"X-Mimetype": file.type,
|
"X-Mimetype": file.type,
|
||||||
"X-Original-Filename": file.name
|
"X-Original-Filename": file.name
|
||||||
},
|
},
|
||||||
body: await file.arrayBuffer()
|
body: await file.arrayBuffer(),
|
||||||
|
successMessage: "Successfully uploaded image",
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const fileJSON = await fileData.json();
|
|
||||||
|
|
||||||
if (!fileData.ok) {
|
|
||||||
return { success: false, message: fileJSON.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully uploaded image", fileId: fileJSON.file_id };
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX } from "$lib/server/utils";
|
||||||
import type { Article, ArticleInput, DocsCategory } from "$lib/db-schema";
|
import { apiRequest } from "$lib/server/utils";
|
||||||
|
import type { Article, DocsCategory } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent, locals }) => {
|
export const load: PageServerLoad = async ({ params, fetch, url, parent, locals }) => {
|
||||||
const searchQuery = url.searchParams.get("article_search_query");
|
const searchQuery = url.searchParams.get("article_search_query");
|
||||||
const filterBy = url.searchParams.get("article_filter");
|
const filterBy = url.searchParams.get("article_filter");
|
||||||
|
|
||||||
@@ -34,28 +35,22 @@ export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent
|
|||||||
|
|
||||||
const constructedFetchUrl = `${baseFetchUrl}&${parameters.toString()}`;
|
const constructedFetchUrl = `${baseFetchUrl}&${parameters.toString()}`;
|
||||||
|
|
||||||
const totalArticlesData = await fetch(baseFetchUrl, {
|
const totalArticles = await apiRequest(fetch, baseFetchUrl, "HEAD", {
|
||||||
method: "HEAD",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Prefer: "count=exact"
|
Prefer: "count=exact"
|
||||||
}
|
},
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalArticleCount = Number(
|
const totalArticleCount = Number(
|
||||||
totalArticlesData.headers.get("content-range")?.split("/").at(-1)
|
totalArticles.data.headers.get("content-range")?.split("/").at(-1)
|
||||||
);
|
);
|
||||||
|
|
||||||
const articlesData = await fetch(constructedFetchUrl, {
|
const articles: (Article & { docs_category: DocsCategory | null })[] = (
|
||||||
method: "GET",
|
await apiRequest(fetch, constructedFetchUrl, "GET", {
|
||||||
headers: {
|
returnData: true
|
||||||
"Content-Type": "application/json",
|
})
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
).data;
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const articles: (Article & { docs_category: DocsCategory | null })[] = await articlesData.json();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalArticleCount,
|
totalArticleCount,
|
||||||
@@ -66,44 +61,22 @@ export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
createArticle: async ({ request, fetch, cookies, params }) => {
|
createArticle: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/article`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/article`, "POST", {
|
||||||
method: "POST",
|
body: {
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
website_id: params.websiteId,
|
website_id: params.websiteId,
|
||||||
title: data.get("title") as string
|
title: data.get("title")
|
||||||
} satisfies ArticleInput)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully created article" };
|
|
||||||
},
|
},
|
||||||
deleteArticle: async ({ request, fetch, cookies }) => {
|
successMessage: "Successfully created article"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteArticle: async ({ request, fetch }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/article?id=eq.${data.get("id")}`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/article?id=eq.${data.get("id")}`, "DELETE", {
|
||||||
method: "DELETE",
|
successMessage: "Successfully deleted article"
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully deleted article" };
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,30 +1,28 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
import type { Article, DocsCategory } from "$lib/db-schema";
|
import type { Article, DocsCategory } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ parent, params, cookies, fetch }) => {
|
export const load: PageServerLoad = async ({ parent, params, fetch }) => {
|
||||||
const articleData = await fetch(`${API_BASE_PREFIX}/article?id=eq.${params.articleId}`, {
|
const article: Article = (
|
||||||
method: "GET",
|
await apiRequest(fetch, `${API_BASE_PREFIX}/article?id=eq.${params.articleId}`, "GET", {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
}
|
},
|
||||||
});
|
returnData: true
|
||||||
|
})
|
||||||
|
).data;
|
||||||
|
|
||||||
const categoryData = await fetch(
|
const categories: DocsCategory[] = (
|
||||||
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/docs_category?website_id=eq.${params.websiteId}&order=category_weight.desc`,
|
`${API_BASE_PREFIX}/docs_category?website_id=eq.${params.websiteId}&order=category_weight.desc`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
returnData: true
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
);
|
).data;
|
||||||
|
|
||||||
const article: Article = await articleData.json();
|
|
||||||
const categories: DocsCategory[] = await categoryData.json();
|
|
||||||
const { website } = await parent();
|
const { website } = await parent();
|
||||||
|
|
||||||
return { website, article, categories, API_BASE_PREFIX };
|
return { website, article, categories, API_BASE_PREFIX };
|
||||||
@@ -47,66 +45,50 @@ export const actions: Actions = {
|
|||||||
headers["X-Original-Filename"] = coverFile.name;
|
headers["X-Original-Filename"] = coverFile.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadedImageData = await fetch(`${API_BASE_PREFIX}/rpc/upload_file`, {
|
const uploadedImage = await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/upload_file`, "POST", {
|
||||||
method: "POST",
|
|
||||||
headers,
|
headers,
|
||||||
body: coverFile ? await coverFile.arrayBuffer() : null
|
body: coverFile ? await coverFile.arrayBuffer() : null,
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const uploadedImage = await uploadedImageData.json();
|
if (!uploadedImage.success && (coverFile?.size ?? 0 > 0)) {
|
||||||
|
|
||||||
if (!uploadedImageData.ok && (coverFile?.size ?? 0 > 0)) {
|
|
||||||
return { success: false, message: uploadedImage.message };
|
return { success: false, message: uploadedImage.message };
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/article?id=eq.${params.articleId}`, {
|
return await apiRequest(
|
||||||
method: "PATCH",
|
fetch,
|
||||||
headers: {
|
`${API_BASE_PREFIX}/article?id=eq.${params.articleId}`,
|
||||||
"Content-Type": "application/json",
|
"PATCH",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
{
|
||||||
},
|
body: {
|
||||||
body: JSON.stringify({
|
|
||||||
title: data.get("title"),
|
title: data.get("title"),
|
||||||
meta_description: data.get("description"),
|
meta_description: data.get("description"),
|
||||||
meta_author: data.get("author"),
|
meta_author: data.get("author"),
|
||||||
cover_image: uploadedImage.file_id,
|
cover_image: uploadedImage.data?.file_id,
|
||||||
publication_date: data.get("publication-date"),
|
publication_date: data.get("publication-date"),
|
||||||
main_content: data.get("main-content"),
|
main_content: data.get("main-content"),
|
||||||
category: data.get("category"),
|
category: data.get("category"),
|
||||||
article_weight: data.get("article-weight") ? data.get("article-weight") : null
|
article_weight: data.get("article-weight") ? data.get("article-weight") : null
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully updated article" };
|
|
||||||
},
|
},
|
||||||
pasteImage: async ({ request, fetch, cookies, params }) => {
|
successMessage: "Successfully updated article"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
pasteImage: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
const file = data.get("file") as File;
|
const file = data.get("file") as File;
|
||||||
|
|
||||||
const fileData = await fetch(`${API_BASE_PREFIX}/rpc/upload_file`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/rpc/upload_file`, "POST", {
|
||||||
method: "POST",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/octet-stream",
|
"Content-Type": "application/octet-stream",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json",
|
Accept: "application/vnd.pgrst.object+json",
|
||||||
"X-Website-Id": params.websiteId,
|
"X-Website-Id": params.websiteId,
|
||||||
"X-Mimetype": file.type,
|
"X-Mimetype": file.type,
|
||||||
"X-Original-Filename": file.name
|
"X-Original-Filename": file.name
|
||||||
},
|
},
|
||||||
body: await file.arrayBuffer()
|
body: await file.arrayBuffer(),
|
||||||
|
successMessage: "Successfully uploaded image",
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const fileJSON = await fileData.json();
|
|
||||||
|
|
||||||
if (!fileData.ok) {
|
|
||||||
return { success: false, message: fileJSON.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully uploaded image", fileId: fileJSON.file_id };
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
import type { DocsCategory, DocsCategoryInput } from "$lib/db-schema";
|
import type { DocsCategory } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ parent, params, cookies, fetch }) => {
|
export const load: PageServerLoad = async ({ parent, params, fetch }) => {
|
||||||
const categoryData = await fetch(
|
const categories: DocsCategory[] = (
|
||||||
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/docs_category?website_id=eq.${params.websiteId}&order=category_weight.desc`,
|
`${API_BASE_PREFIX}/docs_category?website_id=eq.${params.websiteId}&order=category_weight.desc`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
returnData: true
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
);
|
).data;
|
||||||
|
|
||||||
const categories: DocsCategory[] = await categoryData.json();
|
|
||||||
const { website, home } = await parent();
|
const { website, home } = await parent();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -25,73 +24,44 @@ export const load: PageServerLoad = async ({ parent, params, cookies, fetch }) =
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
createCategory: async ({ request, fetch, cookies, params }) => {
|
createCategory: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/docs_category`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/docs_category`, "POST", {
|
||||||
method: "POST",
|
body: {
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
website_id: params.websiteId,
|
website_id: params.websiteId,
|
||||||
category_name: data.get("category-name") as string,
|
|
||||||
category_weight: data.get("category-weight") as unknown as number
|
|
||||||
} satisfies DocsCategoryInput)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully created category" };
|
|
||||||
},
|
|
||||||
updateCategory: async ({ request, fetch, cookies, params }) => {
|
|
||||||
const data = await request.formData();
|
|
||||||
|
|
||||||
const res = await fetch(
|
|
||||||
`${API_BASE_PREFIX}/docs_category?website_id=eq.${params.websiteId}&id=eq.${data.get("category-id")}`,
|
|
||||||
{
|
|
||||||
method: "PATCH",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
category_name: data.get("category-name"),
|
category_name: data.get("category-name"),
|
||||||
category_weight: data.get("category-weight")
|
category_weight: data.get("category-weight")
|
||||||
})
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully updated category" };
|
|
||||||
},
|
},
|
||||||
deleteCategory: async ({ request, fetch, cookies, params }) => {
|
successMessage: "Successfully created category"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateCategory: async ({ request, fetch }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(
|
return await apiRequest(
|
||||||
`${API_BASE_PREFIX}/docs_category?website_id=eq.${params.websiteId}&id=eq.${data.get("category-id")}`,
|
fetch,
|
||||||
|
`${API_BASE_PREFIX}/docs_category?id=eq.${data.get("category-id")}`,
|
||||||
|
"PATCH",
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
body: {
|
||||||
headers: {
|
category_name: data.get("category-name"),
|
||||||
"Content-Type": "application/json",
|
category_weight: data.get("category-weight")
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
},
|
||||||
}
|
successMessage: "Successfully updated category"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
deleteCategory: async ({ request, fetch }) => {
|
||||||
|
const data = await request.formData();
|
||||||
|
|
||||||
if (!res.ok) {
|
return await apiRequest(
|
||||||
const response = await res.json();
|
fetch,
|
||||||
return { success: false, message: response.message };
|
`${API_BASE_PREFIX}/docs_category?id=eq.${data.get("category-id")}`,
|
||||||
|
"DELETE",
|
||||||
|
{
|
||||||
|
successMessage: "Successfully deleted category"
|
||||||
}
|
}
|
||||||
|
);
|
||||||
return { success: true, message: "Successfully deleted category" };
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
import type { Collab, CollabInput, User } from "$lib/db-schema";
|
import type { Collab, User } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ parent, params, fetch, cookies }) => {
|
export const load: PageServerLoad = async ({ parent, params, fetch }) => {
|
||||||
const { website, home } = await parent();
|
const collaborators: (Collab & { user: User })[] = (
|
||||||
|
await apiRequest(
|
||||||
const collabData = await fetch(
|
fetch,
|
||||||
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&select=*,user!user_id(*)&order=last_modified_at.desc,added_at.desc`,
|
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&select=*,user!user_id(*)&order=last_modified_at.desc,added_at.desc`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
returnData: true
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
);
|
).data;
|
||||||
|
|
||||||
const collaborators: (Collab & { user: User })[] = await collabData.json();
|
const { website, home } = await parent();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
website,
|
website,
|
||||||
@@ -26,83 +24,57 @@ export const load: PageServerLoad = async ({ parent, params, fetch, cookies }) =
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
addCollaborator: async ({ request, fetch, cookies, params }) => {
|
addCollaborator: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const userData = await fetch(`${API_BASE_PREFIX}/user?username=eq.${data.get("username")}`, {
|
const user: User = (
|
||||||
method: "GET",
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
|
`${API_BASE_PREFIX}/user?username=eq.${data.get("username")}`,
|
||||||
|
"GET",
|
||||||
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const user: User = await userData.json();
|
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/collab`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
returnData: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).data;
|
||||||
|
|
||||||
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/collab`, "POST", {
|
||||||
|
body: {
|
||||||
website_id: params.websiteId,
|
website_id: params.websiteId,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
permission_level: data.get("permission-level") as unknown as number
|
|
||||||
} satisfies CollabInput)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully added collaborator" };
|
|
||||||
},
|
|
||||||
updateCollaborator: async ({ request, fetch, cookies, params }) => {
|
|
||||||
const data = await request.formData();
|
|
||||||
|
|
||||||
const res = await fetch(
|
|
||||||
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&user_id=eq.${data.get("user-id")}`,
|
|
||||||
{
|
|
||||||
method: "PATCH",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
permission_level: data.get("permission-level")
|
permission_level: data.get("permission-level")
|
||||||
})
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully updated collaborator" };
|
|
||||||
},
|
},
|
||||||
removeCollaborator: async ({ request, fetch, cookies, params }) => {
|
successMessage: "Successfully added collaborator"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateCollaborator: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(
|
return await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&user_id=eq.${data.get("user-id")}`,
|
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&user_id=eq.${data.get("user-id")}`,
|
||||||
|
"PATCH",
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
body: {
|
||||||
headers: {
|
permission_level: data.get("permission-level")
|
||||||
"Content-Type": "application/json",
|
},
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
successMessage: "Successfully updated collaborator"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
removeCollaborator: async ({ request, fetch, params }) => {
|
||||||
|
const data = await request.formData();
|
||||||
|
|
||||||
if (!res.ok) {
|
return await apiRequest(
|
||||||
const response = await res.json();
|
fetch,
|
||||||
return { success: false, message: response.message };
|
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&user_id=eq.${data.get("user-id")}`,
|
||||||
|
"DELETE",
|
||||||
|
{
|
||||||
|
successMessage: "Successfully removed collaborator"
|
||||||
}
|
}
|
||||||
|
);
|
||||||
return { success: true, message: "Successfully removed collaborator" };
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
import { rm } from "node:fs/promises";
|
import { rm } from "node:fs/promises";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import type { LegalInformation, LegalInformationInput } from "$lib/db-schema";
|
import type { LegalInformation } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ parent, fetch, params, cookies }) => {
|
export const load: PageServerLoad = async ({ parent, fetch, params }) => {
|
||||||
const legalInformationData = await fetch(
|
const legalInformation: LegalInformation = (
|
||||||
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/legal_information?website_id=eq.${params.websiteId}`,
|
`${API_BASE_PREFIX}/legal_information?website_id=eq.${params.websiteId}`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
|
},
|
||||||
|
returnData: true
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
);
|
).data;
|
||||||
|
|
||||||
const legalInformation: LegalInformation = await legalInformationData.json();
|
|
||||||
const { website } = await parent();
|
const { website } = await parent();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -27,48 +28,33 @@ export const load: PageServerLoad = async ({ parent, fetch, params, cookies }) =
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
createUpdateLegalInformation: async ({ request, fetch, cookies, params }) => {
|
createUpdateLegalInformation: async ({ request, fetch, params }) => {
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/legal_information`, {
|
return await apiRequest(fetch, `${API_BASE_PREFIX}/legal_information`, "POST", {
|
||||||
method: "POST",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Prefer: "resolution=merge-duplicates",
|
Prefer: "resolution=merge-duplicates",
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: {
|
||||||
website_id: params.websiteId,
|
website_id: params.websiteId,
|
||||||
main_content: data.get("main-content") as string
|
main_content: data.get("main-content")
|
||||||
} satisfies LegalInformationInput)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: `Successfully ${res.status === 201 ? "created" : "updated"} legal information`
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
deleteLegalInformation: async ({ fetch, cookies, params }) => {
|
successMessage: "Successfully created/updated legal information"
|
||||||
const res = await fetch(
|
});
|
||||||
|
},
|
||||||
|
deleteLegalInformation: async ({ fetch, params }) => {
|
||||||
|
const deleteLegalInformation = await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/legal_information?website_id=eq.${params.websiteId}`,
|
`${API_BASE_PREFIX}/legal_information?website_id=eq.${params.websiteId}`,
|
||||||
|
"DELETE",
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
successMessage: "Successfully deleted legal information"
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!deleteLegalInformation.success) {
|
||||||
const response = await res.json();
|
return deleteLegalInformation;
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await rm(
|
await rm(
|
||||||
@@ -76,6 +62,6 @@ export const actions: Actions = {
|
|||||||
{ force: true }
|
{ force: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
return { success: true, message: `Successfully deleted legal information` };
|
return deleteLegalInformation;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
const { data, form }: { data: PageServerData; form: ActionData } = $props();
|
const { data, form }: { data: PageServerData; form: ActionData } = $props();
|
||||||
|
|
||||||
let previewContent = $state(data.legalInformation.main_content);
|
let previewContent = $state(data.legalInformation?.main_content);
|
||||||
let mainContentTextarea: HTMLTextAreaElement;
|
let mainContentTextarea: HTMLTextAreaElement;
|
||||||
let textareaScrollTop = $state(0);
|
let textareaScrollTop = $state(0);
|
||||||
|
|
||||||
@@ -82,14 +82,14 @@
|
|||||||
bind:value={previewContent}
|
bind:value={previewContent}
|
||||||
bind:this={mainContentTextarea}
|
bind:this={mainContentTextarea}
|
||||||
onscroll={updateScrollPercentage}
|
onscroll={updateScrollPercentage}
|
||||||
required>{data.legalInformation.main_content ?? ""}</textarea
|
required>{data.legalInformation?.main_content ?? ""}</textarea
|
||||||
>
|
>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{#if data.legalInformation.main_content}
|
{#if data.legalInformation?.main_content}
|
||||||
<Modal id="delete-legal-information" text="Delete">
|
<Modal id="delete-legal-information" text="Delete">
|
||||||
<form
|
<form
|
||||||
action="?/deleteLegalInformation"
|
action="?/deleteLegalInformation"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { PageServerLoad } from "./$types";
|
import type { PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
import type { ChangeLog, User, Collab } from "$lib/db-schema";
|
import type { ChangeLog, User, Collab } from "$lib/db-schema";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ parent, fetch, params, cookies, url }) => {
|
export const load: PageServerLoad = async ({ parent, fetch, params, url }) => {
|
||||||
const userFilter = url.searchParams.get("logs_filter_user");
|
const userFilter = url.searchParams.get("logs_filter_user");
|
||||||
const resourceFilter = url.searchParams.get("logs_filter_resource");
|
const resourceFilter = url.searchParams.get("logs_filter_resource");
|
||||||
const operationFilter = url.searchParams.get("logs_filter_operation");
|
const operationFilter = url.searchParams.get("logs_filter_operation");
|
||||||
@@ -27,41 +27,30 @@ export const load: PageServerLoad = async ({ parent, fetch, params, cookies, url
|
|||||||
|
|
||||||
const constructedFetchUrl = `${baseFetchUrl}&${searchParams.toString()}&limit=50&offset=${resultOffset}`;
|
const constructedFetchUrl = `${baseFetchUrl}&${searchParams.toString()}&limit=50&offset=${resultOffset}`;
|
||||||
|
|
||||||
const changeLogData = await fetch(constructedFetchUrl, {
|
const changeLog: (ChangeLog & { user: { username: User["username"] } })[] = (
|
||||||
method: "GET",
|
await apiRequest(fetch, constructedFetchUrl, "GET", { returnData: true })
|
||||||
headers: {
|
).data;
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const resultChangeLogData = await fetch(constructedFetchUrl, {
|
const resultChangeLogData = await apiRequest(fetch, constructedFetchUrl, "HEAD", {
|
||||||
method: "HEAD",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Prefer: "count=exact"
|
Prefer: "count=exact"
|
||||||
}
|
},
|
||||||
|
returnData: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const resultChangeLogCount = Number(
|
const resultChangeLogCount = Number(
|
||||||
resultChangeLogData.headers.get("content-range")?.split("/").at(-1)
|
resultChangeLogData.data.headers.get("content-range")?.split("/").at(-1)
|
||||||
);
|
);
|
||||||
|
|
||||||
const collabData = await fetch(
|
const collaborators: (Collab & { user: User })[] = (
|
||||||
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&select=*,user!user_id(*)&order=last_modified_at.desc,added_at.desc`,
|
`${API_BASE_PREFIX}/collab?website_id=eq.${params.websiteId}&select=*,user!user_id(*)&order=last_modified_at.desc,added_at.desc`,
|
||||||
{
|
"GET",
|
||||||
method: "GET",
|
{ returnData: true }
|
||||||
headers: {
|
)
|
||||||
"Content-Type": "application/json",
|
).data;
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const changeLog: (ChangeLog & { user: { username: User["username"] } })[] =
|
|
||||||
await changeLogData.json();
|
|
||||||
const collaborators: (Collab & { user: User })[] = await collabData.json();
|
|
||||||
const { website, home } = await parent();
|
const { website, home } = await parent();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -2,29 +2,28 @@ import { readFile, mkdir, writeFile, rename } from "node:fs/promises";
|
|||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { type WebsiteOverview, slugify } from "$lib/utils";
|
import { type WebsiteOverview, slugify } from "$lib/utils";
|
||||||
import type { Actions, PageServerLoad } from "./$types";
|
import type { Actions, PageServerLoad } from "./$types";
|
||||||
import { API_BASE_PREFIX } from "$lib/server/utils";
|
import { API_BASE_PREFIX, apiRequest } from "$lib/server/utils";
|
||||||
import { render } from "svelte/server";
|
import { render } from "svelte/server";
|
||||||
import BlogIndex from "$lib/templates/blog/BlogIndex.svelte";
|
import BlogIndex from "$lib/templates/blog/BlogIndex.svelte";
|
||||||
import BlogArticle from "$lib/templates/blog/BlogArticle.svelte";
|
import BlogArticle from "$lib/templates/blog/BlogArticle.svelte";
|
||||||
import DocsIndex from "$lib/templates/docs/DocsIndex.svelte";
|
import DocsIndex from "$lib/templates/docs/DocsIndex.svelte";
|
||||||
import DocsArticle from "$lib/templates/docs/DocsArticle.svelte";
|
import DocsArticle from "$lib/templates/docs/DocsArticle.svelte";
|
||||||
import { dev } from "$app/environment";
|
import { dev } from "$app/environment";
|
||||||
import type { DomainPrefixInput } from "$lib/db-schema";
|
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ params, fetch, cookies }) => {
|
export const load: PageServerLoad = async ({ params, fetch }) => {
|
||||||
const websiteOverviewData = await fetch(
|
const websiteOverview: WebsiteOverview = (
|
||||||
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}&select=*,settings(*),header(*),home(*),footer(*),article(*,docs_category(*)),legal_information(*),domain_prefix(*)`,
|
`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}&select=*,settings(*),header(*),home(*),footer(*),article(*,docs_category(*)),legal_information(*),domain_prefix(*)`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
|
},
|
||||||
|
returnData: true
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
);
|
).data;
|
||||||
|
|
||||||
const websiteOverview: WebsiteOverview = await websiteOverviewData.json();
|
|
||||||
|
|
||||||
generateStaticFiles(websiteOverview);
|
generateStaticFiles(websiteOverview);
|
||||||
|
|
||||||
@@ -53,73 +52,66 @@ export const load: PageServerLoad = async ({ params, fetch, cookies }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
publishWebsite: async ({ fetch, params, cookies }) => {
|
publishWebsite: async ({ fetch, params }) => {
|
||||||
const websiteOverviewData = await fetch(
|
const websiteOverview: WebsiteOverview = (
|
||||||
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}&select=*,settings(*),header(*),home(*),footer(*),article(*,docs_category(*)),legal_information(*),domain_prefix(*)`,
|
`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}&select=*,settings(*),header(*),home(*),footer(*),article(*,docs_category(*)),legal_information(*),domain_prefix(*)`,
|
||||||
|
"GET",
|
||||||
{
|
{
|
||||||
method: "GET",
|
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
|
},
|
||||||
|
returnData: true
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
);
|
).data;
|
||||||
|
|
||||||
const websiteOverview = await websiteOverviewData.json();
|
|
||||||
generateStaticFiles(websiteOverview, false);
|
generateStaticFiles(websiteOverview, false);
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}`, {
|
return await apiRequest(
|
||||||
method: "PATCH",
|
fetch,
|
||||||
headers: {
|
`${API_BASE_PREFIX}/website?id=eq.${params.websiteId}`,
|
||||||
"Content-Type": "application/json",
|
"PATCH",
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
is_published: true
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const response = await res.json();
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, message: "Successfully published website" };
|
|
||||||
},
|
|
||||||
createUpdateCustomDomainPrefix: async ({ request, fetch, params, cookies }) => {
|
|
||||||
const data = await request.formData();
|
|
||||||
|
|
||||||
const oldDomainPrefixData = await fetch(
|
|
||||||
`${API_BASE_PREFIX}/domain_prefix?website_id=eq.${params.websiteId}`,
|
|
||||||
{
|
{
|
||||||
method: "GET",
|
body: {
|
||||||
headers: {
|
is_published: true
|
||||||
"Content-Type": "application/json",
|
},
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
successMessage: "Successfully published website"
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const oldDomainPrefix = await oldDomainPrefixData.json();
|
},
|
||||||
|
createUpdateCustomDomainPrefix: async ({ request, fetch, params }) => {
|
||||||
|
const data = await request.formData();
|
||||||
|
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/domain_prefix`, {
|
const oldDomainPrefix = (
|
||||||
method: "POST",
|
await apiRequest(
|
||||||
|
fetch,
|
||||||
|
`${API_BASE_PREFIX}/domain_prefix?website_id=eq.${params.websiteId}`,
|
||||||
|
"GET",
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
|
},
|
||||||
|
returnData: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).data;
|
||||||
|
|
||||||
|
const newDomainPrefix = await apiRequest(fetch, `${API_BASE_PREFIX}/domain_prefix`, "POST", {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Prefer: "resolution=merge-duplicates",
|
Prefer: "resolution=merge-duplicates",
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: {
|
||||||
website_id: params.websiteId,
|
website_id: params.websiteId,
|
||||||
prefix: data.get("domain-prefix") as string
|
prefix: data.get("domain-prefix") as string
|
||||||
} satisfies DomainPrefixInput)
|
},
|
||||||
|
successMessage: "Successfully created/updated domain prefix"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!newDomainPrefix.success) {
|
||||||
const response = await res.json();
|
return newDomainPrefix;
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await rename(
|
await rename(
|
||||||
@@ -128,39 +120,38 @@ export const actions: Actions = {
|
|||||||
"var",
|
"var",
|
||||||
"www",
|
"www",
|
||||||
"archtika-websites",
|
"archtika-websites",
|
||||||
res.status === 201 ? params.websiteId : oldDomainPrefix.prefix
|
oldDomainPrefix?.prefix ? oldDomainPrefix.prefix : params.websiteId
|
||||||
),
|
),
|
||||||
join("/", "var", "www", "archtika-websites", data.get("domain-prefix") as string)
|
join("/", "var", "www", "archtika-websites", data.get("domain-prefix") as string)
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return newDomainPrefix;
|
||||||
success: true,
|
|
||||||
message: `Successfully ${res.status === 201 ? "created" : "updated"} domain prefix`
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
deleteCustomDomainPrefix: async ({ fetch, params, cookies }) => {
|
deleteCustomDomainPrefix: async ({ fetch, params }) => {
|
||||||
const res = await fetch(`${API_BASE_PREFIX}/domain_prefix?website_id=eq.${params.websiteId}`, {
|
const customPrefix = await apiRequest(
|
||||||
method: "DELETE",
|
fetch,
|
||||||
|
`${API_BASE_PREFIX}/domain_prefix?website_id=eq.${params.websiteId}`,
|
||||||
|
"DELETE",
|
||||||
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${cookies.get("session_token")}`,
|
|
||||||
Prefer: "return=representation",
|
Prefer: "return=representation",
|
||||||
Accept: "application/vnd.pgrst.object+json"
|
Accept: "application/vnd.pgrst.object+json"
|
||||||
|
},
|
||||||
|
successMessage: "Successfully deleted domain prefix",
|
||||||
|
returnData: true
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
const response = await res.json();
|
if (!customPrefix.success) {
|
||||||
|
return customPrefix;
|
||||||
if (!res.ok) {
|
|
||||||
return { success: false, message: response.message };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await rename(
|
await rename(
|
||||||
join("/", "var", "www", "archtika-websites", response.prefix),
|
join("/", "var", "www", "archtika-websites", customPrefix.data.prefix),
|
||||||
join("/", "var", "www", "archtika-websites", params.websiteId)
|
join("/", "var", "www", "archtika-websites", params.websiteId)
|
||||||
);
|
);
|
||||||
|
|
||||||
return { success: true, message: `Successfully deleted domain prefix` };
|
return customPrefix;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,6 +169,8 @@ const generateStaticFiles = async (websiteData: WebsiteOverview, isPreview = tru
|
|||||||
</html>`;
|
</html>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(websiteData);
|
||||||
|
|
||||||
const { head, body } = render(websiteData.content_type === "Blog" ? BlogIndex : DocsIndex, {
|
const { head, body } = render(websiteData.content_type === "Blog" ? BlogIndex : DocsIndex, {
|
||||||
props: {
|
props: {
|
||||||
websiteOverview: websiteData,
|
websiteOverview: websiteData,
|
||||||
|
|||||||
@@ -34,6 +34,10 @@
|
|||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>archtika | {routeName.replaceAll("/", " - ")}</title>
|
<title>archtika | {routeName.replaceAll("/", " - ")}</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="FLOSS, modern, performant and lightweight CMS (Content Mangement System) with predefined templates"
|
||||||
|
/>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ test.describe.serial("Collaborator tests", () => {
|
|||||||
await page.getByRole("button", { name: "Submit" }).click();
|
await page.getByRole("button", { name: "Submit" }).click();
|
||||||
|
|
||||||
if (permissionLevel === 30) {
|
if (permissionLevel === 30) {
|
||||||
await expect(page.getByText("Successfully created legal")).toBeVisible();
|
await expect(page.getByText("Successfully created/updated legal")).toBeVisible();
|
||||||
} else {
|
} else {
|
||||||
await expect(page.getByText("Insufficient permissions")).toBeVisible();
|
await expect(page.getByText("Insufficient permissions")).toBeVisible();
|
||||||
}
|
}
|
||||||
@@ -345,7 +345,7 @@ test.describe.serial("Collaborator tests", () => {
|
|||||||
await page.getByRole("button", { name: "Submit" }).click();
|
await page.getByRole("button", { name: "Submit" }).click();
|
||||||
|
|
||||||
if (permissionLevel === 30) {
|
if (permissionLevel === 30) {
|
||||||
await expect(page.getByText("Successfully updated legal")).toBeVisible();
|
await expect(page.getByText("Successfully created/updated legal")).toBeVisible();
|
||||||
} else {
|
} else {
|
||||||
await expect(page.getByText("Insufficient permissions")).toBeVisible();
|
await expect(page.getByText("Insufficient permissions")).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,12 +238,12 @@ test.describe.serial("Website tests", () => {
|
|||||||
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").click();
|
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").click();
|
||||||
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").fill("## Content");
|
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").fill("## Content");
|
||||||
await page.getByRole("button", { name: "Submit" }).click();
|
await page.getByRole("button", { name: "Submit" }).click();
|
||||||
await expect(page.getByText("Successfully created legal")).toBeVisible();
|
await expect(page.getByText("Successfully created/updated legal")).toBeVisible();
|
||||||
|
|
||||||
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").click();
|
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").click();
|
||||||
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").fill("## Content updated");
|
await page.getByPlaceholder("## Impressum\n\n## Privacy policy").fill("## Content updated");
|
||||||
await page.getByRole("button", { name: "Submit" }).click();
|
await page.getByRole("button", { name: "Submit" }).click();
|
||||||
await expect(page.getByText("Successfully updated legal")).toBeVisible();
|
await expect(page.getByText("Successfully created/updated legal")).toBeVisible();
|
||||||
});
|
});
|
||||||
test("Delete legal information", async ({ authenticatedPage: page }) => {
|
test("Delete legal information", async ({ authenticatedPage: page }) => {
|
||||||
await page.getByRole("link", { name: "Blog" }).click();
|
await page.getByRole("link", { name: "Blog" }).click();
|
||||||
|
|||||||
Reference in New Issue
Block a user