feat(news): improve news listing with tags filter, badges and url params

- Add new vertical layout with thumbnail, excerpt, tags and read more button
- Add tags filter navbar with click-to-filter functionality
- Add tags as checkered badges (beige/green pattern)
- Add URL parameter ?tag=[tag] for sharing filtered views
- Add tags display to individual news page
- Fix TypeScript errors in news pages
- Update tina config for proper content schema
This commit is contained in:
Esteban Paz 2026-04-20 20:33:53 -05:00
parent 627ea56417
commit b65e070620
19 changed files with 234 additions and 60 deletions

View File

@ -7,24 +7,71 @@ import utc from "dayjs/plugin/utc";
const regionNames = new Intl.DisplayNames(['es'], { type: 'region' });
const locale = Astro.currentLocale;
import { createTranslator } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
dayjs.extend(utc);
dayjs.locale(locale);
const { data } = Astro.props;
const { data, content } = Astro.props;
const nicedate = dayjs.utc(data.data.date).format("D MMMM YYYY");
const countryName = data?.data?.country ? regionNames.of(data.data.country) : "";
const locationArray = [data.data.city,countryName]
locationArray.filter(Boolean).join(', ');
const location = locationArray.filter(Boolean).join(', ');
const newsUrl = `/${locale}/news/${data.id}`;
const rawContent = content?.body || "";
const plainText = rawContent.replace(/^#.*$/gm, '').replace(/^###.*$/gm, '').trim();
const words = plainText.split(/\s+/).slice(0, 40);
const excerpt = words.join(' ') + (words.length === 40 ? '...' : '');
---
<div>
<h3 class="text-2xl font-bold mb-1 font-secondary text-tertiary"><a href={`/${locale}/news/${data.id}`}>{data.data.title}</a></h3>
{
data.data.city && <span class="font-normal font-primary text-lg text-tertiary/70">
{locationArray.filter(Boolean).join(', ')} | </span>
}
<span class="font-normal font-primary text-lg text-tertiary/70">{nicedate}</span>
<a href={newsUrl} class="block group">
<article class="flex flex-col md:flex-row gap-6 md:gap-8 p-4 md:p-6 border-b border-tertiary/20 hover:bg-tertiary/5 transition-colors">
<div class="md:w-1/3 flex-shrink-0 overflow-hidden">
<Image
src={data.data.thumbnail}
alt={data.data.title}
width={400}
height={300}
class="w-full h-48 md:h-full object-cover transform group-hover:scale-105 transition-transform duration-300"
/>
</div>
<div class="md:w-2/3 flex flex-col">
<div class="flex items-center gap-2 mb-2">
<span class="font-normal font-primary text-sm text-tertiary/70">{nicedate}</span>
{location && (
<>
<span class="text-tertiary/40">|</span>
<span class="font-normal font-primary text-sm text-tertiary/70">{location}</span>
</>
)}
</div>
<h3 class="text-xl md:text-2xl font-bold font-secondary text-tertiary group-hover:text-tertiary/80 transition-colors mb-2">
{data.data.title}
</h3>
<p class="font-primary text-base text-tertiary/80 mb-4 line-clamp-3">
{excerpt}
</p>
{data.data.tags && data.data.tags.length > 0 && (
<div class="flex flex-wrap gap-2 mb-4">
{data.data.tags.map((tag: string) => (
<span class="badge rounded-none bg-[#EBE6D2] border-none text-[#003421]">{tag}</span>
))}
</div>
)}
<div class="mt-auto">
<span class="inline-flex items-center gap-1 text-sm font-primary text-tertiary font-semibold group-hover:underline">
{tl("news.seemore")}
<Icon name="ph:arrow-right" class="transform group-hover:translate-x-1 transition-transform" />
</span>
</div>
</div>
</article>
</a>

View File

@ -16,6 +16,7 @@ const news = defineCollection({
country: z.string().optional(),
thumbnail: image().optional().describe("Main news thumbnail image"),
youtube: z.string().optional(),
tags: z.array(z.string()).optional().describe("News tags"),
gallery: z.array(z.object({
image: image().optional(),
text: z.string().optional()

View File

@ -7,6 +7,7 @@ place: 'Cámara de Representantes'
city: 'Bogotá'
state: 'Distrito Capital'
country: 'CO'
tags: [Colombia]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/JBP-CONDECORACION-25.webp
gallery: [
{

View File

@ -6,6 +6,7 @@ slug: 2025-08-29-un-nuevo-hijo-para-jacarei
place: ''
city: Jacareí
country: BR
tags: [Brasil]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2025-09-04-19.53.04.jpg
---

View File

@ -6,6 +6,7 @@ slug: 2025-09-18-la-democracia-se-vistio-de-gala
place: Congreso de Colombia
city: Bogotá
country: CO
tags: [Colombia]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/Condecoracion-JBP-congreso-18-sep-2025_-15-scaled.jpg
---

View File

@ -5,6 +5,7 @@ date: 2026-02-13
slug: 2026-02-13-congreso-internacional-de-rabinos-en-puerto-rico
city: San Juan
country: PR
tags: [Puerto Rico]
thumbnail: ' https://ik.imagekit.io/crpy/tr:w-900/Viernes-3.webp'
gallery: [
{

View File

@ -5,6 +5,7 @@ date: 2026-02-15
slug: 2026-02-15-apertura-oficial-del-iii-congreso-internacional-rabinos-en-puerto-rico
city: San Juan
country: PR
tags: [Puerto Rico]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_15_congreso8.webp
gallery: [
{

View File

@ -182,6 +182,8 @@
"news.text2": "This section brings together the main events, awards, and undertakings of the Kingdom of Peace and Justice Center and its founder.",
"news.text3": "This page brings together the main events, awards, and undertakings of the Kingdom of Peace and Justice Center and its founder.",
"news.buttonLable": "See More News",
"news.seemore": "See More",
"news.all": "All",
"participate.title": "Participate | Collaborate",

View File

@ -188,6 +188,8 @@
"news.text2": "Esta sección reúne las principales actividades, reconocimientos y acciones del Centro del Reino de Paz y Justicia y de su fundador.",
"news.text3": "Esta página reúne las principales actividades, reconocimientos y acciones del Centro del Reino de Paz y Justicia y de su fundador.",
"news.buttonLable": "Ver Más Noticias",
"news.seemore": "Ver Más",
"news.all": "Todas",
"participate.title": "Participa | Colabora",
"participate.text": "Sumarse es asumir un compromiso con propósito",
@ -206,6 +208,4 @@
"footer.form.mesagge": "Escriba su mensaje",
"footer.form.button": "Enviar",
"footer.reserved": "©2026. Todos los Derechos Reservados. Centro del Reino de Paz y Justicia"
}

View File

@ -35,12 +35,16 @@ const routeTranslations = {
const baseSlug = routeTranslations.news[locale] || routeTranslations.news.en;
const rawContent = post.body || "";
const plainText = rawContent.replace(/^#.*$/gm, '').replace(/^###.*$/gm, '').trim();
const words = plainText.split(/\s+/).slice(0, 35);
const excerpt = words.join(' ') + (words.length === 35 ? '...' : '');
---
</style>
<MainLayout
title={post.data.title}
description={`${post.data.title} - ${post.data.city ?? ""} ${post.data.country ?? ""}`}
description={excerpt}
image={post.data.thumbnail}
url={new URL(`/${locale}/${"news"}/${post.id}`, Astro.site)}
>
@ -48,18 +52,37 @@ const baseSlug = routeTranslations.news[locale] || routeTranslations.news.en;
<Header />
</div>
<a href={`/${locale}/news/${post.id}`} class="block">
<TitleSection title={post.data.title} />
</a>
<div class="container mx-auto">
{post.data.gallery?.length ? ( <CarouselSection images={post.data.gallery} />) : post.data.thumbnail ? (<Image src={post.data.thumbnail} alt="" /> ) : null}
<a href={`/${locale}/news/${post.id}`} class="block">
{post.data.gallery?.length ? ( <CarouselSection images={post.data.gallery} />) : post.data.thumbnail ? (<Image src={post.data.thumbnail} alt={post.data.title} class="hover:opacity-90 transition-opacity" /> ) : null}
</a>
{post.data.tags && post.data.tags.length > 0 && (
<div class="container mx-auto lg:max-w-4xl px-4 mb-6">
<div class="flex flex-wrap gap-2">
{post.data.tags.map((tag: string) => (
<span class="px-2 py-1 text-xs font-bold font-primary text-[#003421] rounded-sm relative overflow-hidden" style="background: repeating-conic-gradient(#003421 0% 25%, #EBE5D0 0% 50%) 50% / 8px 8px;">
<span class="block px-1">{tag}</span>
</span>
))}
</div>
</div>
)}
<div class="grid md:grid-cols-10">
<div class="md:col-span-7 content bg-white p-8 md:p-20 prose-p:mb-4 text-[#003421] text-justify">
<!-- <p class="text-lg font-semibold text-tertiary mb-8 pb-6 border-b border-tertiary/20 italic">
{excerpt}
</p> -->
<Content />
</div>
<div class="md:col-span-3 bg-tertiary md:sticky top-0 h-fit">
{ post.data.youtube && (
<YouTube id={post.data.youtube} />
)}
{post.data.gallery && (
@ -67,8 +90,6 @@ const baseSlug = routeTranslations.news[locale] || routeTranslations.news.en;
<Image src={galleryImage.image} alt={galleryImage.text} />
))
)}
</div>
</div>
</div>
</MainLayout>

View File

@ -1,20 +1,32 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import NewsSection from "@/components/section/NewsSection.astro"
import Header from "@/components/Header.astro"
import NewsCard from "@/components/cards/NewsCard.astro";
import NewsList from "@/components/cards/NewsList.astro";
import { getCollection, getEntry } from "astro:content";
import FooterSection from "@/components/section/FooterSection.astro";
import NewsList from "@/components/cards/NewsList.astro";
import { createTranslator, t } from '@/i18n';
import { createTranslator } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
const newsItems = await getCollection("news", (post)=>{
const currentLocale = Astro.currentLocale;
return post.data.locale == currentLocale
});
const sortedPosts = [...newsItems]
.sort((a, b) => {
const dateDiff = new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
if (dateDiff !== 0) return dateDiff
return (a.data.order ?? 0) - (b.data.order ?? 0)
});
const allTags = [...new Set(
sortedPosts
.filter(p => p.data.tags && p.data.tags.length > 0)
.flatMap(p => p.data.tags)
.filter((tag): tag is string => tag !== undefined)
)].sort();
---
<MainLayout >
@ -25,23 +37,29 @@ const newsItems = await getCollection("news", (post)=>{
<div class="flex flex-col lg:w-1/2 items-center mx-auto py-8">
<h1 class="text-white text-2xl uppercase font-bold text-center mb-4 font-primary md:mt-20 mt-10">{tl("news.title")}</h1>
<h2 class="text-white text-3xl lg:text-5xl font-bold text-center font-secondary mb-4">{tl("news.text")}</h2>
<!-- <p class="text-white text-xl text-center">{tl("news.text3")}</p> -->
</div>
{allTags.length > 0 && (
<div class="container mx-auto mb-8">
<div class="flex flex-wrap gap-2 justify-center">
<button class="filter-btn px-4 py-2 font-primary text-sm cursor-pointer transition-colors" data-tag="all">
{tl("news.all")}
</button>
{allTags.map((tag) => (
<button class="filter-btn px-4 py-2 font-primary text-sm cursor-pointer transition-colors" data-tag={tag!}>
{tag}
</button>
))}
</div>
</div>
)}
<div class="flex flex-col md:gap-8 gap-2 lg:max-w-4xl mx-auto bg-white p-8">
<div class="flex flex-col md:gap-0 gap-2 lg:max-w-4xl mx-auto bg-white p-4 md:p-8">
{
[...newsItems]
.sort((a, b) => {
const dateDiff =
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
if (dateDiff !== 0) return dateDiff
return (a.data.order ?? 0) - (b.data.order ?? 0)
})
.map((item) => (
<NewsList data={item} />
sortedPosts.map((item) => (
<div class="news-item" data-tags={JSON.stringify(item.data.tags || [])}>
<NewsList data={item} content={{ body: item.body }} />
</div>
))
}
</div>
@ -49,3 +67,65 @@ const newsItems = await getCollection("news", (post)=>{
<FooterSection />
</MainLayout>
<script>
const activeClasses = "bg-[#003421] text-[#EBE5D0]";
const inactiveClasses = "bg-[#003421]/20 text-[#EBE5D0] hover:bg-[#003421]/30";
function activateTag(tag: string | null) {
document.querySelectorAll('.filter-btn').forEach(b => {
if (b.getAttribute('data-tag') === tag) {
b.classList.remove(...inactiveClasses.split(" "));
b.classList.add(...activeClasses.split(" "));
} else {
b.classList.remove(...activeClasses.split(" "));
b.classList.add(...inactiveClasses.split(" "));
}
});
document.querySelectorAll('.news-item').forEach(item => {
const itemTags = JSON.parse(item.getAttribute('data-tags') || '[]');
if (tag === 'all' || tag === null || itemTags.includes(tag)) {
(item as HTMLElement).style.display = 'block';
} else {
(item as HTMLElement).style.display = 'none';
}
});
}
function updateUrl(tag: string | null) {
const url = new URL(window.location.href);
if (tag && tag !== 'all') {
url.searchParams.set('tag', tag);
} else {
url.searchParams.delete('tag');
}
window.history.replaceState({}, '', url.toString());
}
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.classList.add(...inactiveClasses.split(" "));
});
const urlParams = new URLSearchParams(window.location.search);
const initialTag = urlParams.get('tag');
if (initialTag) {
const matchingBtn = document.querySelector(`.filter-btn[data-tag="${initialTag}"]`);
if (matchingBtn) {
matchingBtn.classList.remove(...inactiveClasses.split(" "));
matchingBtn.classList.add(...activeClasses.split(" "));
}
activateTag(initialTag);
} else {
document.querySelector('.filter-btn[data-tag="all"]')?.classList.add(...activeClasses.split(" "));
document.querySelector('.filter-btn[data-tag="all"]')?.classList.remove(...inactiveClasses.split(" "));
}
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', () => {
const tag = btn.getAttribute('data-tag');
activateTag(tag);
updateUrl(tag);
});
});
</script>

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":{"fullVersion":"2.2.3","major":"2","minor":"2","patch":"3"},"meta":{"flags":["experimentalData"]},"collections":[{"name":"news","label":"News","path":"src/content/news","format":"md","fields":[{"type":"string","name":"locale","label":"Language","options":[{"label":"Español","value":"es"},{"label":"English","value":"en"}],"namespace":["news","locale"],"searchable":true,"uid":false},{"type":"string","name":"title","label":"Title","isTitle":true,"required":true,"namespace":["news","title"],"searchable":true,"uid":false},{"type":"datetime","name":"date","label":"Date","required":true,"namespace":["news","date"],"searchable":true,"uid":false},{"type":"string","name":"slug","label":"Slug","namespace":["news","slug"],"searchable":true,"uid":false},{"type":"string","name":"place","label":"Place","namespace":["news","place"],"searchable":true,"uid":false},{"type":"string","name":"thumbnail","label":"Thumbnail URL","namespace":["news","thumbnail"],"searchable":true,"uid":false},{"type":"string","name":"youtube","label":"YouTube ID","namespace":["news","youtube"],"searchable":true,"uid":false},{"type":"boolean","name":"draft","label":"Draft","namespace":["news","draft"],"searchable":true,"uid":false},{"type":"rich-text","name":"body","label":"Content","isBody":true,"namespace":["news","body"],"searchable":true,"parser":{"type":"markdown"},"uid":false}],"namespace":["news"]},{"name":"documentaries","label":"Documentaries","path":"src/content/documentaries","format":"md","fields":[{"type":"string","name":"locale","label":"Language","options":[{"label":"Español","value":"es"}],"namespace":["documentaries","locale"],"searchable":true,"uid":false},{"type":"string","name":"title","label":"Title","isTitle":true,"required":true,"namespace":["documentaries","title"],"searchable":true,"uid":false},{"type":"string","name":"video_yt","label":"YouTube ID","namespace":["documentaries","video_yt"],"searchable":true,"uid":false},{"type":"datetime","name":"date","label":"Date","required":true,"namespace":["documentaries","date"],"searchable":true,"uid":false}],"namespace":["documentaries"]}],"config":{"media":{"tina":{"publicFolder":"public","mediaRoot":"public/images"}}}}
{"version":{"fullVersion":"2.2.3","major":"2","minor":"2","patch":"3"},"meta":{"flags":["experimentalData"]},"collections":[{"name":"news","label":"News","path":"src/content/news","format":"md","fields":[{"type":"string","name":"locale","label":"Language","options":[{"label":"Español","value":"es"},{"label":"English","value":"en"}],"namespace":["news","locale"],"searchable":true,"uid":false},{"type":"string","name":"title","label":"Title","isTitle":true,"required":true,"namespace":["news","title"],"searchable":true,"uid":false},{"type":"datetime","name":"date","label":"Date","required":true,"namespace":["news","date"],"searchable":true,"uid":false},{"type":"string","name":"slug","label":"Slug","namespace":["news","slug"],"searchable":true,"uid":false},{"type":"string","name":"place","label":"Place","namespace":["news","place"],"searchable":true,"uid":false},{"type":"string","name":"thumbnail","label":"Thumbnail URL","namespace":["news","thumbnail"],"searchable":true,"uid":false},{"type":"string","name":"youtube","label":"YouTube ID","namespace":["news","youtube"],"searchable":true,"uid":false},{"type":"string","name":"tags","label":"Tags (comma separated)","namespace":["news","tags"],"searchable":true,"uid":false},{"type":"boolean","name":"draft","label":"Draft","namespace":["news","draft"],"searchable":true,"uid":false},{"type":"rich-text","name":"body","label":"Content","isBody":true,"namespace":["news","body"],"searchable":true,"parser":{"type":"markdown"},"uid":false}],"namespace":["news"]},{"name":"documentaries","label":"Documentaries","path":"src/content/documentaries","format":"md","fields":[{"type":"string","name":"locale","label":"Language","options":[{"label":"Español","value":"es"}],"namespace":["documentaries","locale"],"searchable":true,"uid":false},{"type":"string","name":"title","label":"Title","isTitle":true,"required":true,"namespace":["documentaries","title"],"searchable":true,"uid":false},{"type":"string","name":"video_yt","label":"YouTube ID","namespace":["documentaries","video_yt"],"searchable":true,"uid":false},{"type":"datetime","name":"date","label":"Date","required":true,"namespace":["documentaries","date"],"searchable":true,"uid":false}],"namespace":["documentaries"]}],"config":{"media":{"tina":{"publicFolder":"public","mediaRoot":"public/images"}}}}

View File

@ -65,6 +65,11 @@ var config_default = defineConfig({
name: "youtube",
label: "YouTube ID"
},
{
type: "string",
name: "tags",
label: "Tags (comma separated)"
},
{
type: "boolean",
name: "draft",

View File

@ -7,6 +7,7 @@ fragment NewsParts on News {
place
thumbnail
youtube
tags
draft
body
}

View File

@ -98,6 +98,7 @@ type News implements Node & Document {
place: String
thumbnail: String
youtube: String
tags: String
draft: Boolean
body: JSON
id: ID!
@ -139,6 +140,7 @@ input NewsFilter {
place: StringFilter
thumbnail: StringFilter
youtube: StringFilter
tags: StringFilter
draft: BooleanFilter
body: RichTextFilter
}
@ -213,6 +215,7 @@ input NewsMutation {
place: String
thumbnail: String
youtube: String
tags: String
draft: Boolean
body: JSON
}

View File

@ -192,6 +192,7 @@ export type News = Node & Document & {
place?: Maybe<Scalars['String']['output']>;
thumbnail?: Maybe<Scalars['String']['output']>;
youtube?: Maybe<Scalars['String']['output']>;
tags?: Maybe<Scalars['String']['output']>;
draft?: Maybe<Scalars['Boolean']['output']>;
body?: Maybe<Scalars['JSON']['output']>;
id: Scalars['ID']['output'];
@ -233,6 +234,7 @@ export type NewsFilter = {
place?: InputMaybe<StringFilter>;
thumbnail?: InputMaybe<StringFilter>;
youtube?: InputMaybe<StringFilter>;
tags?: InputMaybe<StringFilter>;
draft?: InputMaybe<BooleanFilter>;
body?: InputMaybe<RichTextFilter>;
};
@ -370,6 +372,7 @@ export type NewsMutation = {
place?: InputMaybe<Scalars['String']['input']>;
thumbnail?: InputMaybe<Scalars['String']['input']>;
youtube?: InputMaybe<Scalars['String']['input']>;
tags?: InputMaybe<Scalars['String']['input']>;
draft?: InputMaybe<Scalars['Boolean']['input']>;
body?: InputMaybe<Scalars['JSON']['input']>;
};
@ -381,7 +384,7 @@ export type DocumentariesMutation = {
date?: InputMaybe<Scalars['String']['input']>;
};
export type NewsPartsFragment = { __typename: 'News', locale?: string | null, title: string, date: string, slug?: string | null, place?: string | null, thumbnail?: string | null, youtube?: string | null, draft?: boolean | null, body?: any | null };
export type NewsPartsFragment = { __typename: 'News', locale?: string | null, title: string, date: string, slug?: string | null, place?: string | null, thumbnail?: string | null, youtube?: string | null, tags?: string | null, draft?: boolean | null, body?: any | null };
export type DocumentariesPartsFragment = { __typename: 'Documentaries', locale?: string | null, title: string, video_yt?: string | null, date: string };
@ -390,7 +393,7 @@ export type NewsQueryVariables = Exact<{
}>;
export type NewsQuery = { __typename?: 'Query', news: { __typename: 'News', id: string, locale?: string | null, title: string, date: string, slug?: string | null, place?: string | null, thumbnail?: string | null, youtube?: string | null, draft?: boolean | null, body?: any | null, _sys: { __typename?: 'SystemInfo', filename: string, basename: string, hasReferences?: boolean | null, breadcrumbs: Array<string>, path: string, relativePath: string, extension: string } } };
export type NewsQuery = { __typename?: 'Query', news: { __typename: 'News', id: string, locale?: string | null, title: string, date: string, slug?: string | null, place?: string | null, thumbnail?: string | null, youtube?: string | null, tags?: string | null, draft?: boolean | null, body?: any | null, _sys: { __typename?: 'SystemInfo', filename: string, basename: string, hasReferences?: boolean | null, breadcrumbs: Array<string>, path: string, relativePath: string, extension: string } } };
export type NewsConnectionQueryVariables = Exact<{
before?: InputMaybe<Scalars['String']['input']>;
@ -402,7 +405,7 @@ export type NewsConnectionQueryVariables = Exact<{
}>;
export type NewsConnectionQuery = { __typename?: 'Query', newsConnection: { __typename?: 'NewsConnection', totalCount: number, pageInfo: { __typename?: 'PageInfo', hasPreviousPage: boolean, hasNextPage: boolean, startCursor: string, endCursor: string }, edges?: Array<{ __typename?: 'NewsConnectionEdges', cursor: string, node?: { __typename: 'News', id: string, locale?: string | null, title: string, date: string, slug?: string | null, place?: string | null, thumbnail?: string | null, youtube?: string | null, draft?: boolean | null, body?: any | null, _sys: { __typename?: 'SystemInfo', filename: string, basename: string, hasReferences?: boolean | null, breadcrumbs: Array<string>, path: string, relativePath: string, extension: string } } | null } | null> | null } };
export type NewsConnectionQuery = { __typename?: 'Query', newsConnection: { __typename?: 'NewsConnection', totalCount: number, pageInfo: { __typename?: 'PageInfo', hasPreviousPage: boolean, hasNextPage: boolean, startCursor: string, endCursor: string }, edges?: Array<{ __typename?: 'NewsConnectionEdges', cursor: string, node?: { __typename: 'News', id: string, locale?: string | null, title: string, date: string, slug?: string | null, place?: string | null, thumbnail?: string | null, youtube?: string | null, tags?: string | null, draft?: boolean | null, body?: any | null, _sys: { __typename?: 'SystemInfo', filename: string, basename: string, hasReferences?: boolean | null, breadcrumbs: Array<string>, path: string, relativePath: string, extension: string } } | null } | null> | null } };
export type DocumentariesQueryVariables = Exact<{
relativePath: Scalars['String']['input'];
@ -433,6 +436,7 @@ export const NewsPartsFragmentDoc = gql`
place
thumbnail
youtube
tags
draft
body
}

View File

@ -66,6 +66,11 @@ export default defineConfig({
name: "youtube",
label: "YouTube ID",
},
{
type: "string",
name: "tags",
label: "Tags (comma separated)",
},
{
type: "boolean",
name: "draft",

File diff suppressed because one or more lines are too long