use strapi client, use locals for strapi url
This commit is contained in:
parent
817c3a78ac
commit
0e94cb95ca
11 changed files with 144 additions and 110 deletions
6
src/app.d.ts
vendored
6
src/app.d.ts
vendored
|
|
@ -3,7 +3,11 @@
|
|||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
interface Locals {
|
||||
Strapi: {
|
||||
url: string;
|
||||
};
|
||||
}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { HandleServerError } from '@sveltejs/kit';
|
||||
import { env } from '$env/dynamic/private';
|
||||
import type { Handle, HandleServerError } from '@sveltejs/kit';
|
||||
import { randomUUID } from 'crypto';
|
||||
|
||||
export const handleError: HandleServerError = async ({ error, event, message, status }) => {
|
||||
|
|
@ -11,3 +12,10 @@ export const handleError: HandleServerError = async ({ error, event, message, st
|
|||
errorId
|
||||
};
|
||||
};
|
||||
|
||||
export const handle: Handle = async ({ event, resolve }) => {
|
||||
event.locals.Strapi.url = `http://${env.STRAPI_HOST}:${env.STRAPI_PORT}`;
|
||||
|
||||
const response = await resolve(event);
|
||||
return response;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,24 +3,24 @@
|
|||
import { Link } from 'lucide-svelte';
|
||||
|
||||
interface Props {
|
||||
documentId: string;
|
||||
id: string;
|
||||
img: string;
|
||||
'img-alt': string | null;
|
||||
title: string;
|
||||
published: string;
|
||||
topics: { id: number; Topic: string }[];
|
||||
topics: { id: number; name: string }[];
|
||||
}
|
||||
|
||||
let { documentId, img, 'img-alt': alt, title, published, topics }: Props = $props();
|
||||
let { id, img, 'img-alt': alt, title, published, topics }: Props = $props();
|
||||
|
||||
let blogLink = $derived(`/blog/${documentId}`);
|
||||
let blogLink = $derived(`/blog/${id}`);
|
||||
</script>
|
||||
|
||||
<div class="card">
|
||||
<figure class="rounded-box group">
|
||||
<div class="absolute top-4 left-4 z-10 flex gap-2">
|
||||
{#each topics as topic (topic.id)}
|
||||
<div class="badge badge-soft badge-info">{topic.Topic}</div>
|
||||
<div class="badge badge-soft badge-info">{topic.name}</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="absolute z-10 opacity-0 transition-opacity group-hover:opacity-75">
|
||||
|
|
|
|||
56
src/lib/types/Blog.ts
Normal file
56
src/lib/types/Blog.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
type Dates = {
|
||||
createdAt: string;
|
||||
updateAt: string;
|
||||
publishedAt: string;
|
||||
};
|
||||
|
||||
export interface BlogPost extends Dates {
|
||||
id: number;
|
||||
documentId: string;
|
||||
Title: string;
|
||||
Header: Image;
|
||||
Body: string;
|
||||
Topics: Topic[];
|
||||
}
|
||||
|
||||
interface Topic {
|
||||
id: number;
|
||||
Topic: string;
|
||||
}
|
||||
|
||||
interface ImageFormat {
|
||||
ext: string;
|
||||
url: string;
|
||||
hash: string;
|
||||
mime: string;
|
||||
name: string;
|
||||
path: unknown;
|
||||
size: number;
|
||||
width: number;
|
||||
height: number;
|
||||
sizeInBytes: number;
|
||||
}
|
||||
|
||||
interface Image extends Dates {
|
||||
id: number;
|
||||
documentId: string;
|
||||
name: string;
|
||||
alternativeText: string | null;
|
||||
caption: string | null;
|
||||
width: string;
|
||||
height: string;
|
||||
formats: {
|
||||
large: ImageFormat;
|
||||
medium: ImageFormat;
|
||||
small: ImageFormat;
|
||||
thumbnail: ImageFormat;
|
||||
};
|
||||
hash: string;
|
||||
ext: string;
|
||||
mime: string;
|
||||
size: number;
|
||||
url: string;
|
||||
previewUrl: string | null;
|
||||
provider: string;
|
||||
provider_metadata: unknown | null;
|
||||
}
|
||||
0
src/lib/types/index.ts
Normal file
0
src/lib/types/index.ts
Normal file
|
|
@ -1,89 +1,39 @@
|
|||
import { env } from '$env/dynamic/private';
|
||||
import { strapi } from '@strapi/client';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
type Dates = {
|
||||
createdAt: string;
|
||||
updateAt: string;
|
||||
publishedAt: string;
|
||||
};
|
||||
export const load: PageServerLoad = async ({ locals }) => {
|
||||
const { Strapi } = locals;
|
||||
|
||||
interface BlogPost extends Dates {
|
||||
id: number;
|
||||
documentId: string;
|
||||
Title: string;
|
||||
Header: Image;
|
||||
Body: string;
|
||||
Topics: Topic[];
|
||||
}
|
||||
const client = strapi({
|
||||
baseURL: Strapi.url,
|
||||
auth: env.STRAPI_TOKEN
|
||||
});
|
||||
|
||||
interface Topic {
|
||||
id: number;
|
||||
Topic: string;
|
||||
}
|
||||
const blogs = client.collection('blogs');
|
||||
|
||||
interface ImageFormat {
|
||||
ext: string;
|
||||
url: string;
|
||||
hash: string;
|
||||
mime: string;
|
||||
name: string;
|
||||
path: unknown;
|
||||
size: number;
|
||||
width: number;
|
||||
height: number;
|
||||
sizeInBytes: number;
|
||||
}
|
||||
|
||||
interface Image extends Dates {
|
||||
id: number;
|
||||
documentId: string;
|
||||
name: string;
|
||||
alternativeText: string | null;
|
||||
caption: string | null;
|
||||
width: string;
|
||||
height: string;
|
||||
formats: {
|
||||
large: ImageFormat;
|
||||
medium: ImageFormat;
|
||||
small: ImageFormat;
|
||||
thumbnail: ImageFormat;
|
||||
};
|
||||
hash: string;
|
||||
ext: string;
|
||||
mime: string;
|
||||
size: number;
|
||||
url: string;
|
||||
previewUrl: string | null;
|
||||
provider: string;
|
||||
provider_metadata: unknown | null;
|
||||
}
|
||||
|
||||
interface Meta {
|
||||
pagingation: {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
pageCount: number;
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
|
||||
export const load: PageServerLoad = async () => {
|
||||
const response = await fetch(
|
||||
`http://${env.STRAPI_HOST}:${env.STRAPI_PORT}/api/blogs?populate=Header&populate=Topics`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `bearer ${env.STRAPI_TOKEN}`
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const { data, meta }: { data: BlogPost[]; meta: Meta } = await response.json();
|
||||
|
||||
console.log(JSON.stringify(data, null, 2));
|
||||
const { data, meta } = await blogs.find({
|
||||
populate: ['Header', 'Topics']
|
||||
});
|
||||
|
||||
return {
|
||||
posts: data,
|
||||
strapi: {
|
||||
url: Strapi.url
|
||||
},
|
||||
posts: data.map((post) => ({
|
||||
id: post.documentId,
|
||||
image: {
|
||||
url: `${Strapi.url}${post.Header.formats.medium.url}`,
|
||||
alt: post.Header.alternativeText
|
||||
},
|
||||
title: post.Title,
|
||||
body: post.Body,
|
||||
topics: post.Topics.map((topic: { id: string; Topic: string }) => ({
|
||||
id: topic.id,
|
||||
name: topic.Topic
|
||||
})),
|
||||
published: post.publishedAt
|
||||
})),
|
||||
meta
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts">
|
||||
import { env } from '$env/dynamic/public';
|
||||
import BlogCard from '$lib/components/BlogCard.svelte';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
|
|
@ -15,12 +14,12 @@
|
|||
<div class="mx-auto grid gap-8 px-3 py-3 sm:px-8 sm:py-4 lg:grid-cols-2">
|
||||
{#each posts as post (post.id)}
|
||||
<BlogCard
|
||||
documentId={post.documentId}
|
||||
img={`${env.PUBLIC_STRAPI_HOST}${post.Header.formats.medium.url}`}
|
||||
img-alt={post.Header.alternativeText}
|
||||
title={post.Title}
|
||||
published={post.publishedAt}
|
||||
topics={post.Topics}
|
||||
id={post.id}
|
||||
img={post.image.url}
|
||||
img-alt={post.image.alt}
|
||||
title={post.title}
|
||||
published={post.published}
|
||||
topics={post.topics}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,24 +1,37 @@
|
|||
import { env } from '$env/dynamic/private';
|
||||
import { strapi } from '@strapi/client';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ params }) => {
|
||||
export const load: PageServerLoad = async ({ locals, params }) => {
|
||||
const { slug } = params;
|
||||
const response = await fetch(
|
||||
`http://${env.STRAPI_HOST}:${env.STRAPI_PORT}/api/blogs/${slug}?populate=Header&populate=Topics`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `bearer ${env.STRAPI_TOKEN}`
|
||||
}
|
||||
}
|
||||
);
|
||||
const { Strapi } = locals;
|
||||
|
||||
const { data, meta } = await response.json();
|
||||
const client = strapi({
|
||||
baseURL: Strapi.url,
|
||||
auth: env.STRAPI_TOKEN
|
||||
});
|
||||
|
||||
console.log(JSON.stringify(data, null, 2));
|
||||
const blogs = client.collection('blogs');
|
||||
|
||||
const { data: post, meta } = await blogs.findOne(slug, {
|
||||
populate: ['Header', 'Topics']
|
||||
});
|
||||
|
||||
return {
|
||||
post: data,
|
||||
post: {
|
||||
id: post.documentId,
|
||||
image: {
|
||||
url: `${Strapi.url}${post.Header.url}`,
|
||||
alt: post.Header.alternativeText
|
||||
},
|
||||
title: post.Title,
|
||||
body: post.Body,
|
||||
topics: post.Topics.map((topic: { id: string; Topic: string }) => ({
|
||||
id: topic.id,
|
||||
name: topic.Topic
|
||||
})),
|
||||
published: post.publishedAt
|
||||
},
|
||||
meta
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,16 +11,16 @@
|
|||
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="w-full max-w-5xl px-4">
|
||||
<p class="text-gray-500">{dayjs(post.createdAt).format('DD MMMM YYYY')}</p>
|
||||
<h1 class="text-4xl font-light">{post.Title}</h1>
|
||||
<p class="text-gray-500">{dayjs(post.published).format('DD MMMM YYYY')}</p>
|
||||
<h1 class="text-4xl font-light">{post.title}</h1>
|
||||
</div>
|
||||
<img
|
||||
class="aspect-4/2 w-full object-cover"
|
||||
src={`${env.PUBLIC_STRAPI_HOST}${post.Header.formats.medium.url}`}
|
||||
alt={post.Header.alternativeText}
|
||||
src={`${env.PUBLIC_STRAPI_HOST}${post.image.url}`}
|
||||
alt={post.image.alt}
|
||||
/>
|
||||
<div class="w-full max-w-5xl px-4">
|
||||
{#await compile(post.Body)}
|
||||
{#await compile(post.body)}
|
||||
<div class="skeleton h-48 w-full"></div>
|
||||
{:then content}
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue