Calendario y eventos de Discourse

No aparecen errores en la consola. Sin embargo, he grabado un video de referencia.
Esto ocurre en Chrome, Firefox y Safari. En Safari móvil no sucede.

1 me gusta

¡Tu enlace al video está roto!

Perdona, no lo había entendido bien. En efecto, tienes razón: al hacer clic en una fecha del calendario, se abre el modal de creación de evento, pero con el botón «¿Quieres abandonar?». Sí, en efecto, hay un pequeño error :sweat_smile:

2 Me gusta

Para su información, de mi parte he añadido un botón de +info para mis usuarios que no piensan hacer clic en el título para acceder al tema. He retomado la idea de @nathank sobre su botón «Añadir al calendario».

Coloque el script en un componente de tema, en la sección general /head

<script>
(() => {
    const eventInfoSelector = ".event-header .event-info";
    const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";
    // CSS inyectado limpio y adaptado a los temas de Discourse (Claro/Oscuro)
    const style = document.createElement("style");
    style.innerHTML = `
    .custom-topic-info-btn {
        display: flex !important;
        align-items: center;
        justify-content: center;
        width: 40%; /* Ocupa todo el ancho para un aspecto limpio bajo el título */
        box-sizing: border-box;
        margin: 12px 0 6px 0;
        padding: 10px 16px;
        
        /* Uso de variables nativas de Discourse */
        background-color: var(--tertiary) !important; /* Color de acento (ej. azul) */
        color: var(--secondary) !important;          /* Color de texto con contraste */
        
        border-radius: 8px;
        font-weight: 700;
        text-decoration: none !important;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
        transition: background-color 0.2s ease, transform 0.1s ease;
    }
    /* Efecto al pasar el cursor */
    .custom-topic-info-btn:hover {
        background-color: var(--tertiary-hover) !important;
        color: var(--secondary) !important;
        transform: translateY(-1px);
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
    }
    /* Efecto al hacer clic */
    .custom-topic-info-btn:active {
        transform: translateY(0);
    }
    /* Estilo del icono SVG */
    .custom-topic-info-btn .btn-icon-svg {
        margin-right: 8px;
        width: 16px;
        height: 16px;
        fill: currentColor;
    }
    `;
    document.head.appendChild(style);
    const findTopicLink = (container) => {
        if (!container) return null;
        const links = [...container.querySelectorAll('a[href*="/t/"]')];
        if (links.length) return links[0].href;
        return null;
    };
    const createTopicInfoButton = () => {
        const eventInfo = document.querySelector(eventInfoSelector);
        if (!eventInfo || eventInfo.querySelector(".custom-topic-info-btn")) return;
        const card = eventInfo.closest(eventCardSelector) || document;
        const topicUrl = findTopicLink(card);
        if (!topicUrl) return;
        const button = document.createElement("a");
        button.className = "btn custom-topic-info-btn";
        button.title = "Ver el tema completo";
        button.href = topicUrl;
        
        // Añadir un icono de información SVG armonizado
        button.innerHTML = `
            <svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V240h-24c-13.3 0-24-10.7-24-24s10.7-24 24-24h40c13.3 0 24 10.7 24 24v120h24c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144a32 32 0 1 1 0-64 32 32 0 1 1 0 64z"/>
            </svg>
            <span class="d-button-label">Más info</span>
        `;
        if (eventInfo.firstElementChild) {
            eventInfo.insertBefore(button, eventInfo.firstElementChild.nextSibling);
        } else {
            eventInfo.appendChild(button);
        }
    };
    const observer = new MutationObserver(() => createTopicInfoButton());
    observer.observe(document.body, { childList: true, subtree: true });
    createTopicInfoButton();
})();
</script>

Aquí tiene una vista previa

o bien

este código

