init pole elements collection
This commit is contained in:
@@ -1,5 +1,11 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({});
|
export default defineConfig({
|
||||||
|
vite: {
|
||||||
|
plugins: [tailwindcss()]
|
||||||
|
}
|
||||||
|
});
|
||||||
4894
client/package-lock.json
generated
Normal file
4894
client/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,11 @@
|
|||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"astro": "^5.7.12"
|
"@tailwindcss/vite": "^4.1.10",
|
||||||
|
"@types/qs": "^6.14.0",
|
||||||
|
"astro": "^5.7.12",
|
||||||
|
"marked": "^15.0.12",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"tailwindcss": "^4.1.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
client/src/components/MardownContent.astro
Normal file
7
client/src/components/MardownContent.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import { marked } from "marked";
|
||||||
|
const { content, ...otherProps } = Astro.props
|
||||||
|
const markedContent = marked.parse(Astro.props.content);
|
||||||
|
---
|
||||||
|
|
||||||
|
<div set:html={markedContent} {...otherProps} />
|
||||||
61
client/src/content.config.mjs
Normal file
61
client/src/content.config.mjs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { defineCollection, z } from "astro:content";
|
||||||
|
import qs from "qs";
|
||||||
|
|
||||||
|
// Define a custom content collection that loads data from Strapi
|
||||||
|
const strapiPoleElementsLoader = defineCollection({
|
||||||
|
// Async loader function that fetches data from Strapi API
|
||||||
|
loader: async () => {
|
||||||
|
// Get Strapi URL from environment variables or fallback to localhost
|
||||||
|
const BASE_URL = import.meta.env.STRAPI_URL || "http://localhost:1337";
|
||||||
|
const path = "/api/elements";
|
||||||
|
const url = new URL(path, BASE_URL);
|
||||||
|
|
||||||
|
// Build query parameters using qs to populate cover image data
|
||||||
|
url.search = qs.stringify({
|
||||||
|
populate: {
|
||||||
|
mainImage: {
|
||||||
|
fields: ["url", "alternativeText"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fetch articles from Strapi
|
||||||
|
const poleElementsData = await fetch(url.href);
|
||||||
|
const { data }= await poleElementsData.json();
|
||||||
|
// Transform the API response into the desired data structure
|
||||||
|
return data.map((item) => ({
|
||||||
|
id: item.id.toString(),
|
||||||
|
name: item.name,
|
||||||
|
description: item.description,
|
||||||
|
createdAt: item.createdAt,
|
||||||
|
updatedAt: item.updatedAt,
|
||||||
|
publishedAt: item.publishedAt,
|
||||||
|
mainImage: {
|
||||||
|
id: Number(item.mainImage.id),
|
||||||
|
documentId: item.mainImage.documentId,
|
||||||
|
url: item.mainImage.url,
|
||||||
|
alternativeText: item.mainImage.alternativeText,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
// Define the schema for type validation using Zod
|
||||||
|
schema: z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
createdAt: z.string(),
|
||||||
|
updatedAt: z.string(),
|
||||||
|
publishedAt: z.string(),
|
||||||
|
mainImage: z.object({
|
||||||
|
id: z.number(),
|
||||||
|
documentId: z.string(),
|
||||||
|
url: z.string(),
|
||||||
|
alternativeText: z.string(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export the collection for use in Astro pages
|
||||||
|
export const collections = {
|
||||||
|
strapiPoleElementsLoader,
|
||||||
|
};
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
---
|
||||||
|
import "../styles/global.css";
|
||||||
|
---
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -1,11 +1,51 @@
|
|||||||
---
|
---
|
||||||
import Welcome from '../components/Welcome.astro';
|
// Import necessary components and utilities
|
||||||
import Layout from '../layouts/Layout.astro';
|
import Layout from '../layouts/Layout.astro';
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
import MarkdownComponent from "../components/MardownContent.astro";
|
||||||
|
|
||||||
// Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build
|
// Fetch all posts from Strapi using Astro's content collection
|
||||||
// Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh.
|
const strapiPoleElements = await getCollection("strapiPoleElementsLoader");
|
||||||
|
// Get Strapi URL from environment variables with fallback to localhost
|
||||||
|
const BASE_URL = await import.meta.env.STRAPI_URL || "http://localhost:1337";
|
||||||
|
|
||||||
|
// Helper function to handle media URLs from Strapi
|
||||||
|
function getStrapiMedia(url: string | null) {
|
||||||
|
if (url == null) return null;
|
||||||
|
// Return as-is if it's a data URL (base64)
|
||||||
|
if (url.startsWith("data:")) return url;
|
||||||
|
// Return as-is if it's an absolute URL
|
||||||
|
if (url.startsWith("http") || url.startsWith("//")) return url;
|
||||||
|
// Prepend BASE_URL for relative URLs
|
||||||
|
return `${BASE_URL}${url}`;
|
||||||
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
<Welcome />
|
<div class="container mx-auto p-4">
|
||||||
</Layout>
|
<!-- Main heading -->
|
||||||
|
<h1 class="text-3xl font-bold mb-8">Hello Strapi 5 and Astro 5 World</h1>
|
||||||
|
<!-- Responsive grid layout using Tailwind CSS -->
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
|
{/* Map through posts and create article cards */}
|
||||||
|
{strapiPoleElements.map((post) => (
|
||||||
|
<article class="bg-white rounded-lg shadow-lg overflow-hidden">
|
||||||
|
{/* Post cover image */}
|
||||||
|
<img
|
||||||
|
src={getStrapiMedia(post.data.mainImage.url)}
|
||||||
|
alt={post.data.mainImage.alternativeText}
|
||||||
|
class="w-full h-48 object-cover"
|
||||||
|
/>
|
||||||
|
{/* Post content container */}
|
||||||
|
<div class="p-4">
|
||||||
|
<h2 class="text-xl font-bold mb-2">{post.data.name}</h2>
|
||||||
|
<MarkdownComponent content={post.data.description} class="text-gray-600 mb-4"/>
|
||||||
|
<div class="text-sm text-gray-500">
|
||||||
|
Published: {new Date(post.data.publishedAt).toLocaleDateString()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
1
client/src/styles/global.css
Normal file
1
client/src/styles/global.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
Reference in New Issue
Block a user