backend and api endpoints

This commit is contained in:
2023-07-14 11:58:27 +00:00
parent 90b4c95cd8
commit 897b9ae2cf
27 changed files with 1140 additions and 20 deletions

View File

@@ -2,8 +2,12 @@
import Footer from "./lib/components/Footer.svelte"
import Header from "./lib/components/Menu/Header.svelte"
import Menu from "./lib/components/Menu/Menu.svelte"
import { location } from "./store"
import NotFound from "./lib/components/NotFound.svelte"
import Rows from "./lib/components/Pagebuilder/Rows.svelte"
import { location, navigation, pages, serviceNavigation } from "./lib/store"
import { Route, Router } from "svelte-routing"
import { loadPages } from "./lib/functions/getPages"
import { loadNavigation } from "./lib/functions/loadNavigation"
export let url = ""
if (url) {
@@ -18,12 +22,45 @@
}
}
if (typeof window !== "undefined") console.log("App initialized")
let activeMenu = true
async function getPages() {
let pagesArray = await loadPages()
let pagesRes: Pages = {}
pagesArray.forEach((e) => {
pagesRes[e.path] = e
})
$pages = pagesRes
console.log(pagesRes)
}
async function getNavigation() {
let nav: Navigation[] = await loadNavigation()
console.log(nav)
$navigation = nav[0]
$serviceNavigation = nav[1]
}
getNavigation()
getPages()
let activeMenu = false
</script>
<main class="">
<Header bind:active="{activeMenu}" />
<div class="content-container" id="siteContainer" data-url="{url}">
<Router url="{url}">
<Route path="/">
<Rows path="/" homepage="{true}" />
</Route>
<Route path="/*path" let:params>
<Rows path="/{params?.path}" homepage="{false}" />
</Route>
<Route>
<NotFound />
</Route>
</Router>
</div>
<Footer />
</main>

121
frontend/src/api.ts Normal file
View File

@@ -0,0 +1,121 @@
import { apiBaseURL } from "./config"
const _f = function (url, options): Promise<Response> {
if (typeof XMLHttpRequest === "undefined") {
return Promise.resolve(null)
}
options = options || {}
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest()
const keys = []
const all = []
const headers = {}
const response = (): Response => ({
ok: ((request.status / 100) | 0) == 2, // 200-299
statusText: request.statusText,
status: request.status,
url: request.responseURL,
text: () => Promise.resolve(request.responseText),
json: () => Promise.resolve(request.responseText).then(JSON.parse),
blob: () => Promise.resolve(new Blob([request.response])),
clone: response,
headers: {
// @ts-ignore
keys: () => keys,
// @ts-ignore
entries: () => all,
get: (n) => headers[n.toLowerCase()],
has: (n) => n.toLowerCase() in headers,
},
})
request.open(options.method || "get", url, true)
request.onload = () => {
request
.getAllResponseHeaders()
// @ts-ignore
.replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, (m, key, value) => {
keys.push((key = key.toLowerCase()))
all.push([key, value])
headers[key] = headers[key] ? `${headers[key]},${value}` : value
})
resolve(response())
}
request.onerror = reject
request.withCredentials = options.credentials == "include"
for (const i in options.headers) {
request.setRequestHeader(i, options.headers[i])
}
request.send(options.body || null)
})
}
const _fetch = typeof fetch === "undefined" ? (typeof window === "undefined" ? _f : window.fetch || _f) : fetch
export const api = async <T>(
endpoint: string,
options?: {
method?: string
filter?: any
sort?: string
limit?: number
offset?: number
projection?: string
headers?: {
[key: string]: string
}
params?: {
[key: string]: string
}
},
body?: any
): Promise<{ data: T; count: number } | any> => {
if (typeof window === "undefined") {
// ssr
// @ts-ignore
return context.ssrFetch(endpoint, options)
}
let method = options?.method || "GET"
let query = "&count=1"
if (options?.filter) query += "&filter=" + encodeURIComponent(JSON.stringify(options.filter))
if (options?.sort) query += "&sort=" + options.sort + "&sort=_id"
if (options?.limit) query += "&limit=" + options.limit
if (options?.offset) query += "&offset=" + options.offset
if (options?.projection) query += "&projection=" + options.projection
if (options?.params) {
Object.keys(options.params).forEach((p) => {
query += "&" + p + "=" + encodeURIComponent(options.params[p])
})
}
let headers: any = {
"Content-Type": "application/json",
}
if (options?.headers) headers = { ...headers, ...options.headers }
let url = apiBaseURL + endpoint + (query ? "?" + query : "")
const requestOptions: any = {
method,
mode: "cors",
headers,
}
if (method === "POST" || method === "PUT") {
requestOptions.body = JSON.stringify(body)
}
let response = await _fetch(url, requestOptions)
if (response.status == 409 || response.status == 401) return response
let data = (await response?.json()) || null
// @ts-ignore
return { data }
}

View File

@@ -1,5 +1,5 @@
import App from "./App.svelte"
import { location } from "./store"
import { location } from "./lib/store"
const publishLocation = (_p?: string) => {
let _s: string

View File

@@ -0,0 +1,52 @@
<script>
import { navigate } from "svelte-routing"
</script>
<div class="not-found">
<div class="content">
<h1>404</h1>
<h2>Seite nicht gefunden</h2>
<p>
Die gesuchte Seite wurde möglicherweise entfernt, ihr Name wurde geändert oder sie ist vorübergehend nicht
verfügbar.
</p>
<button on:click="{() => navigate('/')}" class="back-home">Zurück zur Startseite</button>
</div>
</div>
<style lang="less">
@import "../assets/css/main.less";
.not-found {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
.content {
text-align: center;
padding: 2rem;
background-color: rgba(255, 255, 255, 0.9);
h1 {
font-size: 6rem;
margin-bottom: 2rem;
}
h2 {
font-size: 2rem;
margin-bottom: 1rem;
}
p {
margin-bottom: 2rem;
}
.back-home {
text-decoration: none;
border: 1px solid black;
padding: 0.5rem 1rem;
transition: background-color 0.2s, color 0.2s;
}
}
}
</style>

View File

@@ -0,0 +1,5 @@
<script lang="ts">
export let row: Row
</script>
<stlye lang="less"></stlye>

View File

@@ -0,0 +1,8 @@
<script lang="ts">
export let row: Row
</script>
<div></div>
<style lang="less">
</style>

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import { init } from "svelte/internal"
import { pages } from "../../store"
export let path
export let homepage = false
let page: Page
function initPage() {
page = $pages[path]
}
$: {
if (Object.keys($pages).length) {
initPage()
}
}
</script>
<div>
{#if page}
{page.path}
{/if}
</div>
<style lang="less">
</style>

View File

@@ -0,0 +1,6 @@
import { api } from "../../api"
export async function loadPages(): Promise<Page[]> {
let site = await api<Page[]>("page", {})
return site.data
}

View File

@@ -0,0 +1,6 @@
import { api } from "../../api"
export async function loadNavigation(): Promise<Navigation[]> {
let nav = await api<Navigation[]>("navigation", {})
return nav.data
}

View File

@@ -8,4 +8,8 @@ const initLoc = {
pop: false,
categoryPath: "",
}
export const location = writable(initLoc)
export const location = writable(initLoc)
export let navigation = writable<Navigation>()
export let pages = writable<Pages>({})
export let serviceNavigation = writable<Navigation>()