<script>
(() => {
    const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";

    // CSS inyectado para un aspecto limpio y moderno
    const style = document.createElement("style");
    style.innerHTML = `
    .custom-topic-info-wrapper {
        margin-top: 16px;
        padding-top: 16px;
        border-top: 1px solid var(--primary-low); /* Línea de separación sutil */
        width: 100%;
        display: flex;
        justify-content: center;
    }

    .custom-topic-info-btn {
        display: flex !important;
        align-items: center;
        justify-content: center;
        width: 100%;
        box-sizing: border-box;
        padding: 8px 16px;
        
        /* Estilo Outline elegante */
        background-color: transparent !important;
        color: var(--tertiary) !important;
        border: 1px solid var(--tertiary) !important;
        
        border-radius: 6px;
        font-weight: 600;
        text-decoration: none !important;
        transition: all 0.2s ease;
        cursor: pointer;
    }

    /* Efecto al pasar el cursor: el botón se rellena */
    .custom-topic-info-btn:hover {
        background-color: var(--tertiary) !important;
        color: var(--secondary) !important;
        border-color: var(--tertiary) !important;
    }

    /* Alineación del icono de información */
    .custom-topic-info-btn .btn-icon-svg {
        margin-right: 8px;
        width: 16px;
        height: 16px;
        fill: currentColor;
    }
    `;
    document.head.appendChild(style);

    const findTopicLink = (container) => {
        if (!container) return null;
        const links = [...container.querySelectorAll('a[href*="/t/"]')];
        if (links.length) return links[0].href;
        return null;
    };

    const createTopicInfoButton = () => {
        const cards = document.querySelectorAll(eventCardSelector);
        
        cards.forEach(card => {
            if (card.querySelector(".custom-topic-info-btn")) return;

            const topicUrl = findTopicLink(card);
            if (!topicUrl) return;

            const wrapper = document.createElement("div");
            wrapper.className = "custom-topic-info-wrapper";

            const button = document.createElement("a");
            button.className = "btn custom-topic-info-btn";
            button.title = "Consultar el tema completo";
            button.href = topicUrl;
            
            // Icono "i" de información + Nuevo texto accionable
            button.innerHTML = `
                <svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                    <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V240h-24c-13.3 0-24-10.7-24-24s10.7-24 24-24h40c13.3 0 24 10.7 24 24v120h24c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144a32 32 0 1 1 0-64 32 32 0 1 1 0 64z"/>
                </svg>
                <span class="d-button-label">Consultar el tema</span>
            `;

            wrapper.appendChild(button);

            /* Posicionamiento encima de las opciones de respuesta (Participará, etc.) */
            const actionsContainer = card.querySelector(".status-and-options, .event-actions");
            const infoContainer = card.querySelector(".event-info");
            
            if (actionsContainer && actionsContainer.parentNode) {
                actionsContainer.parentNode.insertBefore(wrapper, actionsContainer);
            } else if (infoContainer) {
                infoContainer.appendChild(wrapper);
            } else {
                card.appendChild(wrapper);
            }
        });
    };

    const observer = new MutationObserver(() => createTopicInfoButton());
    observer.observe(document.body, { childList: true, subtree: true });

    createTopicInfoButton();
})();
</script>

Vista previa del resultado

Tiene la opción de elegir :rofl:

3 Me gusta

¡Realmente han mejorado la facilidad para crear un evento desde las últimas actualizaciones :+1:

Pero quería saber si existe una configuración que impida crear un evento cuando un usuario hace clic en el calendario. A veces, en lugar de hacer clic en el evento, hace clic al lado, lo que abre un modal para crear un evento :sweat_smile:

Gracias

2 Me gusta

Sé que soy pesado, pero tengo otra pregunta o sugerencia sobre los eventos expirados. Podrían eliminarse automáticamente, ya que ya no tienen interés en estar presentes; me parece que el plugin de eventos lo hacía automáticamente.

Actualmente, lo hago manualmente, así que si hay alguna forma de ahorrar tiempo :sweat_smile:

Gracias al equipo.

1 me gusta

¿Existe alguna forma de que la ubicación en el evento realice una búsqueda, como se hace en Google Calendar o en los eventos de Facebook, a) para ayudar al usuario a seleccionar la ubicación y b) para que la ubicación sea clicable y abra una aplicación de mapas?

(No pude encontrar ninguna solución buscando, pero quizás mis consultas de búsqueda no fueron adecuadas)

1 me gusta

El Locations Plugin 🌍 sí tiene ese tipo de funcionalidad, pero solo se integra con la alternativa Events Plugin 📅.

El desarrollador (@merefield) podría estar dispuesto a integrarlo con el plugin oficial, pero imagino que sería bastante trabajo establecerlo y mantenerlo, por lo que definitivamente necesitarías patrocinar el trabajo para que esto ocurra.

1 me gusta

He estado intentando revisar ese plugin de eventos, pero me he quedado atascado en

ya que el sitio lleva meses fuera de línea.

Podría valer la pena presentar una solicitud formal de función en Contribute > Feature (etiquetada como calendar-and-events) para su consideración. Puedo imaginar que sería algo viable y que tiene el potencial de ser de gran valor para muchos.


más tarde…
@lou efectivamente lo ha hecho aquí:

1 me gusta

Se ha fusionado una publicación en un tema existente: Soporte para mapa de ubicación de eventos