generated from autonomic-cooperative/astro-payload-template
Initial commit
This commit is contained in:
27
astro/src/components/Content.astro
Normal file
27
astro/src/components/Content.astro
Normal 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
1
astro/src/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="astro/client" />
|
36
astro/src/layouts/Layout.astro
Normal file
36
astro/src/layouts/Layout.astro
Normal 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>
|
45
astro/src/pages/index.astro
Normal file
45
astro/src/pages/index.astro
Normal 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>
|
31
astro/src/pages/posts/[id].astro
Normal file
31
astro/src/pages/posts/[id].astro
Normal 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>
|
||||
)
|
||||
}
|
41
astro/src/utils/helpers.ts
Normal file
41
astro/src/utils/helpers.ts
Normal 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> </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;
|
||||
};
|
13
astro/src/utils/payload.ts
Normal file
13
astro/src/utils/payload.ts
Normal 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}`;
|
Reference in New Issue
Block a user