/**
* Retrieves the translation of text.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/
*/
import {__} from '@wordpress/i18n';
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
import {useBlockProps, InspectorControls, RichText} from '@wordpress/block-editor';
import {
PanelBody,
ToggleControl,
QueryControls,
FormTokenField,
RadioControl,
RangeControl,
TextControl,
TextareaControl,
Dashicon
} from '@wordpress/components';
import {useSelect, select} from '@wordpress/data';
import {useEffect, useState} from '@wordpress/element';
import PostSearchControl from '../../bloque-pl-componentes/src/components/PostSearchControl';
/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* Those files can contain any CSS code that gets applied to the editor.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './editor.scss';
/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
*
* @return {Element} Element to render.
*/
export default function Edit({attributes, setAttributes}) {
const dir_images = '../wp-content/themes/ux_prensalibre/client/build/images/iconos';
const [selectedTags, setSelectedTags] = useState([]);
const [searchQuery, setSearchQuery] = useState("");
const [selectedTagIds, setSelectedTagIds] = useState([]);
const [selectedValue, setSelectedValue] = useState('0');
const [idsPost, setIdsPost] = useState([]);
const {
category,
count_category,
array_post,
titulo_modulo,
mostrar_categoria,
mostrar_fecha,
selectTags,
is_plus,
no_filas,
tax_relation_ns,
tag_plus,
unit,
publi_desc,
url_titulo,
exclude_posts,
mostrar_widget,
type_form,
class_style_block,
notas_mood,
post_id,
post_array_manual,
btn_disabled
} = attributes;
const [taxRelationNS, setTaxRelationNS] = useState(tax_relation_ns);
const [typeForm, settypeForm] = useState(type_form);
const [moodPost, setMoodPost] = useState(notas_mood);
const [arrNotas, setArrNotas] = useState(post_array_manual);
const catIDs = category && category.length > 0 ? category.map((cat) => cat.id) : [];
// CATEGORÍAS
const categoriesPost = useSelect(
(select) => {
const {getEntityRecords} = select('core');
return getEntityRecords('taxonomy', 'category', {
per_page: -1
});
}, []
);
useEffect(() => {
if (categoriesPost) {
}
}, [categoriesPost]);
// MANTIENE LAS CATEGORÍAS SELECCIONADAS EN QUERYCONTROLS
const onChangeCategory = (values) => {
const hasNoSuggestions = values.some(
(value) => typeof value === 'string' && !catSuggestions[value]
);
if (hasNoSuggestions) return;
const updatedCats = values.map((token) => {
return typeof token === 'string' ? catSuggestions[token] : token;
});
setAttributes({category: updatedCats});
};
// FILTRA LAS CATEGORÍAS QUE TIENEN POST
const categoriesWithPosts = categoriesPost ? categoriesPost.filter((categoryItem) => {
const hasPosts = categoryItem && categoryItem.count > 0;
return hasPosts;
}) : [];
const catSuggestions = {};
if (categoriesWithPosts) {
for (let i = 0; i < categoriesWithPosts.length; i++) {
const cat = categoriesWithPosts[i];
catSuggestions[cat.id + ' - ' + cat.name] = cat;
}
}
const perPageValue = count_category * no_filas;
// Define el slug de la etiqueta que estás buscando
const tagSlug = 'suscriptores';
// Realiza la consulta para obtener la etiqueta con el slug especificado
const tagQuery = useSelect(
(select) => {
const tags = select('core').getEntityRecords('taxonomy', 'post_tag', {
per_page: 1,
slug: tagSlug,
});
return tags ? tags[0]?.id : null;
},
[tagSlug]
);
useEffect(() => {
if (tagQuery) {
setAttributes({tag_plus: tagQuery});
}
}, [tagQuery]);
const posts = useSelect(
(select) => {
const {getEntityRecords} = select("core");
if (notas_mood === "1" && post_id) {
// Modalidad Manual: Cargar solo el post guardado en `post_id`
return getEntityRecords("postType", "post", {
status: "publish",
per_page: 1,
orderby: "date",
order: "desc",
_embed: true,
include: [post_id], // Asegura que se envía como array
});
}
if (notas_mood === "0") {
// Modalidad Automática: Cargar lista de posts
const result = getEntityRecords("postType", "post", {
status: "publish",
_embed: true,
per_page: perPageValue,
order_by: "date",
categories: catIDs,
tags: selectTags,
tax_query: [
{
relation: taxRelationNS,
taxonomy: "category",
field: "term_id",
terms: catIDs,
},
],
});
let resultPlus = [];
if (is_plus === 1) {
resultPlus = getEntityRecords("postType", "pl_plus", {
status: "publish",
_embed: true,
per_page: perPageValue,
order_by: "date",
categories: catIDs,
tags: selectTags,
tax_query: [
{
relation: taxRelationNS,
taxonomy: "category",
field: "term_id",
terms: catIDs,
},
],
});
}
// Combina y ordena los resultados
const combinedResults = [...(result || []), ...(resultPlus || [])];
return combinedResults.sort((a, b) => new Date(b.date) - new Date(a.date));
}
return [];
},
[notas_mood, catIDs, selectTags, perPageValue, is_plus, tag_plus, taxRelationNS, post_id]
);
useEffect(() => {
if (notas_mood === "1") {
if (posts && Array.isArray(posts) && posts.length > 0) {
// Filtrar posts duplicados antes de procesarlos
const uniquePosts = posts.filter(
newPost => !post_array_manual.some(existingPost => existingPost.id === newPost.id)
);
// Procesar y eliminar propiedades no deseadas
const updatedPosts = uniquePosts.map((post) => {
delete post.content;
delete post.class_list;
delete post.comment_status;
delete post.format;
delete post.generated_slug;
delete post.jetpack_featured_media_url;
delete post.password;
delete post.permalink_template;
delete post.ping_status;
delete post.slug;
delete post.status;
delete post._links;
delete post.guid;
// Devolver el objeto actualizado
return post;
});
setArrNotas((prevNotas) => [...prevNotas, ...updatedPosts]);
setAttributes({
post_array_manual: [...post_array_manual, ...updatedPosts],
});
// Actualizar los IDs de los posts
const postIds = [...new Set([...post_array_manual.map(post => post.id), ...updatedPosts.map(post => post.id)])];
setIdsPost(postIds);
}
} else if (notas_mood === "0") {
// Eliminar la propiedad 'content' de cada post
const updatedPosts = posts.map((post) => {
// Eliminar múltiples propiedades
delete post.content;
delete post.class_list;
delete post.comment_status;
delete post.format;
delete post.generated_slug;
delete post.jetpack_featured_media_url;
delete post.password;
delete post.permalink_template;
delete post.ping_status;
delete post.slug;
delete post.status;
delete post._links;
delete post.guid;
// Devolver el objeto actualizado
return post;
});
setAttributes({array_post: updatedPosts});
const postIds = updatedPosts.map(post => post.id);
setIdsPost(postIds);
}
}, [posts, notas_mood]);
console.log(post_array_manual, 'post_array_manual');
console.log(array_post, 'array_post');
useEffect(() => {
if (notas_mood === "1") {
setAttributes({array_post: []});
} else if (notas_mood === "0") {
setAttributes({post_array_manual: []});
}
}, [notas_mood]);
// CONVERTIR FECHA
const formatDateToText = (isoDate) => {
const options = {year: 'numeric', month: 'long', day: 'numeric'};
const date = new Date(isoDate);
return date.toLocaleDateString('es-ES', options);
};
const queryNotesByTags = useSelect(
(select) => {
return select("core").getEntityRecords("postType", "post", {
per_page: 30,
orderby: "date",
order: "desc",
tags: selectedTagIds, // Filter by specified post tag IDs
});
},
[selectedTagIds]
);
// Get the tags that match the search
const filteredTags = useSelect(
(select) => {
const perPage = 100; // Number of tags to load per page
// Get tags that match the search and have a valid 'name'
const matchingTags = select("core").getEntityRecords(
"taxonomy",
"post_tag",
{
per_page: perPage,
search: searchQuery,
_embed: true,
}
);
return matchingTags || [];
},
[searchQuery]
);
const handleTagChange = (newValue) => {
setSelectedTags(newValue);
// Gets the IDs of the selected tags and stores them in selectedTagIds
const newTagIds = newValue.map((selectedTagName) => {
const selectedTag = filteredTags.find((tag) => tag.name === selectedTagName);
return selectedTag ? selectedTag.id : null;
});
// Update the attribute only if there are changes
if (!arraysEqual(selectedTagIds, newTagIds)) {
setAttributes({selectTags: newTagIds});
}
setSelectedTagIds(newTagIds);
};
// Function to check if two arrays are equal
const arraysEqual = (a, b) => {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
};
useEffect(() => {
if (queryNotesByTags) {
}
}, [queryNotesByTags]);
const handleChange = (newValue) => {
setSelectedValue(newValue);
};
const handleChangeRelation = (newValue) => {
setTaxRelationNS(newValue);
setAttributes({tax_relation_ns: newValue});
};
const handleChangeForm = (newValue) => {
settypeForm(newValue);
setAttributes({type_form: newValue});
};
useEffect(() => {
if (typeForm === '0') {
setAttributes({class_style_block: 'col-12'});
} else if ((typeForm === '1') || (typeForm === '2')) {
setAttributes({class_style_block: 'col-lg-8 col-xl-9 pe-md-2'});
}
}, [typeForm]);
const changeMood = (newValue) => {
setMoodPost(newValue);
setAttributes({notas_mood: newValue});
};
const handleRemove = (noteId) => {
const updatedManualPosts = post_array_manual.filter((post) => post.id !== noteId);
setAttributes({post_array_manual: updatedManualPosts});
};
return (
setAttributes({publi_desc: value})}
/>
setAttributes({unit: value})}
/>
setAttributes({url_titulo: value})}
/>
setAttributes({btn_disabled: attributes.btn_disabled === 1 ? 0 : 1})}
/>
{moodPost === '0' && (
<>
setAttributes({is_plus: attributes.is_plus === 1 ? 0 : 1})}
/>
setAttributes({exclude_posts: attributes.exclude_posts === 1 ? 0 : 1})}
/>
setAttributes({no_filas: value})}
min={1}
max={10}
step={1}
/>
tag.name)}
onChange={handleTagChange}
onInputChange={(newSearchQuery) => setSearchQuery(newSearchQuery)}
/>
>
)}
{moodPost === '1' && (
{
setAttributes({post_id: value});
}}
numOfInitialResults={20}
filterResults={(results) => results}
/>
)}
{/* Mostrar o no la categoría */}
setAttributes({mostrar_categoria: attributes.mostrar_categoria === 1 ? 0 : 1})}
/>
{/* Mostrar o no la fecha */}
setAttributes({mostrar_fecha: attributes.mostrar_fecha === 1 ? 0 : 1})}
/>
{/* Mostrar o no el widget */}
setAttributes({mostrar_widget: attributes.mostrar_widget === 1 ? 0 : 1})}
/>
setAttributes({titulo_modulo: value})}
/>
{moodPost === '0' && array_post && array_post.map((post) => {
const hasSuscriptoresTag = post.tags && post.tags.includes(tagQuery)
if (hasSuscriptoresTag === true || post.type === "pl_plus") {
return (
{post._embedded['wp:featuredmedia'] ? (
) : (
)}
{attributes.mostrar_fecha === 1 && (
{formatDateToText(post.date)}
)}
Suscriptores
{post.title.raw}
);
} else {
return (
{
post._embedded['wp:featuredmedia'] ? (
) : (
)
}
{attributes.mostrar_fecha === 1 && (
{formatDateToText(post.date)}
)}
{post._embedded['wp:term'] ? attributes.mostrar_categoria === 1 && attributes.mostrar_fecha === 0 && (
{post._embedded['wp:term'][0][0].name}
) : (
SIN
CATEGORÍA
)}
{post._embedded['wp:term'] ? attributes.mostrar_categoria === 1 && attributes.mostrar_fecha === 1 && (
{post._embedded['wp:term'][0][0].name}
) : (
SIN
CATEGORÍA
)}
{post.title.raw}
);
}
})}
{post_array_manual && moodPost === '1' && post_array_manual.map((post) => {
const hasSuscriptoresTag = post.tags && post.tags.includes(tagQuery)
if (hasSuscriptoresTag === true || post.type === "pl_plus") {
return (
{post._embedded['wp:featuredmedia'] ? (
) : (
)}
{attributes.mostrar_fecha === 1 && (
{formatDateToText(post.date)}
)}
Suscriptores
{post.title.raw}
);
} else {
return (
{
post._embedded['wp:featuredmedia'] ? (
) : (
)
}
{attributes.mostrar_fecha === 1 && (
{formatDateToText(post.date)}
)}
{post._embedded['wp:term'] ? attributes.mostrar_categoria === 1 && attributes.mostrar_fecha === 0 && (
{post._embedded['wp:term'][0][0].name}
) : (
SIN
CATEGORÍA
)}
{post._embedded['wp:term'] ? attributes.mostrar_categoria === 1 && attributes.mostrar_fecha === 1 && (
{post._embedded['wp:term'][0][0].name}
) : (
SIN
CATEGORÍA
)}
{post.title.raw}
);
}
})}
{typeForm === '1' && (
)}
{(typeForm === '1' || typeForm === '2') && (
LO MÁS LEÍDO
1
¿Por qué se pide visa a los
dominicanos?
2
Pedro Castillo pide a la
CIDH su libertad y restitución como presidente de Perú
3
8.500 becas para aprender
inglés
4
La Selección Nacional
asciende a la Liga A y clasifica a la Copa Oro
5
La Selección Nacional
asciende a la Liga A y clasifica a la Copa Oro
)}
{typeForm === '1' && (
)}
{typeForm === '1' && (
)}
{(typeForm === '1' || typeForm === '2') && (
LO MÁS LEÍDO
1
¿Por qué se pide visa a los
dominicanos?
2
Pedro Castillo pide a la
CIDH su libertad y restitución como presidente de Perú
3
8.500 becas para aprender
inglés
4
La Selección Nacional
asciende a la Liga A y clasifica a la Copa Oro
5
La Selección Nacional
asciende a la Liga A y clasifica a la Copa Oro
)}
);
}
Real Madrid dice presente en los cuartos de final en una dramática definición ante el Atlético
INICIO
Deportes
Fútbol Internacional
Fútbol Internacional
Real Madrid dice presente en los cuartos de final en una dramática definición ante el Atlético El Real Madrid dijo presente en los cuartos de final de la Champions League, después de vencer en la tanda de los penaltis al Atlético (4-2).
Los jugadores del Real Madrid celebran su pase a cuartos tras derrotar en la tanda de penaltis al Atlético de Madrid. (Foto Prensa Libre: EFE).
La serie de octavos de final entre el Atlético y el Real Madrid fue cerrada y dramática. Este miércoles en el estadio Metropolitano del equipo de Diego Simeone ganó 1-0 en los 90 minutos, pero con el triunfo (2-1) del Real en la ida la serie estaba 2-2.
El gol del Atlético llegó apenas al comenzar el partido, al minuto 1, con un remate a bocajarro del inglés Conor Gallagher, al que no llegó Courtois y para poner la igualada en la eliminatoria.
El Real Madrid se perdió una gran oportunidad de empatar el juego con un penalti cometido sobre Kylian Mbappé, al 65, y fallado por el brasileño Vinícius (68), que envió fuera.
En la tanda decisiva, el colegiado anuló el penal que había marcado el delantero argentino Julián Álvarez por resbalar y tocar dos veces el balón, mientras que Marcos Llorente mandó el balón al larguero.
El Real Madrid se medirá en los cuartos de final al Arsenal en una serie de ida y vuelta que dará inicio el 8 de abril próximo.
Con el Real Madrid clasificado, las series de cuartos de final de la Champions League quedaron de la siguiente manera.
Serie cuartos de final de la Champions
Los encuentros Arsenal-Real Madrid, en el Emirates, y Bayern Múnich-Inter Milán abrirán el martes 8 de abril los cuartos de final de la Liga de Campeones, según anunció esta noche la UEFA tras completarse los octavos.
Al día siguiente, se jugarán los partidos París Saint Germain-Aston Villa, en el Parque de los Príncipes, y Barcelona-Borussia Dortmund, en el Olímpico de Montjuic.
La vuelta, que tendrá el mismo horario en los cuatro encuentros, comenzará el martes 15 con los encuentros Aston Villa-PSG, en Villa Park, y Borussia Dortmund-Barcelona, en el Signal Iduna Park.
Los cuartos acabarán el miércoles 16 con los partidos Real Madrid-Aston Villa en el Santiago Bernabéu e Inter-Bayern Múnich en el Giuseppe Meazza
Real Madrid – Arsenal
Aston Villa – PSG
Dortmund – Barcelona
Inter – Bayern Múnich
Los jugadores del Atlético lamentan la eliminación frente al Real Madrid en la ronda de octavos de final de la Champions. (Foto Prensa Libre: AFP).
ESCRITO POR:
Fernando López R.
Periodista de Prensa Libre, especializado en deportes con más de 20 años de experiencia como reportero y editor. Reconocido por coberturas como los Juegos Olímpicos de Atenas 2004, Pekín 2008 y Londres 2012.