Initial commit

This commit is contained in:
Autonomic Cooperative
2024-05-17 22:32:32 +00:00
commit d07472434f
43 changed files with 12506 additions and 0 deletions

View File

@ -0,0 +1,27 @@
---
import { Image } from "@astrojs/image/components";
import { getContentArray } from "@/utils/helpers";
import { getImageSrc } from "@/utils/payload";
const { content } = Astro.props;
const contentArray = getContentArray(content);
---
<div>
{
contentArray.map((value) => {
if (typeof value === "string") {
return <article set:html={value} />;
} else {
return (
<Image
src={getImageSrc(value.src)}
width={value.width}
height={value.height}
format="webp"
alt="hallo"
/>
);
}
})
}
</div>

1
astro/src/env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="astro/client" />

View File

@ -0,0 +1,36 @@
---
export interface Props {
title: string;
}
const { title } = Astro.props;
---
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title}</title>
<style>
@font-face {
font-family: "Plex";
src: url("/fonts/Plex-Regular.woff2") format("woff2");
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Plex";
src: url("/fonts/Plex-Bold.woff2") format("woff2");
font-weight: bold;
font-style: normal;
font-display: swap;
}
</style>
</head>
<body class="mx-auto max-w-7xl bg-gray px-6 py-8 font-plex text-gray-200">
<slot />
</body>
</html>

View File

@ -0,0 +1,45 @@
---
import Layout from "@/layouts/Layout.astro";
import { getPosts } from "@/utils/payload";
const posts = await getPosts();
---
<Layout title="Astroad">
<main class="" >
<h1 class="font-bold text-5xl">Astroad</h1>
<p class="mt-3 text-lg">
Astroad is a pre-configured setup for Astro and Payloadcms that makes it
easy to get started with building your website. With Astroad, you'll have
a complete development environment that you can run locally using Docker.
This makes it easy to test and develop your website before deploying it to
a production environment.
<br />
When you're ready to deploy the website on your own server, Astrotus
comes with a production environment that requires the use of Traefik as a
reverse proxy. This setup provides a secure and scalable production
environment for your website.
</p>
<h2 class="mt-6 font-bold text-2xl">Posts</h2>
<div class="flex gap-4 mt-3 flex-wrap">
{
posts.length > 0 ? (
posts.map((post) => (
<a href={`/posts/${post.id}/`}>
<article class="text-gray bg-gray-light px-5 py-3 rounded-md shadow-md w-64 text-center hover:-translate-y-1 transition-transform">
<h3 class="font-bold text-lg" transition:name=`title-${post.id}`>{post.title}</h3>
{post.publishedDate && (
<p>
{new Date(post.publishedDate).toLocaleDateString("de-DE")}
</p>
)}
</article>
</a>
))
) : (
<p>Add Posts in Payloadcms</p>
)
}
</div>
</main>
</Layout>

View File

@ -0,0 +1,31 @@
---
import Layout from "@/layouts/Layout.astro";
import Content from "@/components/Content.astro";
import type { Post } from "@/types";
import { getPost, getPosts } from "@/utils/payload";
export async function getStaticPaths() {
const posts = await getPosts();
const paths = posts.map((post: Post) => ({
params: { id: post.id },
}));
return paths;
}
const { id } = Astro.params;
const post = id && (await getPost(id));
---
{
post ? (
<Layout title={`Astroad | ${post.title!}`}>
<div class="space-y-3 my-3">
<a href="/">BACK</a>
<h1 class="font-bold text-5xl" transition:name=`title-${post.id}`>{post.title}</h1>
{post.content && <Content content={post.content} />}
</div>
</Layout>
) : (
<div>404</div>
)
}

View File

@ -0,0 +1,41 @@
import { payloadSlateToDomConfig, slateToHtml } from "slate-serializers";
import { Element } from "domhandler";
export const getContentArray = (content: any) => {
const html = slateToHtml(content, {
...payloadSlateToDomConfig,
elementTransforms: {
...payloadSlateToDomConfig.elementTransforms,
upload: ({ node }) =>
// @ts-ignore
new Element("img", {
src: node.value.filename,
width: `${node.value.width}`,
height: `${node.value.height}`,
}),
},
}).replaceAll("<p></p>", "<p>&nbsp;</p>");
const htmlImageArray: (
| string
| { src: string; width: number; height: number }
)[] = [];
let lastIndex = 0;
while (true) {
const imgStartIndex = html.indexOf("<img", lastIndex);
if (imgStartIndex === -1) {
htmlImageArray.push(html.substring(lastIndex));
break;
}
const imgEndIndex = html.indexOf(">", imgStartIndex) + 1;
const imgTag = html.substring(imgStartIndex, imgEndIndex);
const remainingHtml = html.substring(lastIndex, imgStartIndex);
const imgObject = {
src: imgTag.match(/src="(.*?)"/)![1],
width: +imgTag.match(/width="(.*?)"/)![1],
height: +imgTag.match(/height="(.*?)"/)![1],
};
htmlImageArray.push(remainingHtml, imgObject);
lastIndex = imgEndIndex;
}
return htmlImageArray;
};

View File

@ -0,0 +1,13 @@
import type { Post } from "@/types";
const url = import.meta.env.DEV
? "http://payload:3001"
: `${import.meta.env.PAYLOAD_URL}`;
export const getPosts = async () =>
(await (await fetch(`${url}/api/posts`)).json()).docs as Post[];
export const getPost = async (id: string) =>
(await (await fetch(`${url}/api/posts/${id}`)).json()) as Post;
export const getImageSrc = (src: string) => `${url}/media/${src}`;