{"id":106,"date":"2025-09-14T03:06:38","date_gmt":"2025-09-14T03:06:38","guid":{"rendered":"http:\/\/madrigal.uea.edu.br\/?page_id=106"},"modified":"2025-12-04T03:41:10","modified_gmt":"2025-12-04T03:41:10","slug":"agenda-de-eventos","status":"publish","type":"page","link":"https:\/\/madrigal.uea.edu.br\/index.php\/agenda-de-eventos\/","title":{"rendered":"Agenda de Eventos<font _mstmutation=\"1\"><\/font>"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"106\" class=\"elementor elementor-106\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d660b1c e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"d660b1c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-df0333d elementor-widget elementor-widget-html\" data-id=\"df0333d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\tios26-calendar\/\r\n  ios26-calendar.php\r\n  includes\/\r\n    class-ios26-events.php\r\n    class-ios26-elementor-register.php\r\n    widget-ios26-calendar.php\r\n  assets\/\r\n    css\/style.css\r\n    js\/calendar.js\r\n\r\n<?php\r\n\/**\r\n * Plugin Name: Calend\u00e1rio iOS 26 - Elementor\r\n * Description: Widget de calend\u00e1rio estilo iOS 26 para Elementor. Registra um post type de eventos, endpoint REST para buscar eventos por data e um widget Elementor personalizado.\r\n * Version: 1.0.0\r\n * Author: Seu Nome\r\n * Text Domain: ios26-calendar\r\n *\/\r\n\r\nif ( ! defined( 'ABSPATH' ) ) exit;\r\n\r\ndefine( 'IOS26_CALENDAR_VERSION', '1.0.0' );\r\ndefine( 'IOS26_CALENDAR_DIR', plugin_dir_path( __FILE__ ) );\r\ndefine( 'IOS26_CALENDAR_URL', plugin_dir_url( __FILE__ ) );\r\n\r\n\/\/ Includes\r\nrequire_once IOS26_CALENDAR_DIR . 'includes\/class-ios26-events.php';\r\nrequire_once IOS26_CALENDAR_DIR . 'includes\/class-ios26-elementor-register.php';\r\n\r\n\/\/ Enqueue and REST registration on init\r\nfunction ios26_calendar_init() {\r\n    add_action( 'wp_enqueue_scripts', 'ios26_enqueue_assets' );\r\n    add_action( 'rest_api_init', 'ios26_register_rest_routes' );\r\n}\r\nadd_action( 'init', 'ios26_calendar_init' );\r\n\r\n\/\/ Enqueue front assets\r\nfunction ios26_enqueue_assets() {\r\n    wp_enqueue_style( 'ios26-calendar-style', IOS26_CALENDAR_URL . 'assets\/css\/style.css', array(), IOS26_CALENDAR_VERSION );\r\n    wp_enqueue_script( 'ios26-calendar-js', IOS26_CALENDAR_URL . 'assets\/js\/calendar.js', array( 'jquery' ), IOS26_CALENDAR_VERSION, true );\r\n    wp_localize_script( 'ios26-calendar-js', 'IOS26_CALENDAR', array(\r\n        'root' => esc_url_raw( rest_url() ),\r\n        'nonce' => wp_create_nonce( 'wp_rest' ),\r\n    ) );\r\n}\r\n\r\n\/\/ REST route to get events by date (YYYY-MM-DD)\r\nfunction ios26_register_rest_routes() {\r\n    register_rest_route( 'ios26\/v1', '\/events', array(\r\n        'methods' => 'GET',\r\n        'callback' => 'ios26_get_events_by_date',\r\n        'permission_callback' => '__return_true',\r\n        'args' => array(\r\n            'date' => array( 'required' => true ),\r\n        ),\r\n    ) );\r\n}\r\n\r\nfunction ios26_get_events_by_date( $request ) {\r\n    $date = sanitize_text_field( $request->get_param( 'date' ) );\r\n\r\n    $args = array(\r\n        'post_type' => 'ios26_event',\r\n        'posts_per_page' => -1,\r\n        'meta_query' => array(\r\n            array(\r\n                'key' => 'ios26_event_date',\r\n                'value' => $date,\r\n                'compare' => '=',\r\n            ),\r\n        ),\r\n    );\r\n\r\n    $q = new WP_Query( $args );\r\n    $events = array();\r\n    while ( $q->have_posts() ) {\r\n        $q->the_post();\r\n        $events[] = array(\r\n            'id' => get_the_ID(),\r\n            'title' => get_the_title(),\r\n            'content' => apply_filters( 'the_content', get_the_content() ),\r\n            'date' => get_post_meta( get_the_ID(), 'ios26_event_date', true ),\r\n            'time' => get_post_meta( get_the_ID(), 'ios26_event_time', true ),\r\n            'location' => get_post_meta( get_the_ID(), 'ios26_event_location', true ),\r\n        );\r\n    }\r\n    wp_reset_postdata();\r\n\r\n    return rest_ensure_response( $events );\r\n}\r\n\r\n\r\n<?php\r\nif ( ! defined( 'ABSPATH' ) ) exit;\r\n\r\nclass IOS26_Calendar_Events {\r\n    public function __construct() {\r\n        add_action( 'init', array( $this, 'register_post_type' ) );\r\n        add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );\r\n        add_action( 'save_post', array( $this, 'save_meta' ) );\r\n    }\r\n\r\n    public function register_post_type() {\r\n        $labels = array(\r\n            'name' => 'Eventos do Calend\u00e1rio',\r\n            'singular_name' => 'Evento do Calend\u00e1rio',\r\n        );\r\n        $args = array(\r\n            'label' => 'Eventos do Calend\u00e1rio',\r\n            'labels' => $labels,\r\n            'public' => true,\r\n            'show_in_menu' => true,\r\n            'supports' => array( 'title', 'editor' ),\r\n            'menu_icon' => 'dashicons-calendar-alt',\r\n        );\r\n        register_post_type( 'ios26_event', $args );\r\n    }\r\n\r\n    public function add_meta_boxes() {\r\n        add_meta_box( 'ios26_event_meta', 'Detalhes do Evento', array( $this, 'render_meta_box' ), 'ios26_event', 'normal', 'high' );\r\n    }\r\n\r\n    public function render_meta_box( $post ) {\r\n        wp_nonce_field( 'ios26_event_save', 'ios26_event_nonce' );\r\n        $date = get_post_meta( $post->ID, 'ios26_event_date', true );\r\n        $time = get_post_meta( $post->ID, 'ios26_event_time', true );\r\n        $location = get_post_meta( $post->ID, 'ios26_event_location', true );\r\n        ?>\r\n        <p>\r\n            <label>Data (YYYY-MM-DD):<\/label><br>\r\n            <input type=\"date\" name=\"ios26_event_date\" value=\"<?php echo esc_attr( $date ); ?>\" \/>\r\n        <\/p>\r\n        <p>\r\n            <label>Hora:<\/label><br>\r\n            <input type=\"time\" name=\"ios26_event_time\" value=\"<?php echo esc_attr( $time ); ?>\" \/>\r\n        <\/p>\r\n        <p>\r\n            <label>Local:<\/label><br>\r\n            <input type=\"text\" name=\"ios26_event_location\" value=\"<?php echo esc_attr( $location ); ?>\" style=\"width:100%\" \/>\r\n        <\/p>\r\n        <?php\r\n    }\r\n\r\n    public function save_meta( $post_id ) {\r\n        if ( ! isset( $_POST['ios26_event_nonce'] ) ) return;\r\n        if ( ! wp_verify_nonce( $_POST['ios26_event_nonce'], 'ios26_event_save' ) ) return;\r\n        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;\r\n\r\n        if ( isset( $_POST['ios26_event_date'] ) ) {\r\n            update_post_meta( $post_id, 'ios26_event_date', sanitize_text_field( $_POST['ios26_event_date'] ) );\r\n        }\r\n        if ( isset( $_POST['ios26_event_time'] ) ) {\r\n            update_post_meta( $post_id, 'ios26_event_time', sanitize_text_field( $_POST['ios26_event_time'] ) );\r\n        }\r\n        if ( isset( $_POST['ios26_event_location'] ) ) {\r\n            update_post_meta( $post_id, 'ios26_event_location', sanitize_text_field( $_POST['ios26_event_location'] ) );\r\n        }\r\n    }\r\n}\r\n\r\nnew IOS26_Calendar_Events();\r\n\r\n<?php\r\nif ( ! defined( 'ABSPATH' ) ) exit;\r\n\r\nclass IOS26_Elementor_Register {\r\n    public function __construct() {\r\n        add_action( 'init', array( $this, 'maybe_register' ) );\r\n    }\r\n\r\n    public function maybe_register() {\r\n        if ( did_action( 'elementor\/loaded' ) ) {\r\n            add_action( 'elementor\/widgets\/register', array( $this, 'register_widget' ) );\r\n        }\r\n    }\r\n\r\n    public function register_widget( $widgets_manager ) {\r\n        require_once IOS26_CALENDAR_DIR . 'includes\/widget-ios26-calendar.php';\r\n        $widgets_manager->register( new \\IOS26_Calendar_Widget() );\r\n    }\r\n}\r\n\r\nnew IOS26_Elementor_Register();\r\n\r\n<?php\r\nif ( ! defined( 'ABSPATH' ) ) exit;\r\n\r\nuse \\Elementor\\Controls_Manager;\r\n\r\nclass IOS26_Calendar_Widget extends \\Elementor\\Widget_Base {\r\n    public function get_name() { return 'ios26_calendar_widget'; }\r\n    public function get_title() { return 'Calend\u00e1rio iOS 26'; }\r\n    public function get_icon() { return 'eicon-calendar'; }\r\n    public function get_categories() { return [ 'general' ]; }\r\n\r\n    protected function register_controls() {\r\n        $this->start_controls_section( 'section_content', [ 'label' => 'Conte\u00fado' ] );\r\n        $this->add_control( 'start_week', [\r\n            'label' => 'Primeiro dia da semana',\r\n            'type' => Controls_Manager::SELECT,\r\n            'default' => '1',\r\n            'options' => [ '0' => 'Domingo', '1' => 'Segunda' ],\r\n        ] );\r\n        $this->end_controls_section();\r\n    }\r\n\r\n    protected function render() {\r\n        ?>\r\n        <div class=\"ios26-calendar-root\">\r\n            <div class=\"calendar-container\">\r\n                <div class=\"calendar-header\">\r\n                    <button class=\"prev-month\">\u2039<\/button>\r\n                    <div class=\"month-year\"><\/div>\r\n                    <button class=\"next-month\">\u203a<\/button>\r\n                <\/div>\r\n                <div class=\"calendar-grid\"><\/div>\r\n            <\/div>\r\n\r\n            <!-- Modal de eventos -->\r\n            <div class=\"ios26-modal\" aria-hidden=\"true\">\r\n                <div class=\"ios26-modal-content\">\r\n                    <button class=\"ios26-modal-close\">\u2715<\/button>\r\n                    <div class=\"ios26-modal-body\"><\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n        <?php\r\n    }\r\n}\r\n\r\n.ios26-calendar-root { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }\r\n.calendar-container{\r\n  max-width:380px;margin:auto;padding:18px;border-radius:18px;background:linear-gradient(180deg, rgba(255,255,255,0.98), rgba(245,245,245,0.9));box-shadow:0 8px 30px rgba(0,0,0,0.08);\r\n}\r\n.calendar-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}\r\n.calendar-header .month-year{font-size:16px;font-weight:600}\r\n.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}\r\n.day-cell{padding:12px;border-radius:10px;text-align:center;cursor:pointer}\r\n.day-cell.inactive{opacity:0.25}\r\n.day-cell.today{box-shadow:0 4px 14px rgba(0,0,0,0.08);border:1px solid rgba(0,0,0,0.04)}\r\n.day-cell.has-event{background:linear-gradient(135deg, rgba(0,122,255,0.08), rgba(0,122,255,0.02))}\r\n\r\n\/* Modal *\/\r\n.ios26-modal{position:fixed;inset:0;display:none;align-items:center;justify-content:center;backdrop-filter:blur(6px);}\r\n.ios26-modal[aria-hidden=\"false\"]{display:flex}\r\n.ios26-modal-content{width:min(640px,96%);background:#fff;border-radius:16px;padding:18px;box-shadow:0 20px 60px rgba(0,0,0,0.12)}\r\n.ios26-modal-close{float:right;border:none;background:transparent;font-size:18px}\r\n\r\n(function($){\r\n    function IOS26Calendar(root){\r\n        this.root = root;\r\n        this.date = new Date();\r\n        this.root.find('.prev-month').on('click', this.prevMonth.bind(this));\r\n        this.root.find('.next-month').on('click', this.nextMonth.bind(this));\r\n        this.root.on('click', '.day-cell', this.onClickDay.bind(this));\r\n        this.root.find('.ios26-modal-close').on('click', this.closeModal.bind(this));\r\n        this.render();\r\n    }\r\n\r\n    IOS26Calendar.prototype.render = function(){\r\n        var grid = this.root.find('.calendar-grid');\r\n        grid.empty();\r\n        var year = this.date.getFullYear();\r\n        var month = this.date.getMonth();\r\n        this.root.find('.month-year').text(this.date.toLocaleString(undefined,{month:'long', year:'numeric'}));\r\n\r\n        var firstDay = new Date(year, month, 1);\r\n        var startDay = firstDay.getDay();\r\n        var daysInMonth = new Date(year, month+1, 0).getDate();\r\n\r\n        for(var i=0;i<startDay;i++){\r\n            var cell = $('<div>').addClass('day-cell inactive').text('');\r\n            grid.append(cell);\r\n        }\r\n        for(var d=1; d<=daysInMonth; d++){\r\n            var cell = $('<div>').addClass('day-cell').attr('data-day', d).text(d);\r\n            var isoDate = year + '-' + String(month+1).padStart(2,'0') + '-' + String(d).padStart(2,'0');\r\n            (function(cell, isoDate){\r\n                $.ajax({\r\n                    url: IOS26_CALENDAR.root + 'ios26\/v1\/events',\r\n                    method: 'GET',\r\n                    data: { date: isoDate },\r\n                    beforeSend: function(xhr){ xhr.setRequestHeader('X-WP-Nonce', IOS26_CALENDAR.nonce); }\r\n                }).done(function(data){\r\n                    if(data && data.length){\r\n                        cell.addClass('has-event');\r\n                        cell.data('events', data);\r\n                    }\r\n                });\r\n            })(cell, isoDate);\r\n\r\n            var today = new Date();\r\n            if(d==today.getDate() && month==today.getMonth() && year==today.getFullYear()){\r\n                cell.addClass('today');\r\n            }\r\n            grid.append(cell);\r\n        }\r\n    }\r\n\r\n    IOS26Calendar.prototype.prevMonth = function(){ this.date.setMonth(this.date.getMonth()-1); this.render(); }\r\n    IOS26Calendar.prototype.nextMonth = function(){ this.date.setMonth(this.date.getMonth()+1); this.render(); }\r\n\r\n    IOS26Calendar.prototype.onClickDay = function(e){\r\n        var cell = $(e.currentTarget);\r\n        var events = cell.data('events') || [];\r\n        var isoDate = this.date.getFullYear() + '-' + String(this.date.getMonth()+1).padStart(2,'0') + '-' + String(cell.data('day')).padStart(2,'0');\r\n        if(events.length===0){\r\n            var self = this;\r\n            $.ajax({\r\n                url: IOS26_CALENDAR.root + 'ios26\/v1\/events',\r\n                method: 'GET',\r\n                data: { date: isoDate },\r\n                beforeSend: function(xhr){ xhr.setRequestHeader('X-WP-Nonce', IOS26_CALENDAR.nonce); }\r\n            }).done(function(data){\r\n                self.showEventsModal(isoDate, data);\r\n            });\r\n        } else {\r\n            this.showEventsModal(isoDate, events);\r\n        }\r\n    }\r\n\r\n    IOS26Calendar.prototype.showEventsModal = function(date, events){\r\n        var modal = this.root.find('.ios26-modal');\r\n        var body = modal.find('.ios26-modal-body');\r\n        body.empty();\r\n        body.append('<h3>Eventos \u2014 ' + date + '<\/h3>');\r\n        if(events.length===0){ body.append('<p>Nenhum evento nesta data.<\/p>'); }\r\n        events.forEach(function(ev){\r\n            var el = $('<div class=\"event-item\">');\r\n            el.append('<h4>'+ ev.title +'<\/h4>');\r\n            if(ev.time) el.append('<p><strong>Hora:<\/strong> '+ ev.time +'<\/p>');\r\n            if(ev.location) el.append('<p><strong>Local:<\/strong> '+ ev.location +'<\/p>');\r\n            el.append('<div>'+ ev.content +'<\/div>');\r\n            body.append(el);\r\n        });\r\n        modal.attr('aria-hidden', 'false');\r\n    }\r\n\r\n    IOS26Calendar.prototype.closeModal = function(){ this.root.find('.ios26-modal').attr('aria-hidden','true'); }\r\n\r\n    $(document).ready(function(){\r\n        $('.ios26-calendar-root').each(function(){ new IOS26Calendar( $(this) ); });\r\n    });\r\n\r\n})(jQuery);\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>ios26-calendar\/ ios26-calendar.php includes\/ class-ios26-events.php class-ios26-elementor-register.php widget-ios26-calendar.php assets\/ css\/style.css js\/calendar.js Data (YYYY-MM-DD):<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-106","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/pages\/106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/comments?post=106"}],"version-history":[{"count":5,"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/pages\/106\/revisions"}],"predecessor-version":[{"id":502,"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/pages\/106\/revisions\/502"}],"wp:attachment":[{"href":"https:\/\/madrigal.uea.edu.br\/index.php\/wp-json\/wp\/v2\/media?parent=106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}