Merge branch 'archiveUpdate'

# Conflicts:
#	src/content/news/es/2026-04-20.md
This commit is contained in:
Esteban Paz 2026-04-22 01:53:34 -05:00
commit ae5eab243a
66 changed files with 20765 additions and 73 deletions

View File

@ -7,6 +7,7 @@ import icon from "astro-icon";
import node from "@astrojs/node"; import node from "@astrojs/node";
import vue from "@astrojs/vue"; import vue from "@astrojs/vue";
import react from "@astrojs/react";
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
@ -16,7 +17,7 @@ export default defineConfig({
site: "https://centrodelreinodepazyjusticia.com/", site: "https://centrodelreinodepazyjusticia.com/",
//base: '/mockup/', //base: '/mockup/',
integrations: [markdoc(), icon(), vue()], integrations: [markdoc(), icon(), vue(), react()],
i18n: { i18n: {
locales: ["es", "en", "fr", "he", "uk", "pt-br", "ru"], locales: ["es", "en", "fr", "he", "uk", "pt-br", "ru"],

19060
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
"type": "module", "type": "module",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "tinacms dev -c \"astro dev\"",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro" "astro": "astro"
@ -11,6 +11,7 @@
"dependencies": { "dependencies": {
"@astrojs/markdoc": "^0.15.10", "@astrojs/markdoc": "^0.15.10",
"@astrojs/node": "^9.5.3", "@astrojs/node": "^9.5.3",
"@astrojs/react": "^5.0.3",
"@astrojs/vue": "^5.1.4", "@astrojs/vue": "^5.1.4",
"@coreui/icons": "^3.0.1", "@coreui/icons": "^3.0.1",
"@dotenvx/dotenvx": "^1.52.0", "@dotenvx/dotenvx": "^1.52.0",
@ -30,9 +31,13 @@
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"googleapis": "^171.4.0", "googleapis": "^171.4.0",
"prisma": "^6.19.2", "prisma": "^6.19.2",
"react": "^19.2.5",
"react-dom": "^19.2.5",
"swiper": "^12.1.0", "swiper": "^12.1.0",
"tailwindcss": "^4.1.18", "tailwindcss": "^4.1.18",
"vue": "^3.5.28" "vue": "^3.5.28",
"@tinacms/cli": "^2.2.2",
"tinacms": "^2.2.2"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.19", "@tailwindcss/typography": "^0.5.19",

2
public/admin/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
index.html
assets/

View File

@ -24,6 +24,8 @@ const { locale } = Astro.params;
<a class="hover:text-colorPrimary transition" href=`/${currentLocale}#somos`>{tl("nav.about")}</a> <a class="hover:text-colorPrimary transition" href=`/${currentLocale}#somos`>{tl("nav.about")}</a>
<a class="hover:text-colorPrimary transition" href=`/${currentLocale}#programs`>{tl("nav.programs")}</a> <a class="hover:text-colorPrimary transition" href=`/${currentLocale}#programs`>{tl("nav.programs")}</a>
<a class="hover:text-colorPrimary transition" href=`/${currentLocale}#news`>{tl("nav.news")}</a> <a class="hover:text-colorPrimary transition" href=`/${currentLocale}#news`>{tl("nav.news")}</a>
<!-- <a class="hover:text-colorPrimary transition" href=`/${currentLocale}/archive`>{tl("nav.archive")}</a>
<a class="hover:text-colorPrimary transition" href=`/${currentLocale}/nations`>{tl("nav.nations")}</a> -->
</div> </div>
<div class="drawer lg:hidden"> <div class="drawer lg:hidden">
<input id="my-drawer-1" type="checkbox" class="drawer-toggle" /> <input id="my-drawer-1" type="checkbox" class="drawer-toggle" />

View File

@ -7,24 +7,71 @@ import utc from "dayjs/plugin/utc";
const regionNames = new Intl.DisplayNames(['es'], { type: 'region' }); const regionNames = new Intl.DisplayNames(['es'], { type: 'region' });
const locale = Astro.currentLocale; const locale = Astro.currentLocale;
import { createTranslator } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
dayjs.extend(utc); dayjs.extend(utc);
dayjs.locale(locale); dayjs.locale(locale);
const { data } = Astro.props; const { data, content } = Astro.props;
const nicedate = dayjs.utc(data.data.date).format("D MMMM YYYY"); const nicedate = dayjs.utc(data.data.date).format("D MMMM YYYY");
const countryName = data?.data?.country ? regionNames.of(data.data.country) : ""; const countryName = data?.data?.country ? regionNames.of(data.data.country) : "";
const locationArray = [data.data.city,countryName] 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> <a href={newsUrl} class="block group">
<h3 class="text-2xl font-bold mb-1 font-secondary text-tertiary"><a href={`/${locale}/news/${data.id}`}>{data.data.title}</a></h3> <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
data.data.city && <span class="font-normal font-primary text-lg text-tertiary/70"> src={data.data.thumbnail}
{locationArray.filter(Boolean).join(', ')} | </span> alt={data.data.title}
} width={400}
<span class="font-normal font-primary text-lg text-tertiary/70">{nicedate}</span> height={300}
class="w-full h-48 md:h-full object-cover transform group-hover:scale-105 transition-transform duration-300"
</div> />
</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(), country: z.string().optional(),
thumbnail: image().optional().describe("Main news thumbnail image"), thumbnail: image().optional().describe("Main news thumbnail image"),
youtube: z.string().optional(), youtube: z.string().optional(),
tags: z.array(z.string()).optional().describe("News tags"),
gallery: z.array(z.object({ gallery: z.array(z.object({
image: image().optional(), image: image().optional(),
text: z.string().optional() text: z.string().optional()

View File

@ -0,0 +1,5 @@
---
locale: es
title: test
---

View File

@ -6,6 +6,7 @@ date: 2025-09-05
place: The basement place: The basement
city: Jacareí city: Jacareí
country: BR country: BR
tags: [Brasil]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2025-09-04-19.53.04.jpg?updatedAt=1770780193361 thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2025-09-04-19.53.04.jpg?updatedAt=1770780193361
gallery: [ gallery: [
{ {

View File

@ -5,6 +5,7 @@ date: 2025-05-08
slug: awarding-of-decoration-order-of-democracy-simon-bolivar slug: awarding-of-decoration-order-of-democracy-simon-bolivar
city: Bogotá city: Bogotá
country: CO country: CO
tags: ['Colombia', 'Decoration']
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/JBP-CONDECORACION-25.webp?updatedAt=1770780239998 thumbnail: https://ik.imagekit.io/crpy/tr:w-900/JBP-CONDECORACION-25.webp?updatedAt=1770780239998
gallery: [ gallery: [
{ {

View File

@ -5,6 +5,7 @@ date: 2026-02-13
slug: 2026-02-13-3rd-international-congress-of-rabbis-in-puerto-rico slug: 2026-02-13-3rd-international-congress-of-rabbis-in-puerto-rico
city: San Juan city: San Juan
country: PR country: PR
tags: [Puerto Rico, Congress]
thumbnail: ' https://ik.imagekit.io/crpy/tr:w-900/Viernes-3.webp' thumbnail: ' https://ik.imagekit.io/crpy/tr:w-900/Viernes-3.webp'
gallery: [ gallery: [
{ {

View File

@ -4,6 +4,7 @@ title: 'Official opening of the 3rd International Congress of Rabbis in Puerto R
date: 2026-02-15 date: 2026-02-15
slug: 2026-02-15-official-opening-of-the-3rd-international-congress-of-rabbis-in-puerto-rico slug: 2026-02-15-official-opening-of-the-3rd-international-congress-of-rabbis-in-puerto-rico
city: San Juan city: San Juan
tags: [Puerto Rico, Congress]
country: PR country: PR
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_15_congreso8.webp thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_15_congreso8.webp
gallery: [ gallery: [

View File

@ -5,6 +5,7 @@ date: 2026-02-16
slug: 2026-02-16-closing-of-the-3rd-international-congress-of-rabbis-in-puerto-rico slug: 2026-02-16-closing-of-the-3rd-international-congress-of-rabbis-in-puerto-rico
city: Cayey city: Cayey
country: PR country: PR
tags: [Puerto Rico, Congress]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_16_cierre2.webp thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_16_cierre2.webp
gallery: [ gallery: [
{ {

View File

@ -6,6 +6,7 @@ date: 2026-02-26
order: 1 order: 1
city: Asunción city: Asunción
country: PY country: PY
tags: [Paraguay]
youtube: https://www.youtube.com/watch?v=MjmYkRTWhk0 youtube: https://www.youtube.com/watch?v=MjmYkRTWhk0
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/visitante-ilustre.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/visitante-ilustre.webp'
--- ---

View File

@ -5,6 +5,7 @@ date: 2026-03-03
slug: 2026-03-03-statement-center-kingodm-of-peace-and-justice slug: 2026-03-03-statement-center-kingodm-of-peace-and-justice
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1200/press-release.png' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1200/press-release.png'
tags: [Israel, Statement]
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',

View File

@ -3,6 +3,7 @@ locale: en
title: 'Remarks for International Womens Day, dedicated to the Women of the Israeli Defense Forces' title: 'Remarks for International Womens Day, dedicated to the Women of the Israeli Defense Forces'
date: 2026-03-08 date: 2026-03-08
slug: 2026-03-08-remarks-for-international-womens-day-dedicated-to-the-women-of-the-israeli-defense-forces slug: 2026-03-08-remarks-for-international-womens-day-dedicated-to-the-women-of-the-israeli-defense-forces
tags: [Israel]
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,h-720,cm-pad_resize,bg-blurred/woman-day-2.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,h-720,cm-pad_resize,bg-blurred/woman-day-2.webp'
--- ---

View File

@ -6,6 +6,7 @@ slug: 2026-04-02-speaking-from-cayey-dr-jose-benjamin-perez-addresses-the-global
place: '' place: ''
city: Cayey city: Cayey
country: PR country: PR
tags: [Puerto Rico]
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/new-crpj-1.jpeg' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/new-crpj-1.jpeg'
gallery: [ gallery: [
{ {

View File

@ -10,6 +10,7 @@ gallery: [
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred//banderas-1a1.png', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred//banderas-1a1.png',
}, },
] ]
tags: [Spain, France, Israel]
--- ---
**Puerto Rico, April 11, 2026**. In an international context marked by growing diplomatic tensions in the Middle East and Europe, Dr. José Benjamín Pérez Matos, President of the Kingdom of Peace and Justice Center, gave an address linking current geopolitical decisions to a spiritual passage with global implications. **Puerto Rico, April 11, 2026**. In an international context marked by growing diplomatic tensions in the Middle East and Europe, Dr. José Benjamín Pérez Matos, President of the Kingdom of Peace and Justice Center, gave an address linking current geopolitical decisions to a spiritual passage with global implications.

View File

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

View File

@ -6,6 +6,7 @@ slug: 2025-08-29-un-nuevo-hijo-para-jacarei
place: '' place: ''
city: Jacareí city: Jacareí
country: BR country: BR
tags: ['Brasil', 'Homenaje']
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2025-09-04-19.53.04.jpg 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 place: Congreso de Colombia
city: Bogotá city: Bogotá
country: CO country: CO
tags: [Colombia]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/Condecoracion-JBP-congreso-18-sep-2025_-15-scaled.jpg 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 slug: 2026-02-13-congreso-internacional-de-rabinos-en-puerto-rico
city: San Juan city: San Juan
country: PR country: PR
tags: [Puerto Rico, Congreso]
thumbnail: ' https://ik.imagekit.io/crpy/tr:w-900/Viernes-3.webp' thumbnail: ' https://ik.imagekit.io/crpy/tr:w-900/Viernes-3.webp'
gallery: [ 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 slug: 2026-02-15-apertura-oficial-del-iii-congreso-internacional-rabinos-en-puerto-rico
city: San Juan city: San Juan
country: PR country: PR
tags: [Puerto Rico, Congreso]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_15_congreso8.webp thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_15_congreso8.webp
gallery: [ gallery: [
{ {

View File

@ -5,6 +5,7 @@ date: 2026-02-16
slug: 2026-02-16-cierre-del-iii-congreso-internacional-rabinos-en-puerto-rico slug: 2026-02-16-cierre-del-iii-congreso-internacional-rabinos-en-puerto-rico
city: Cayey city: Cayey
country: PR country: PR
tags: [Puerto Rico, Congreso]
thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_16_cierre2.webp thumbnail: https://ik.imagekit.io/crpy/tr:w-900/2026_02_16_cierre2.webp
gallery: [ gallery: [
{ {

View File

@ -5,6 +5,7 @@ date: 2026-02-16
slug: 2026-02-16-iii-palabras-de-clausura-del-iii-congreso-de-rabinos-internacional slug: 2026-02-16-iii-palabras-de-clausura-del-iii-congreso-de-rabinos-internacional
city: Cayey city: Cayey
country: PR country: PR
tags: [Puerto Rico, Congreso]
thumbnail: https://ik.imagekit.io/crpy/tr:w-1280/2026_02_16_cierre1.webp thumbnail: https://ik.imagekit.io/crpy/tr:w-1280/2026_02_16_cierre1.webp
gallery: [ gallery: [
{ {

View File

@ -4,6 +4,7 @@ title: 'Cuatro años de guerra en Ucrania: memoria, justicia y responsabilidad i
date: 2026-02-24 date: 2026-02-24
slug: 2026-02-24-cuatro-anos-de-guerra-en-ucrania-memoria-justicia-responsabilidad-internacional slug: 2026-02-24-cuatro-anos-de-guerra-en-ucrania-memoria-justicia-responsabilidad-internacional
thumbnail: https://ik.imagekit.io/crpy/tr:w-1280/ucrania-new-5.webp thumbnail: https://ik.imagekit.io/crpy/tr:w-1280/ucrania-new-5.webp
tags: [Ucrania]
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280/ucrania-new-4.webp', image: 'https://ik.imagekit.io/crpy/tr:w-1280/ucrania-new-4.webp',

View File

@ -6,6 +6,7 @@ slug: 2026-02-26-dr-jose-benjamin-perez-plantacion-bosque-israel
city: Asunción city: Asunción
order: 2 order: 2
country: PY country: PY
tags: [Paraguay]
youtube: https://youtu.be/8-YWuoWb4dY youtube: https://youtu.be/8-YWuoWb4dY
thumbnail: https://ik.imagekit.io/crpy/tr:w-1280/parque-isarel.jpg thumbnail: https://ik.imagekit.io/crpy/tr:w-1280/parque-isarel.jpg
gallery: [ gallery: [

View File

@ -6,6 +6,7 @@ date: 2026-02-26
order: 3 order: 3
city: Asunción city: Asunción
country: PY country: PY
tags: [Paraguay]
youtube: https://youtu.be/oKrSlITOaUA?si=1v-Hm5MNW3aAlqPG youtube: https://youtu.be/oKrSlITOaUA?si=1v-Hm5MNW3aAlqPG
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/entrega-llave-de-la-ciudad.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/entrega-llave-de-la-ciudad.webp'
--- ---

View File

@ -5,6 +5,7 @@ slug: 2026-02-26-la-municipalidad-de-mariano-roque-alonso-declara-visitante-ilus
date: 2026-02-26 date: 2026-02-26
order: 1 order: 1
city: Asunción city: Asunción
tags: [Paraguay]
country: PY country: PY
youtube: https://www.youtube.com/watch?v=MjmYkRTWhk0 youtube: https://www.youtube.com/watch?v=MjmYkRTWhk0
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/visitante-ilustre.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/visitante-ilustre.webp'

View File

@ -4,6 +4,7 @@ title: 'Centro del Reino de Paz y Justicia Comunicado'
date: 2026-03-03 date: 2026-03-03
slug: 2026-03-03-comunicado-centro-del-reino-de-paz-y-justicia slug: 2026-03-03-comunicado-centro-del-reino-de-paz-y-justicia
place: '' place: ''
tags: [Israel, Comunicado]
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-2.png' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-2.png'
gallery: [ gallery: [
{ {

View File

@ -1,11 +1,13 @@
--- ---
locale: es locale: es
title: 'Palabras por el Día Internacional de la Mujer, dirigidas a las mujeres de las fuerzas militares de Israel' title: 'Palabras por el Día Internacional de la Mujer, dirigidas a las mujeres de las fuerzas militares de Israel'
date: 2026-03-08 date: 2026-03-08T00:00:00.000Z
slug: 2026-03-08-palabras-por-el-dia-internacional-de-la-mujer-dirigidas-a-las-mujeres-de-las-fuerzas-militares-de-israel slug: 2026-03-08-palabras-por-el-dia-internacional-de-la-mujer-dirigidas-a-las-mujeres-de-las-fuerzas-militares-de-israel
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,h-720,cm-pad_resize,bg-blurred/woman-day-2.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280,h-720,cm-pad_resize,bg-blurred/woman-day-2.webp'
tags: [Israel]
--- ---
En este Día Internacional de la Mujer, quiero felicitar a cada una de las mujeres que visten el uniforme del ejército de Israel. En este Día Internacional de la Mujer, quiero felicitar a cada una de las mujeres que visten el uniforme del ejército de Israel.
Ustedes viven el legado de las mujeres que, desde la fundación de este Estado, entendieron que la paz no es algo que se recibe, sino algo que se protege con determinación. En los puestos de mando, en el terreno, en la tecnología y en la logística, ustedes son la columna vertebral de nuestra defensa. Ustedes viven el legado de las mujeres que, desde la fundación de este Estado, entendieron que la paz no es algo que se recibe, sino algo que se protege con determinación. En los puestos de mando, en el terreno, en la tecnología y en la logística, ustedes son la columna vertebral de nuestra defensa.
@ -22,4 +24,4 @@ Ustedes demuestran, con cada misión cumplida, que el valor no tiene género, y
¡Am Israel Jai! ¡Am Israel Jai!
**Dr. José Benjamín Pérez Matos** **Dr. José Benjamín Pérez Matos**

View File

@ -4,6 +4,7 @@ title: 'Declaración oficial de solidaridad y condena por el ataque a la ciudad
date: 2026-03-22 date: 2026-03-22
slug: 2026-03-22-declaracion-oficial-de-solidaridad-y-condena-por-el-ataque-a-la-ciudad-de-arad slug: 2026-03-22-declaracion-oficial-de-solidaridad-y-condena-por-el-ataque-a-la-ciudad-de-arad
place: '' place: ''
tags: [Israel, Comunicado, Irán]
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-2.png' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-2.png'
gallery: [ gallery: [
{ {

View File

@ -5,6 +5,7 @@ date: 2026-03-23
slug: 2026-03-23-el-dr-jose-benjamin-perez-anticipa-el-fin-de-las-estructuras-imperiales-en-oriente-medio-durante-conferencia-en-puerto-rico slug: 2026-03-23-el-dr-jose-benjamin-perez-anticipa-el-fin-de-las-estructuras-imperiales-en-oriente-medio-durante-conferencia-en-puerto-rico
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/04_02-1080X1080-webpage.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/04_02-1080X1080-webpage.webp'
tags: [Irán]
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/04_02-1080X1080-webpage.webp', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/04_02-1080X1080-webpage.webp',

View File

@ -5,6 +5,7 @@ date: 2026-03-29
slug: 2026-03-29-repudio-al-ataque-contra-el-complejo-industrial-de-neot-hovav-en-israel-implicancias-bajo-el-derecho-internacional-y-la-seguridad-estrategica slug: 2026-03-29-repudio-al-ataque-contra-el-complejo-industrial-de-neot-hovav-en-israel-implicancias-bajo-el-derecho-internacional-y-la-seguridad-estrategica
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-03-29_20-51-04.jpg' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/photo_2026-03-29_20-51-04.jpg'
tags: [Irán, Israel]
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-03-29_20-51-04.jpg', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/photo_2026-03-29_20-51-04.jpg',

View File

@ -6,6 +6,7 @@ slug: 2026-04-02-el-dr-jose-benjamin-perez-hablo-en-cayey-sobre-repercusiones-gl
place: '' place: ''
city: Cayey city: Cayey
country: PR country: PR
tags: [Puerto Rico]
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/new-crpj-1.jpeg' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/new-crpj-1.jpeg'
gallery: [ gallery: [
{ {

View File

@ -5,6 +5,7 @@ date: 2026-04-03
slug: 2026-04-03-la-embajada-de-iran-en-uruguay-vulnera-las-normas-internacionales-al-atacar-a-argentina-y-se-espera-una-respuesta-firme-del-presidente-yamandu-orsi slug: 2026-04-03-la-embajada-de-iran-en-uruguay-vulnera-las-normas-internacionales-al-atacar-a-argentina-y-se-espera-una-respuesta-firme-del-presidente-yamandu-orsi
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp'
tags: [Uruguay, Irán, Comunicado]
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',

View File

@ -5,6 +5,7 @@ date: 2026-04-11
slug: 2026-04-11-la-tension-internacional-y-advertencias-el-dr-perez-matos-analiza-el-posicionamiento-de-espana-y-francia-frente-a-israel slug: 2026-04-11-la-tension-internacional-y-advertencias-el-dr-perez-matos-analiza-el-posicionamiento-de-espana-y-francia-frente-a-israel
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280//banderas-1a1.png' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280//banderas-1a1.png'
tags: [España, Francia, Israel]
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred//banderas-1a1.png', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred//banderas-1a1.png',

View File

@ -5,6 +5,7 @@ date: 2026-04-15
slug: 2026-04-15-el-rol-de-israel-y-el-destino-de-las-naciones-en-el-panorama-actual slug: 2026-04-15-el-rol-de-israel-y-el-destino-de-las-naciones-en-el-panorama-actual
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp'
tags: [Comunicado, Israel]
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',

View File

@ -5,6 +5,10 @@ date: 2026-04-15
slug: 2026-04-15-el-rol-de-israel-y-el-destino-de-las-naciones-en-el-panorama-actual slug: 2026-04-15-el-rol-de-israel-y-el-destino-de-las-naciones-en-el-panorama-actual
place: '' place: ''
thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp' thumbnail: 'https://ik.imagekit.io/crpy/tr:w-1280/comunicado-1.webp'
<<<<<<< HEAD
=======
tags: [Irán, Israel]
>>>>>>> archiveUpdate
gallery: [ gallery: [
{ {
image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp', image: 'https://ik.imagekit.io/crpy/tr:w-1280,h-900,cm-pad_resize,bg-blurred/comunicado-1.webp',

View File

@ -3,8 +3,10 @@
"nav.logo_line2": "and Justice Center", "nav.logo_line2": "and Justice Center",
"nav.about": "About", "nav.about": "About",
"nav.news": "News", "nav.news": "News",
"nav.archive": "Archive",
"nav.programs": "Programs", "nav.programs": "Programs",
"nav.contact": "Contact", "nav.contact": "Contact",
"nav.nations": "Nations",
"hero.name": "Dr. José Benjamín Pérez Matos", "hero.name": "Dr. José Benjamín Pérez Matos",
"hero.title": "Founding Leader", "hero.title": "Founding Leader",
"hero.body": "“My lifes dream is to see the prophets vision fulfilled: a world of justice and peace for the good of Israel and all mankind.”", "hero.body": "“My lifes dream is to see the prophets vision fulfilled: a world of justice and peace for the good of Israel and all mankind.”",
@ -180,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.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.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.buttonLable": "See More News",
"news.seemore": "See More",
"news.all": "All",
"participate.title": "Participate | Collaborate", "participate.title": "Participate | Collaborate",

View File

@ -4,6 +4,8 @@
"nav.about": "Somos", "nav.about": "Somos",
"nav.news": "Noticias", "nav.news": "Noticias",
"nav.programs": "Programas", "nav.programs": "Programas",
"nav.archive": "Archivo",
"nav.nations": "Naciones",
"nav.contact": "Contacto", "nav.contact": "Contacto",
"hero.name": "Dr. José Benjamín Pérez Matos", "hero.name": "Dr. José Benjamín Pérez Matos",
@ -186,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.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.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.buttonLable": "Ver Más Noticias",
"news.seemore": "Ver Más",
"news.all": "Todas",
"participate.title": "Participa | Colabora", "participate.title": "Participa | Colabora",
"participate.text": "Sumarse es asumir un compromiso con propósito", "participate.text": "Sumarse es asumir un compromiso con propósito",
@ -204,6 +208,4 @@
"footer.form.mesagge": "Escriba su mensaje", "footer.form.mesagge": "Escriba su mensaje",
"footer.form.button": "Enviar", "footer.form.button": "Enviar",
"footer.reserved": "©2026. Todos los Derechos Reservados. Centro del Reino de Paz y Justicia" "footer.reserved": "©2026. Todos los Derechos Reservados. Centro del Reino de Paz y Justicia"
} }

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page document.astro goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page index of documents goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page content goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page nations [nation] goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page index of nations goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -35,12 +35,16 @@ const routeTranslations = {
const baseSlug = routeTranslations.news[locale] || routeTranslations.news.en; 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 <MainLayout
title={post.data.title} title={post.data.title}
description={`${post.data.title} - ${post.data.city ?? ""} ${post.data.country ?? ""}`} description={excerpt}
image={post.data.thumbnail} image={post.data.thumbnail}
url={new URL(`/${locale}/${"news"}/${post.id}`, Astro.site)} url={new URL(`/${locale}/${"news"}/${post.id}`, Astro.site)}
> >
@ -48,27 +52,32 @@ const baseSlug = routeTranslations.news[locale] || routeTranslations.news.en;
<Header /> <Header />
</div> </div>
<TitleSection title={post.data.title} /> <a href={`/${locale}/news/${post.id}`} class="block">
<TitleSection title={post.data.title} />
</a>
<div class="container mx-auto"> <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">
<div class="grid md:grid-cols-10"> {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}
<div class="md:col-span-7 content bg-white p-8 md:p-20 prose-p:mb-4 text-[#003421] text-justify"> </a>
<Content />
</div>
<div class="md:col-span-3 bg-tertiary md:sticky top-0 h-fit">
{ post.data.youtube && (
<YouTube id={post.data.youtube} />
)} <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 && ( {post.data.gallery && (
post.data.gallery.map(galleryImage => ( post.data.gallery.map(galleryImage => (
<Image src={galleryImage.image} alt={galleryImage.text} /> <Image src={galleryImage.image} alt={galleryImage.text} />
)) ))
)} )}
</div>
</div> </div>
</div> </div>
</MainLayout> </MainLayout>

View File

@ -1,20 +1,32 @@
--- ---
import MainLayout from "@/layouts/MainLayout.astro" import MainLayout from "@/layouts/MainLayout.astro"
import NewsSection from "@/components/section/NewsSection.astro"
import Header from "@/components/Header.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 { getCollection, getEntry } from "astro:content";
import FooterSection from "@/components/section/FooterSection.astro"; 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 tl = createTranslator(Astro.currentLocale);
const newsItems = await getCollection("news", (post)=>{ const newsItems = await getCollection("news", (post)=>{
const currentLocale = Astro.currentLocale; const currentLocale = Astro.currentLocale;
return post.data.locale == 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 > <MainLayout >
@ -25,27 +37,98 @@ const newsItems = await getCollection("news", (post)=>{
<div class="flex flex-col lg:w-1/2 items-center mx-auto py-8"> <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> <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> <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> </div>
{allTags.length > 0 && (
<div class="flex flex-col md:gap-8 gap-2 lg:max-w-4xl mx-auto bg-white p-8"> <div class="container mx-auto mb-8">
{ <div class="flex flex-wrap gap-2 justify-center">
[...newsItems] <button class="filter-btn px-4 py-2 font-primary text-sm cursor-pointer transition-colors" data-tag="all">
.sort((a, b) => { {tl("news.all")}
const dateDiff = </button>
new Date(b.data.date).getTime() - new Date(a.data.date).getTime() {allTags.map((tag) => (
<button class="filter-btn px-4 py-2 font-primary text-sm cursor-pointer transition-colors" data-tag={tag!}>
if (dateDiff !== 0) return dateDiff {tag}
</button>
return (a.data.order ?? 0) - (b.data.order ?? 0) ))}
}) </div>
.map((item) => (
<NewsList data={item} />
))
}
</div> </div>
)}
<div class="flex flex-col md:gap-0 gap-2 lg:max-w-4xl mx-auto bg-white p-4 md:p-8">
{
sortedPosts.map((item) => (
<div class="news-item" data-tags={JSON.stringify(item.data.tags || [])}>
<NewsList data={item} content={{ body: item.body }} />
</div>
))
}
</div>
</div> </div>
<FooterSection /> <FooterSection />
</MainLayout> </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());
}
function initTags() {
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.classList.add(...inactiveClasses.split(" "));
});
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('tag')) {
urlParams.delete('tag');
window.history.replaceState({}, '', window.location.pathname + window.location.search);
}
document.querySelector('.filter-btn[data-tag="all"]')?.classList.add(...activeClasses.split(" "));
document.querySelector('.filter-btn[data-tag="all"]')?.classList.remove(...inactiveClasses.split(" "));
activateTag('all');
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', () => {
const tag = btn.getAttribute('data-tag');
activateTag(tag);
updateUrl(tag);
});
});
}
document.addEventListener('astro:page-load', initTags);
if (document.readyState === 'complete') {
initTags();
}
</script>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page document.astro goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page index of documents goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page content goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page nations [nation] goes here
</div>
</div>
<FooterSection />
</MainLayout>

View File

@ -0,0 +1,19 @@
---
import MainLayout from "@/layouts/MainLayout.astro"
import Header from "@/components/Header.astro"
import FooterSection from "@/components/section/FooterSection.astro";
import { createTranslator, t } from '@/i18n';
const tl = createTranslator(Astro.currentLocale);
---
<MainLayout >
<div class="top-16 relative mb container mx-auto">
<Header />
<div class="container mx-auto mt-4">
page index of nations goes here
</div>
</div>
<FooterSection />
</MainLayout>

1
tina/__generated__/_graphql.json generated Normal file

File diff suppressed because one or more lines are too long

1
tina/__generated__/_lookup.json generated Normal file
View File

@ -0,0 +1 @@
{"DocumentConnection":{"type":"DocumentConnection","resolveType":"multiCollectionDocumentList","collections":["news","documentaries"]},"Node":{"type":"Node","resolveType":"nodeDocument"},"DocumentNode":{"type":"DocumentNode","resolveType":"multiCollectionDocument","createDocument":"create","updateDocument":"update"},"News":{"type":"News","resolveType":"collectionDocument","collection":"news","createNews":"create","updateNews":"update"},"NewsConnection":{"type":"NewsConnection","resolveType":"collectionDocumentList","collection":"news"},"Documentaries":{"type":"Documentaries","resolveType":"collectionDocument","collection":"documentaries","createDocumentaries":"create","updateDocumentaries":"update"},"DocumentariesConnection":{"type":"DocumentariesConnection","resolveType":"collectionDocumentList","collection":"documentaries"}}

1
tina/__generated__/_schema.json generated Normal file
View File

@ -0,0 +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":"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"}}}}

5
tina/__generated__/client.ts generated Normal file
View File

@ -0,0 +1,5 @@
import { createClient } from "tinacms/dist/client";
import { queries } from "./types";
export const client = createClient({ url: 'http://localhost:4001/graphql', token: 'null', queries, });
export default client;

125
tina/__generated__/config.prebuild.jsx generated Normal file
View File

@ -0,0 +1,125 @@
// tina/config.ts
import { defineConfig } from "tinacms";
var branch = process.env.HEAD || process.env.VERCEL_GIT_COMMIT_REF || "main";
var config_default = defineConfig({
branch,
clientId: null,
token: null,
build: {
outputFolder: "admin",
publicFolder: "public"
},
media: {
tina: {
mediaRoot: "public/images",
publicFolder: "public"
}
},
schema: {
collections: [
{
name: "news",
label: "News",
path: "src/content/news",
format: "md",
fields: [
{
type: "string",
name: "locale",
label: "Language",
options: [
{ label: "Espa\xF1ol", value: "es" },
{ label: "English", value: "en" }
]
},
{
type: "string",
name: "title",
label: "Title",
isTitle: true,
required: true
},
{
type: "datetime",
name: "date",
label: "Date",
required: true
},
{
type: "string",
name: "slug",
label: "Slug"
},
{
type: "string",
name: "place",
label: "Place"
},
{
type: "string",
name: "thumbnail",
label: "Thumbnail URL"
},
{
type: "string",
name: "youtube",
label: "YouTube ID"
},
{
type: "string",
name: "tags",
label: "Tags (comma separated)"
},
{
type: "boolean",
name: "draft",
label: "Draft"
},
{
type: "rich-text",
name: "body",
label: "Content",
isBody: true
}
]
},
{
name: "documentaries",
label: "Documentaries",
path: "src/content/documentaries",
format: "md",
fields: [
{
type: "string",
name: "locale",
label: "Language",
options: [
{ label: "Espa\xF1ol", value: "es" }
]
},
{
type: "string",
name: "title",
label: "Title",
isTitle: true,
required: true
},
{
type: "string",
name: "video_yt",
label: "YouTube ID"
},
{
type: "datetime",
name: "date",
label: "Date",
required: true
}
]
}
]
}
});
export {
config_default as default
};

21
tina/__generated__/frags.gql generated Normal file
View File

@ -0,0 +1,21 @@
fragment NewsParts on News {
__typename
locale
title
date
slug
place
thumbnail
youtube
tags
draft
body
}
fragment DocumentariesParts on Documentaries {
__typename
locale
title
video_yt
date
}

109
tina/__generated__/queries.gql generated Normal file
View File

@ -0,0 +1,109 @@
query news($relativePath: String!) {
news(relativePath: $relativePath) {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...NewsParts
}
}
query newsConnection($before: String, $after: String, $first: Float, $last: Float, $sort: String, $filter: NewsFilter) {
newsConnection(
before: $before
after: $after
first: $first
last: $last
sort: $sort
filter: $filter
) {
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
totalCount
edges {
cursor
node {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...NewsParts
}
}
}
}
query documentaries($relativePath: String!) {
documentaries(relativePath: $relativePath) {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...DocumentariesParts
}
}
query documentariesConnection($before: String, $after: String, $first: Float, $last: Float, $sort: String, $filter: DocumentariesFilter) {
documentariesConnection(
before: $before
after: $after
first: $first
last: $last
sort: $sort
filter: $filter
) {
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
totalCount
edges {
cursor
node {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...DocumentariesParts
}
}
}
}

233
tina/__generated__/schema.gql generated Normal file
View File

@ -0,0 +1,233 @@
# DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
"""References another document, used as a foreign key"""
scalar Reference
""""""
scalar JSON
type SystemInfo {
filename: String!
title: String
basename: String!
hasReferences: Boolean
breadcrumbs(excludeExtension: Boolean): [String!]!
path: String!
relativePath: String!
extension: String!
template: String!
collection: Collection!
}
type Folder {
name: String!
path: String!
}
type PageInfo {
hasPreviousPage: Boolean!
hasNextPage: Boolean!
startCursor: String!
endCursor: String!
}
""""""
interface Node {
id: ID!
}
""""""
interface Document {
id: ID!
_sys: SystemInfo
_values: JSON!
}
"""A relay-compliant pagination connection"""
interface Connection {
totalCount: Float!
pageInfo: PageInfo!
}
type Query {
getOptimizedQuery(queryString: String!): String
collection(collection: String): Collection!
collections: [Collection!]!
node(id: String): Node!
document(collection: String, relativePath: String): DocumentNode!
news(relativePath: String): News!
newsConnection(before: String, after: String, first: Float, last: Float, sort: String, filter: NewsFilter): NewsConnection!
documentaries(relativePath: String): Documentaries!
documentariesConnection(before: String, after: String, first: Float, last: Float, sort: String, filter: DocumentariesFilter): DocumentariesConnection!
}
input DocumentFilter {
news: NewsFilter
documentaries: DocumentariesFilter
}
type DocumentConnectionEdges {
cursor: String!
node: DocumentNode
}
type DocumentConnection implements Connection {
pageInfo: PageInfo!
totalCount: Float!
edges: [DocumentConnectionEdges]
}
type Collection {
name: String!
slug: String!
label: String
path: String!
format: String
matches: String
templates: [JSON]
fields: [JSON]
documents(before: String, after: String, first: Float, last: Float, sort: String, filter: DocumentFilter, folder: String): DocumentConnection!
}
union DocumentNode = News | Documentaries | Folder
type News implements Node & Document {
locale: String
title: String!
date: String!
slug: String
place: String
thumbnail: String
youtube: String
tags: String
draft: Boolean
body: JSON
id: ID!
_sys: SystemInfo!
_values: JSON!
}
input StringFilter {
startsWith: String
eq: String
exists: Boolean
in: [String]
}
input DatetimeFilter {
after: String
before: String
eq: String
exists: Boolean
in: [String]
}
input BooleanFilter {
eq: Boolean
exists: Boolean
}
input RichTextFilter {
startsWith: String
eq: String
exists: Boolean
}
input NewsFilter {
locale: StringFilter
title: StringFilter
date: DatetimeFilter
slug: StringFilter
place: StringFilter
thumbnail: StringFilter
youtube: StringFilter
tags: StringFilter
draft: BooleanFilter
body: RichTextFilter
}
type NewsConnectionEdges {
cursor: String!
node: News
}
type NewsConnection implements Connection {
pageInfo: PageInfo!
totalCount: Float!
edges: [NewsConnectionEdges]
}
type Documentaries implements Node & Document {
locale: String
title: String!
video_yt: String
date: String!
id: ID!
_sys: SystemInfo!
_values: JSON!
}
input DocumentariesFilter {
locale: StringFilter
title: StringFilter
video_yt: StringFilter
date: DatetimeFilter
}
type DocumentariesConnectionEdges {
cursor: String!
node: Documentaries
}
type DocumentariesConnection implements Connection {
pageInfo: PageInfo!
totalCount: Float!
edges: [DocumentariesConnectionEdges]
}
type Mutation {
addPendingDocument(collection: String!, relativePath: String!, template: String): DocumentNode!
updateDocument(collection: String, relativePath: String!, params: DocumentUpdateMutation!): DocumentNode!
deleteDocument(collection: String, relativePath: String!): DocumentNode!
createDocument(collection: String, relativePath: String!, params: DocumentMutation!): DocumentNode!
createFolder(collection: String, relativePath: String!): DocumentNode!
updateNews(relativePath: String!, params: NewsMutation!): News!
createNews(relativePath: String!, params: NewsMutation!): News!
updateDocumentaries(relativePath: String!, params: DocumentariesMutation!): Documentaries!
createDocumentaries(relativePath: String!, params: DocumentariesMutation!): Documentaries!
}
input DocumentUpdateMutation {
news: NewsMutation
documentaries: DocumentariesMutation
relativePath: String
}
input DocumentMutation {
news: NewsMutation
documentaries: DocumentariesMutation
}
input NewsMutation {
locale: String
title: String
date: String
slug: String
place: String
thumbnail: String
youtube: String
tags: String
draft: Boolean
body: JSON
}
input DocumentariesMutation {
locale: String
title: String
video_yt: String
date: String
}
schema {
query: Query
mutation: Mutation
}

1
tina/__generated__/static-media.json generated Normal file
View File

@ -0,0 +1 @@
[]

642
tina/__generated__/types.ts generated Normal file
View File

@ -0,0 +1,642 @@
//@ts-nocheck
// DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
export function gql(strings: TemplateStringsArray, ...args: string[]): string {
let str = ''
strings.forEach((string, i) => {
str += string + (args[i] || '')
})
return str
}
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
export type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };
export type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: { input: string; output: string; }
String: { input: string; output: string; }
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
/** References another document, used as a foreign key */
Reference: { input: any; output: any; }
JSON: { input: any; output: any; }
};
export type SystemInfo = {
__typename?: 'SystemInfo';
filename: Scalars['String']['output'];
title?: Maybe<Scalars['String']['output']>;
basename: Scalars['String']['output'];
hasReferences?: Maybe<Scalars['Boolean']['output']>;
breadcrumbs: Array<Scalars['String']['output']>;
path: Scalars['String']['output'];
relativePath: Scalars['String']['output'];
extension: Scalars['String']['output'];
template: Scalars['String']['output'];
collection: Collection;
};
export type SystemInfoBreadcrumbsArgs = {
excludeExtension?: InputMaybe<Scalars['Boolean']['input']>;
};
export type Folder = {
__typename?: 'Folder';
name: Scalars['String']['output'];
path: Scalars['String']['output'];
};
export type PageInfo = {
__typename?: 'PageInfo';
hasPreviousPage: Scalars['Boolean']['output'];
hasNextPage: Scalars['Boolean']['output'];
startCursor: Scalars['String']['output'];
endCursor: Scalars['String']['output'];
};
export type Node = {
id: Scalars['ID']['output'];
};
export type Document = {
id: Scalars['ID']['output'];
_sys?: Maybe<SystemInfo>;
_values: Scalars['JSON']['output'];
};
/** A relay-compliant pagination connection */
export type Connection = {
totalCount: Scalars['Float']['output'];
pageInfo: PageInfo;
};
export type Query = {
__typename?: 'Query';
getOptimizedQuery?: Maybe<Scalars['String']['output']>;
collection: Collection;
collections: Array<Collection>;
node: Node;
document: DocumentNode;
news: News;
newsConnection: NewsConnection;
documentaries: Documentaries;
documentariesConnection: DocumentariesConnection;
};
export type QueryGetOptimizedQueryArgs = {
queryString: Scalars['String']['input'];
};
export type QueryCollectionArgs = {
collection?: InputMaybe<Scalars['String']['input']>;
};
export type QueryNodeArgs = {
id?: InputMaybe<Scalars['String']['input']>;
};
export type QueryDocumentArgs = {
collection?: InputMaybe<Scalars['String']['input']>;
relativePath?: InputMaybe<Scalars['String']['input']>;
};
export type QueryNewsArgs = {
relativePath?: InputMaybe<Scalars['String']['input']>;
};
export type QueryNewsConnectionArgs = {
before?: InputMaybe<Scalars['String']['input']>;
after?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Float']['input']>;
last?: InputMaybe<Scalars['Float']['input']>;
sort?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<NewsFilter>;
};
export type QueryDocumentariesArgs = {
relativePath?: InputMaybe<Scalars['String']['input']>;
};
export type QueryDocumentariesConnectionArgs = {
before?: InputMaybe<Scalars['String']['input']>;
after?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Float']['input']>;
last?: InputMaybe<Scalars['Float']['input']>;
sort?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<DocumentariesFilter>;
};
export type DocumentFilter = {
news?: InputMaybe<NewsFilter>;
documentaries?: InputMaybe<DocumentariesFilter>;
};
export type DocumentConnectionEdges = {
__typename?: 'DocumentConnectionEdges';
cursor: Scalars['String']['output'];
node?: Maybe<DocumentNode>;
};
export type DocumentConnection = Connection & {
__typename?: 'DocumentConnection';
pageInfo: PageInfo;
totalCount: Scalars['Float']['output'];
edges?: Maybe<Array<Maybe<DocumentConnectionEdges>>>;
};
export type Collection = {
__typename?: 'Collection';
name: Scalars['String']['output'];
slug: Scalars['String']['output'];
label?: Maybe<Scalars['String']['output']>;
path: Scalars['String']['output'];
format?: Maybe<Scalars['String']['output']>;
matches?: Maybe<Scalars['String']['output']>;
templates?: Maybe<Array<Maybe<Scalars['JSON']['output']>>>;
fields?: Maybe<Array<Maybe<Scalars['JSON']['output']>>>;
documents: DocumentConnection;
};
export type CollectionDocumentsArgs = {
before?: InputMaybe<Scalars['String']['input']>;
after?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Float']['input']>;
last?: InputMaybe<Scalars['Float']['input']>;
sort?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<DocumentFilter>;
folder?: InputMaybe<Scalars['String']['input']>;
};
export type DocumentNode = News | Documentaries | Folder;
export type News = Node & Document & {
__typename?: 'News';
locale?: Maybe<Scalars['String']['output']>;
title: Scalars['String']['output'];
date: Scalars['String']['output'];
slug?: Maybe<Scalars['String']['output']>;
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'];
_sys: SystemInfo;
_values: Scalars['JSON']['output'];
};
export type StringFilter = {
startsWith?: InputMaybe<Scalars['String']['input']>;
eq?: InputMaybe<Scalars['String']['input']>;
exists?: InputMaybe<Scalars['Boolean']['input']>;
in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type DatetimeFilter = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
eq?: InputMaybe<Scalars['String']['input']>;
exists?: InputMaybe<Scalars['Boolean']['input']>;
in?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
};
export type BooleanFilter = {
eq?: InputMaybe<Scalars['Boolean']['input']>;
exists?: InputMaybe<Scalars['Boolean']['input']>;
};
export type RichTextFilter = {
startsWith?: InputMaybe<Scalars['String']['input']>;
eq?: InputMaybe<Scalars['String']['input']>;
exists?: InputMaybe<Scalars['Boolean']['input']>;
};
export type NewsFilter = {
locale?: InputMaybe<StringFilter>;
title?: InputMaybe<StringFilter>;
date?: InputMaybe<DatetimeFilter>;
slug?: InputMaybe<StringFilter>;
place?: InputMaybe<StringFilter>;
thumbnail?: InputMaybe<StringFilter>;
youtube?: InputMaybe<StringFilter>;
tags?: InputMaybe<StringFilter>;
draft?: InputMaybe<BooleanFilter>;
body?: InputMaybe<RichTextFilter>;
};
export type NewsConnectionEdges = {
__typename?: 'NewsConnectionEdges';
cursor: Scalars['String']['output'];
node?: Maybe<News>;
};
export type NewsConnection = Connection & {
__typename?: 'NewsConnection';
pageInfo: PageInfo;
totalCount: Scalars['Float']['output'];
edges?: Maybe<Array<Maybe<NewsConnectionEdges>>>;
};
export type Documentaries = Node & Document & {
__typename?: 'Documentaries';
locale?: Maybe<Scalars['String']['output']>;
title: Scalars['String']['output'];
video_yt?: Maybe<Scalars['String']['output']>;
date: Scalars['String']['output'];
id: Scalars['ID']['output'];
_sys: SystemInfo;
_values: Scalars['JSON']['output'];
};
export type DocumentariesFilter = {
locale?: InputMaybe<StringFilter>;
title?: InputMaybe<StringFilter>;
video_yt?: InputMaybe<StringFilter>;
date?: InputMaybe<DatetimeFilter>;
};
export type DocumentariesConnectionEdges = {
__typename?: 'DocumentariesConnectionEdges';
cursor: Scalars['String']['output'];
node?: Maybe<Documentaries>;
};
export type DocumentariesConnection = Connection & {
__typename?: 'DocumentariesConnection';
pageInfo: PageInfo;
totalCount: Scalars['Float']['output'];
edges?: Maybe<Array<Maybe<DocumentariesConnectionEdges>>>;
};
export type Mutation = {
__typename?: 'Mutation';
addPendingDocument: DocumentNode;
updateDocument: DocumentNode;
deleteDocument: DocumentNode;
createDocument: DocumentNode;
createFolder: DocumentNode;
updateNews: News;
createNews: News;
updateDocumentaries: Documentaries;
createDocumentaries: Documentaries;
};
export type MutationAddPendingDocumentArgs = {
collection: Scalars['String']['input'];
relativePath: Scalars['String']['input'];
template?: InputMaybe<Scalars['String']['input']>;
};
export type MutationUpdateDocumentArgs = {
collection?: InputMaybe<Scalars['String']['input']>;
relativePath: Scalars['String']['input'];
params: DocumentUpdateMutation;
};
export type MutationDeleteDocumentArgs = {
collection?: InputMaybe<Scalars['String']['input']>;
relativePath: Scalars['String']['input'];
};
export type MutationCreateDocumentArgs = {
collection?: InputMaybe<Scalars['String']['input']>;
relativePath: Scalars['String']['input'];
params: DocumentMutation;
};
export type MutationCreateFolderArgs = {
collection?: InputMaybe<Scalars['String']['input']>;
relativePath: Scalars['String']['input'];
};
export type MutationUpdateNewsArgs = {
relativePath: Scalars['String']['input'];
params: NewsMutation;
};
export type MutationCreateNewsArgs = {
relativePath: Scalars['String']['input'];
params: NewsMutation;
};
export type MutationUpdateDocumentariesArgs = {
relativePath: Scalars['String']['input'];
params: DocumentariesMutation;
};
export type MutationCreateDocumentariesArgs = {
relativePath: Scalars['String']['input'];
params: DocumentariesMutation;
};
export type DocumentUpdateMutation = {
news?: InputMaybe<NewsMutation>;
documentaries?: InputMaybe<DocumentariesMutation>;
relativePath?: InputMaybe<Scalars['String']['input']>;
};
export type DocumentMutation = {
news?: InputMaybe<NewsMutation>;
documentaries?: InputMaybe<DocumentariesMutation>;
};
export type NewsMutation = {
locale?: InputMaybe<Scalars['String']['input']>;
title?: InputMaybe<Scalars['String']['input']>;
date?: InputMaybe<Scalars['String']['input']>;
slug?: InputMaybe<Scalars['String']['input']>;
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']>;
};
export type DocumentariesMutation = {
locale?: InputMaybe<Scalars['String']['input']>;
title?: InputMaybe<Scalars['String']['input']>;
video_yt?: InputMaybe<Scalars['String']['input']>;
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, 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 };
export type NewsQueryVariables = Exact<{
relativePath: Scalars['String']['input'];
}>;
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']>;
after?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Float']['input']>;
last?: InputMaybe<Scalars['Float']['input']>;
sort?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<NewsFilter>;
}>;
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'];
}>;
export type DocumentariesQuery = { __typename?: 'Query', documentaries: { __typename: 'Documentaries', id: string, locale?: string | null, title: string, video_yt?: string | null, date: string, _sys: { __typename?: 'SystemInfo', filename: string, basename: string, hasReferences?: boolean | null, breadcrumbs: Array<string>, path: string, relativePath: string, extension: string } } };
export type DocumentariesConnectionQueryVariables = Exact<{
before?: InputMaybe<Scalars['String']['input']>;
after?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Float']['input']>;
last?: InputMaybe<Scalars['Float']['input']>;
sort?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<DocumentariesFilter>;
}>;
export type DocumentariesConnectionQuery = { __typename?: 'Query', documentariesConnection: { __typename?: 'DocumentariesConnection', totalCount: number, pageInfo: { __typename?: 'PageInfo', hasPreviousPage: boolean, hasNextPage: boolean, startCursor: string, endCursor: string }, edges?: Array<{ __typename?: 'DocumentariesConnectionEdges', cursor: string, node?: { __typename: 'Documentaries', id: string, locale?: string | null, title: string, video_yt?: string | null, date: string, _sys: { __typename?: 'SystemInfo', filename: string, basename: string, hasReferences?: boolean | null, breadcrumbs: Array<string>, path: string, relativePath: string, extension: string } } | null } | null> | null } };
export const NewsPartsFragmentDoc = gql`
fragment NewsParts on News {
__typename
locale
title
date
slug
place
thumbnail
youtube
tags
draft
body
}
`;
export const DocumentariesPartsFragmentDoc = gql`
fragment DocumentariesParts on Documentaries {
__typename
locale
title
video_yt
date
}
`;
export const NewsDocument = gql`
query news($relativePath: String!) {
news(relativePath: $relativePath) {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...NewsParts
}
}
${NewsPartsFragmentDoc}`;
export const NewsConnectionDocument = gql`
query newsConnection($before: String, $after: String, $first: Float, $last: Float, $sort: String, $filter: NewsFilter) {
newsConnection(
before: $before
after: $after
first: $first
last: $last
sort: $sort
filter: $filter
) {
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
totalCount
edges {
cursor
node {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...NewsParts
}
}
}
}
${NewsPartsFragmentDoc}`;
export const DocumentariesDocument = gql`
query documentaries($relativePath: String!) {
documentaries(relativePath: $relativePath) {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...DocumentariesParts
}
}
${DocumentariesPartsFragmentDoc}`;
export const DocumentariesConnectionDocument = gql`
query documentariesConnection($before: String, $after: String, $first: Float, $last: Float, $sort: String, $filter: DocumentariesFilter) {
documentariesConnection(
before: $before
after: $after
first: $first
last: $last
sort: $sort
filter: $filter
) {
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
totalCount
edges {
cursor
node {
... on Document {
_sys {
filename
basename
hasReferences
breadcrumbs
path
relativePath
extension
}
id
}
...DocumentariesParts
}
}
}
}
${DocumentariesPartsFragmentDoc}`;
export type Requester<C= {}> = <R, V>(doc: DocumentNode, vars?: V, options?: C) => Promise<R>
export function getSdk<C>(requester: Requester<C>) {
return {
news(variables: NewsQueryVariables, options?: C): Promise<{data: NewsQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: NewsQueryVariables, query: string}> {
return requester<{data: NewsQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: NewsQueryVariables, query: string}, NewsQueryVariables>(NewsDocument, variables, options);
},
newsConnection(variables?: NewsConnectionQueryVariables, options?: C): Promise<{data: NewsConnectionQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: NewsConnectionQueryVariables, query: string}> {
return requester<{data: NewsConnectionQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: NewsConnectionQueryVariables, query: string}, NewsConnectionQueryVariables>(NewsConnectionDocument, variables, options);
},
documentaries(variables: DocumentariesQueryVariables, options?: C): Promise<{data: DocumentariesQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: DocumentariesQueryVariables, query: string}> {
return requester<{data: DocumentariesQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: DocumentariesQueryVariables, query: string}, DocumentariesQueryVariables>(DocumentariesDocument, variables, options);
},
documentariesConnection(variables?: DocumentariesConnectionQueryVariables, options?: C): Promise<{data: DocumentariesConnectionQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: DocumentariesConnectionQueryVariables, query: string}> {
return requester<{data: DocumentariesConnectionQuery, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: DocumentariesConnectionQueryVariables, query: string}, DocumentariesConnectionQueryVariables>(DocumentariesConnectionDocument, variables, options);
}
};
}
export type Sdk = ReturnType<typeof getSdk>;
// TinaSDK generated code
import { createClient, TinaClient } from "tinacms/dist/client";
const generateRequester = (
client: TinaClient,
) => {
const requester: (
doc: any,
vars?: any,
options?: {
branch?: string,
/**
* Aside from `method` and `body`, all fetch options are passed
* through to underlying fetch request
*/
fetchOptions?: Omit<Parameters<typeof fetch>[1], 'body' | 'method'>,
},
client
) => Promise<any> = async (doc, vars, options) => {
let url = client.apiUrl
if (options?.branch) {
const index = client.apiUrl.lastIndexOf('/')
url = client.apiUrl.substring(0, index + 1) + options.branch
}
const data = await client.request({
query: doc,
variables: vars,
url,
}, options)
return { data: data?.data, errors: data?.errors, query: doc, variables: vars || {} }
}
return requester
}
/**
* @experimental this class can be used but may change in the future
**/
export const ExperimentalGetTinaClient = () =>
getSdk(
generateRequester(
createClient({
url: "http://localhost:4001/graphql",
queries,
})
)
)
export const queries = (
client: TinaClient,
) => {
const requester = generateRequester(client)
return getSdk(requester)
}

9
tina/auth.ts Normal file
View File

@ -0,0 +1,9 @@
import { TinaAuth } from "tinacms";
const branch = process.env.HEAD || process.env.VERCEL_GIT_COMMIT_REF || "main";
export const auth = TinaAuth({
branch,
clientId: null,
token: null,
});

123
tina/config.ts Normal file
View File

@ -0,0 +1,123 @@
import { defineConfig } from "tinacms";
const branch = process.env.HEAD || process.env.VERCEL_GIT_COMMIT_REF || "main";
export default defineConfig({
branch,
clientId: null,
token: null,
build: {
outputFolder: "admin",
publicFolder: "public",
},
media: {
tina: {
mediaRoot: "public/images",
publicFolder: "public",
},
},
schema: {
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" },
],
},
{
type: "string",
name: "title",
label: "Title",
isTitle: true,
required: true,
},
{
type: "datetime",
name: "date",
label: "Date",
required: true,
},
{
type: "string",
name: "slug",
label: "Slug",
},
{
type: "string",
name: "place",
label: "Place",
},
{
type: "string",
name: "thumbnail",
label: "Thumbnail URL",
},
{
type: "string",
name: "youtube",
label: "YouTube ID",
},
{
type: "string",
name: "tags",
label: "Tags (comma separated)",
},
{
type: "boolean",
name: "draft",
label: "Draft",
},
{
type: "rich-text",
name: "body",
label: "Content",
isBody: true,
},
],
},
{
name: "documentaries",
label: "Documentaries",
path: "src/content/documentaries",
format: "md",
fields: [
{
type: "string",
name: "locale",
label: "Language",
options: [
{ label: "Español", value: "es" },
],
},
{
type: "string",
name: "title",
label: "Title",
isTitle: true,
required: true,
},
{
type: "string",
name: "video_yt",
label: "YouTube ID",
},
{
type: "datetime",
name: "date",
label: "Date",
required: true,
},
]
},
],
},
});

1
tina/tina-lock.json Normal file

File diff suppressed because one or more lines are too long