Update content & design (#75)
All checks were successful
Deploy to Pages / build (push) Successful in 2m58s
All checks were successful
Deploy to Pages / build (push) Successful in 2m58s
Reviewed-on: https://home.schmelczer.dev/git/git/andras/schmelczer-dev/pulls/75
This commit is contained in:
parent
0be50b6c24
commit
b554e92e9f
83 changed files with 2995 additions and 723 deletions
|
|
@ -32,6 +32,15 @@ const mediaUrl = z.string().refine(
|
|||
{ message: 'Media URL must be an absolute https URL or a root-relative path.' }
|
||||
);
|
||||
|
||||
function isIframeUrl(url: string) {
|
||||
if (isRootRelativeUrl(url)) return true;
|
||||
try {
|
||||
return new URL(url).protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const linkSchema = z.object({
|
||||
label: z.string(),
|
||||
url: linkUrl,
|
||||
|
|
@ -91,37 +100,54 @@ const mediaSchema = ({ image }: SchemaContext) =>
|
|||
const posts = defineCollection({
|
||||
loader: glob({ pattern: '**/*.md', base: './src/content/posts' }),
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
title: z.string(),
|
||||
description: z.string().max(160),
|
||||
date: z.coerce.date(),
|
||||
updated: z.coerce.date().optional(),
|
||||
draft: z.boolean().default(false),
|
||||
thumbnail: thumbnailSchema({ image }),
|
||||
tags: z.array(
|
||||
z.enum([
|
||||
'ai',
|
||||
'systems',
|
||||
'graphics',
|
||||
'simulation',
|
||||
'embedded',
|
||||
'web',
|
||||
'tools',
|
||||
'games',
|
||||
])
|
||||
z
|
||||
.object({
|
||||
title: z.string(),
|
||||
description: z.string().max(160),
|
||||
date: z.coerce.date(),
|
||||
updated: z.coerce.date().optional(),
|
||||
draft: z.boolean().default(false),
|
||||
thumbnail: thumbnailSchema({ image }),
|
||||
iframeThumbnail: z.boolean().default(false),
|
||||
tags: z.array(
|
||||
z.enum([
|
||||
'ai',
|
||||
'systems',
|
||||
'graphics',
|
||||
'simulation',
|
||||
'embedded',
|
||||
'web',
|
||||
'tools',
|
||||
'games',
|
||||
])
|
||||
),
|
||||
featuredOrder: z.number().optional(),
|
||||
projectPeriod: z.string().optional(),
|
||||
role: z.string().optional(),
|
||||
stack: z.array(z.string()).optional(),
|
||||
scale: z.string().optional(),
|
||||
outcome: z.string().optional(),
|
||||
audience: z
|
||||
.enum(['general', 'technical', 'recruiter-relevant'])
|
||||
.default('technical'),
|
||||
links: z.array(linkSchema).default([]),
|
||||
media: z.array(mediaSchema({ image })).default([]),
|
||||
})
|
||||
.refine(
|
||||
(post) =>
|
||||
!post.iframeThumbnail ||
|
||||
post.links.some(
|
||||
(link) =>
|
||||
!link.download &&
|
||||
link.label.trim().toLowerCase() === 'demo' &&
|
||||
isIframeUrl(link.url)
|
||||
),
|
||||
{
|
||||
path: ['iframeThumbnail'],
|
||||
message:
|
||||
'iframeThumbnail requires a non-download Demo link with an https or root-relative URL.',
|
||||
}
|
||||
),
|
||||
featuredOrder: z.number().optional(),
|
||||
projectPeriod: z.string().optional(),
|
||||
role: z.string().optional(),
|
||||
stack: z.array(z.string()).optional(),
|
||||
scale: z.string().optional(),
|
||||
outcome: z.string().optional(),
|
||||
audience: z
|
||||
.enum(['general', 'technical', 'recruiter-relevant'])
|
||||
.default('technical'),
|
||||
links: z.array(linkSchema).default([]),
|
||||
media: z.array(mediaSchema({ image })).default([]),
|
||||
}),
|
||||
});
|
||||
|
||||
const projects = defineCollection({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue