{"id":2604,"date":"2026-06-16T13:13:59","date_gmt":"2026-06-16T13:13:59","guid":{"rendered":"https:\/\/app.digitalfreelancer.org\/?page_id=2604"},"modified":"2026-06-22T18:17:57","modified_gmt":"2026-06-22T18:17:57","slug":"dashboard-convites","status":"publish","type":"page","link":"https:\/\/app.digitalfreelancer.org\/index.php\/dashboard-convites\/","title":{"rendered":"Dashboard Convites+"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2604\" class=\"elementor elementor-2604\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3e3a856 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent\" data-id=\"3e3a856\" 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-5d58e94 elementor-widget elementor-widget-shortcode\" data-id=\"5d58e94\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">        <div id=\"cvp-1-z57ldW\" class=\"cvp-root\">\n                <style>\n        #cvp-1-z57ldW {\n            --cvp-bg: #0a0a0b;\n--cvp-panel: #121316;\n--cvp-panel-2: #1a1c20;\n--cvp-border: #2b2d33;\n--cvp-text: #e8e8e8;\n--cvp-muted: #9a9aa3;\n--cvp-accent: #c0c0c0;\n--cvp-accent-soft: rgba(192,192,192,0.12);\n--cvp-danger: #d3604a;\n            all: initial;\n            * { box-sizing: border-box; }\n            font-family: 'Georgia', 'Iowan Old Style', serif;\n            color: var(--cvp-text);\n            background: var(--cvp-bg);\n            display: block;\n            border-radius: var(--cvp-radius);\n            overflow: hidden;\n            border: 1px solid var(--cvp-border);\n        }\n        #cvp-1-z57ldW button, #cvp-1-z57ldW input,\n        #cvp-1-z57ldW select, #cvp-1-z57ldW textarea {\n            font-family: 'Helvetica Neue', Arial, sans-serif;\n            font-size: 14px;\n            color: var(--cvp-text);\n        }\n        #cvp-1-z57ldW .cvp-app { display: flex; min-height: 720px; max-height: 86vh; }\n\n        \/* Sidebar *\/\n        #cvp-1-z57ldW .cvp-side {\n            width: 220px; flex-shrink: 0; background: var(--cvp-panel);\n            border-right: 1px solid var(--cvp-border); padding: 22px 16px; overflow-y: auto;\n        }\n        #cvp-1-z57ldW .cvp-brand {\n            font-family: 'Helvetica Neue', Arial, sans-serif; letter-spacing: .12em;\n            font-size: 13px; text-transform: uppercase; color: var(--cvp-gold);\n            margin-bottom: 26px; font-weight: 600;\n        }\n        #cvp-1-z57ldW .cvp-nav { list-style: none; margin: 0; padding: 0; font-family: 'Helvetica Neue', Arial, sans-serif; }\n        #cvp-1-z57ldW .cvp-nav li {\n            padding: 11px 12px; border-radius: 8px; margin-bottom: 4px; cursor: pointer;\n            font-size: 13.5px; color: var(--cvp-muted); transition: .15s;\n        }\n        #cvp-1-z57ldW .cvp-nav li:hover { color: var(--cvp-text); background: var(--cvp-panel-2); }\n        #cvp-1-z57ldW .cvp-nav li.active { background: var(--cvp-gold-soft); color: var(--cvp-gold); font-weight: 600; }\n\n        \/* Main *\/\n        #cvp-1-z57ldW .cvp-main { flex: 1; overflow-y: auto; padding: 28px 32px; background: var(--cvp-bg); }\n        #cvp-1-z57ldW .cvp-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; }\n        #cvp-1-z57ldW .cvp-title { font-size: 26px; font-weight: 400; }\n        #cvp-1-z57ldW .cvp-sub { font-family: 'Helvetica Neue', Arial, sans-serif; color: var(--cvp-muted); font-size: 13px; margin-top: 4px; }\n\n        #cvp-1-z57ldW .cvp-btn {\n            font-family: 'Helvetica Neue', Arial, sans-serif; background: var(--cvp-gold); color: #1a1304;\n            border: none; padding: 10px 18px; border-radius: 9px; cursor: pointer; font-weight: 600;\n            font-size: 13.5px; transition: .15s;\n        }\n        #cvp-1-z57ldW .cvp-btn:hover { filter: brightness(1.08); }\n        #cvp-1-z57ldW .cvp-btn.outline { background: transparent; border: 1px solid var(--cvp-border); color: var(--cvp-text); }\n        #cvp-1-z57ldW .cvp-btn.danger { background: var(--cvp-danger); color: #fff; }\n        #cvp-1-z57ldW .cvp-btn.small { padding: 6px 12px; font-size: 12px; border-radius: 7px; }\n\n        \/* Stat cards *\/\n        #cvp-1-z57ldW .cvp-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px,1fr)); gap: 14px; margin-bottom: 26px; }\n        #cvp-1-z57ldW .cvp-stat {\n            background: var(--cvp-panel); border: 1px solid var(--cvp-border); border-radius: var(--cvp-radius);\n            padding: 18px; font-family: 'Helvetica Neue', Arial, sans-serif;\n        }\n        #cvp-1-z57ldW .cvp-stat .num { font-family: Georgia, serif; font-size: 30px; color: var(--cvp-gold); }\n        #cvp-1-z57ldW .cvp-stat .lbl { color: var(--cvp-muted); font-size: 12.5px; margin-top: 2px; }\n\n        \/* Cards \/ list *\/\n        #cvp-1-z57ldW .cvp-card {\n            background: var(--cvp-panel); border: 1px solid var(--cvp-border); border-radius: var(--cvp-radius);\n            padding: 18px; margin-bottom: 16px;\n        }\n        #cvp-1-z57ldW .cvp-card h3 { font-size: 16px; font-weight: 400; margin: 0 0 12px; }\n\n        #cvp-1-z57ldW .cvp-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }\n        #cvp-1-z57ldW .cvp-chip {\n            font-family: 'Helvetica Neue', Arial, sans-serif; border: 1px solid var(--cvp-border); background: var(--cvp-panel-2);\n            color: var(--cvp-muted); padding: 7px 14px; border-radius: 999px; cursor: pointer; font-size: 12.5px;\n        }\n        #cvp-1-z57ldW .cvp-chip.active { background: var(--cvp-gold-soft); border-color: var(--cvp-gold); color: var(--cvp-gold); }\n\n        #cvp-1-z57ldW .cvp-invite-row {\n            display: flex; align-items: center; gap: 14px; border: 1px solid var(--cvp-border);\n            border-radius: 12px; padding: 13px 16px; margin-bottom: 10px; background: var(--cvp-panel-2);\n        }\n        #cvp-1-z57ldW .cvp-invite-thumb {\n            width: 42px; height: 42px; border-radius: 9px; background: var(--cvp-gold-soft); color: var(--cvp-gold);\n            display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0;\n        }\n        #cvp-1-z57ldW .cvp-invite-info { flex: 1; min-width: 0; font-family: 'Helvetica Neue', Arial, sans-serif; }\n        #cvp-1-z57ldW .cvp-invite-info .nm { font-size: 14.5px; font-weight: 600; }\n        #cvp-1-z57ldW .cvp-invite-info .mt { color: var(--cvp-muted); font-size: 12px; margin-top: 2px; }\n        #cvp-1-z57ldW .cvp-status {\n            font-family: 'Helvetica Neue', Arial, sans-serif; font-size: 11px; padding: 4px 10px; border-radius: 999px;\n            text-transform: uppercase; letter-spacing: .04em;\n        }\n        #cvp-1-z57ldW .cvp-status.rascunho { background: rgba(141,138,130,0.18); color: var(--cvp-muted); }\n        #cvp-1-z57ldW .cvp-status.enviado { background: rgba(96,148,211,0.18); color: #7fa8e0; }\n        #cvp-1-z57ldW .cvp-status.concluido { background: rgba(96,180,120,0.18); color: #7fc89a; }\n\n        #cvp-1-z57ldW .cvp-empty {\n            text-align: center; padding: 50px 20px; color: var(--cvp-muted); font-family: 'Helvetica Neue', Arial, sans-serif; font-size: 13.5px;\n        }\n\n        \/* Modal *\/\n        #cvp-1-z57ldW .cvp-overlay {\n            position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: none; align-items: center; justify-content: center; z-index: 999999; padding: 20px;\n        }\n        #cvp-1-z57ldW .cvp-overlay.open { display: flex; }\n        #cvp-1-z57ldW .cvp-modal {\n            background: var(--cvp-panel); border: 1px solid var(--cvp-border); border-radius: var(--cvp-radius);\n            width: 100%; max-width: 480px; padding: 26px; max-height: 86vh; overflow-y: auto;\n        }\n        #cvp-1-z57ldW .cvp-modal h2 { font-size: 19px; font-weight: 400; margin: 0 0 18px; }\n        #cvp-1-z57ldW .cvp-field { margin-bottom: 14px; font-family: 'Helvetica Neue', Arial, sans-serif; }\n        #cvp-1-z57ldW .cvp-field label { display: block; font-size: 12px; color: var(--cvp-muted); margin-bottom: 5px; }\n        #cvp-1-z57ldW .cvp-field input, #cvp-1-z57ldW .cvp-field select, #cvp-1-z57ldW .cvp-field textarea {\n            width: 100%; background: var(--cvp-panel-2); border: 1px solid var(--cvp-border); border-radius: 8px; padding: 9px 11px;\n        }\n        #cvp-1-z57ldW .cvp-field textarea { min-height: 70px; resize: vertical; }\n        #cvp-1-z57ldW .cvp-modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }\n\n        \/* Calendar *\/\n        #cvp-1-z57ldW .cvp-cal-grid { display: grid; grid-template-columns: repeat(7,1fr); gap: 6px; font-family: 'Helvetica Neue', Arial, sans-serif; }\n        #cvp-1-z57ldW .cvp-cal-day-name { text-align: center; font-size: 11px; color: var(--cvp-muted); padding-bottom: 6px; text-transform: uppercase; }\n        #cvp-1-z57ldW .cvp-cal-cell {\n            min-height: 74px; border: 1px solid var(--cvp-border); border-radius: 8px; padding: 6px; font-size: 11.5px; background: var(--cvp-panel-2);\n        }\n        #cvp-1-z57ldW .cvp-cal-cell.empty { background: transparent; border-color: transparent; }\n        #cvp-1-z57ldW .cvp-cal-cell .d { color: var(--cvp-muted); margin-bottom: 4px; }\n        #cvp-1-z57ldW .cvp-cal-tag { background: var(--cvp-gold-soft); color: var(--cvp-gold); border-radius: 5px; padding: 2px 5px; margin-top: 2px; font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n        #cvp-1-z57ldW .cvp-cal-nav { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; font-family: 'Helvetica Neue', Arial, sans-serif; }\n\n        \/* Portfolio *\/\n        #cvp-1-z57ldW .cvp-grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px,1fr)); gap: 14px; }\n        #cvp-1-z57ldW .cvp-mini-card {\n            background: var(--cvp-panel-2); border: 1px solid var(--cvp-border); border-radius: 10px; padding: 14px;\n            text-align: center; font-family: 'Helvetica Neue', Arial, sans-serif;\n        }\n        #cvp-1-z57ldW .cvp-mini-card .ic { font-size: 22px; color: var(--cvp-gold); margin-bottom: 8px; }\n        #cvp-1-z57ldW .cvp-mini-card .nm { font-size: 12.5px; }\n\n        @media (max-width: 760px) {\n            #cvp-1-z57ldW .cvp-app { flex-direction: column; max-height: none; }\n            #cvp-1-z57ldW .cvp-side { width: 100%; display: flex; gap: 6px; overflow-x: auto; padding: 14px; }\n            #cvp-1-z57ldW .cvp-nav { display: flex; gap: 6px; }\n            #cvp-1-z57ldW .cvp-brand { display: none; }\n        }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/* =========================\n   \u2728 ANIMA\u00c7\u00d5ES BASE\n========================= *\/\n\n#cvp-1-z57ldW .cvp-btn,\n#cvp-1-z57ldW .cvp-card,\n#cvp-1-z57ldW .cvp-invite-row,\n#cvp-1-z57ldW .cvp-stat,\n#cvp-1-z57ldW .cvp-mini-card,\n#cvp-1-z57ldW .cvp-chip {\n    transition: all 0.25s ease;\n    will-change: transform, box-shadow;\n}\n        <\/style>\n                        <div class=\"cvp-app\">\n            <!-- Sidebar -->\n            <aside class=\"cvp-side\">\n                <div class=\"cvp-brand\">Convite+<\/div>\n                <ul class=\"cvp-nav\" data-cvp-nav>\n                    <li data-view=\"painel\" class=\"active\">Painel de Controlo<\/li>\n                    <li data-view=\"convites\">Meus Convites<\/li>\n                    <li data-view=\"calendario\">Calend\u00e1rio<\/li>\n                    <li data-view=\"portfolio\">Portf\u00f3lio<\/li>\n                <\/ul>\n            <\/aside>\n\n            <!-- Main -->\n            <main class=\"cvp-main\">\n\n                <!-- PAINEL -->\n                <section data-cvp-view=\"painel\">\n                    <div class=\"cvp-header\">\n                        <div>\n                            <div class=\"cvp-title\">Painel de Controlo<\/div>\n                            <div class=\"cvp-sub\">Vis\u00e3o geral dos teus convites<\/div>\n                        <\/div>\n                        <button class=\"cvp-btn\" data-cvp-new>+ Novo Convite<\/button>\n                    <\/div>\n                    <div class=\"cvp-stats\">\n                        <div class=\"cvp-stat\"><div class=\"num\" data-stat=\"total\">0<\/div><div class=\"lbl\">Convites Criados<\/div><\/div>\n                        <div class=\"cvp-stat\"><div class=\"num\" data-stat=\"concluidos\">0<\/div><div class=\"lbl\">Conclu\u00eddos<\/div><\/div>\n                        <div class=\"cvp-stat\"><div class=\"num\" data-stat=\"rascunho\">0<\/div><div class=\"lbl\">Em Rascunho<\/div><\/div>\n                        <div class=\"cvp-stat\"><div class=\"num\" data-stat=\"proximo\">\u2014<\/div><div class=\"lbl\">Pr\u00f3ximo Evento<\/div><\/div>\n                    <\/div>\n                    <div class=\"cvp-card\">\n                        <h3>Convites Recentes<\/h3>\n                        <div data-cvp-recent><\/div>\n                    <\/div>\n                <\/section>\n\n                <!-- CONVITES -->\n                <section data-cvp-view=\"convites\" style=\"display:none;\">\n                    <div class=\"cvp-header\">\n                        <div>\n                            <div class=\"cvp-title\">Meus Convites &amp; Cat\u00e1logos<\/div>\n                            <div class=\"cvp-sub\">Cria, organiza e gere todos os teus convites<\/div>\n                        <\/div>\n                        <button class=\"cvp-btn\" data-cvp-new>+ Novo Convite<\/button>\n                    <\/div>\n                    <div class=\"cvp-filters\" data-cvp-filters>\n                        <span class=\"cvp-chip active\" data-filter=\"todos\">Todos<\/span>\n                        <span class=\"cvp-chip\" data-filter=\"Casamento\">Casamento<\/span>\n                        <span class=\"cvp-chip\" data-filter=\"Anivers\u00e1rio\">Anivers\u00e1rio<\/span>\n                        <span class=\"cvp-chip\" data-filter=\"Batizado\">Batizado<\/span>\n                        <span class=\"cvp-chip\" data-filter=\"Corporativo\">Corporativo<\/span>\n                        <span class=\"cvp-chip\" data-filter=\"Outro\">Outro<\/span>\n                    <\/div>\n                    <div data-cvp-list><\/div>\n                <\/section>\n\n                <!-- CALENDARIO -->\n                <section data-cvp-view=\"calendario\" style=\"display:none;\">\n                    <div class=\"cvp-header\">\n                        <div>\n                            <div class=\"cvp-title\">Calend\u00e1rio de Produ\u00e7\u00e3o &amp; Entrega<\/div>\n                            <div class=\"cvp-sub\">Datas dos teus eventos<\/div>\n                        <\/div>\n                    <\/div>\n                    <div class=\"cvp-cal-nav\">\n                        <button class=\"cvp-btn outline small\" data-cal-prev\">\u2039<\/button>\n                        <strong data-cal-label><\/strong>\n                        <button class=\"cvp-btn outline small\" data-cal-next\">\u203a<\/button>\n                    <\/div>\n                    <div class=\"cvp-cal-grid\" data-cal-grid><\/div>\n                <\/section>\n\n                <!-- PORTFOLIO -->\n                <section data-cvp-view=\"portfolio\" style=\"display:none;\">\n                    <div class=\"cvp-header\">\n                        <div>\n                            <div class=\"cvp-title\">Gestor de Portf\u00f3lio<\/div>\n                            <div class=\"cvp-sub\">Modelos e estilos de design<\/div>\n                        <\/div>\n                    <\/div>\n                    <div class=\"cvp-grid-cards\">\n                        <div class=\"cvp-mini-card\"><div class=\"ic\">\u2726<\/div><div class=\"nm\">Moderno<\/div><\/div>\n                        <div class=\"cvp-mini-card\"><div class=\"ic\">\u2726<\/div><div class=\"nm\">Cl\u00e1ssico<\/div><\/div>\n                        <div class=\"cvp-mini-card\"><div class=\"ic\">\u2726<\/div><div class=\"nm\">Minimalista<\/div><\/div>\n                        <div class=\"cvp-mini-card\"><div class=\"ic\">\u2726<\/div><div class=\"nm\">Vintage<\/div><\/div>\n                        <div class=\"cvp-mini-card\"><div class=\"ic\">\u2726<\/div><div class=\"nm\">Floral<\/div><\/div>\n                        <div class=\"cvp-mini-card\"><div class=\"ic\">\u2726<\/div><div class=\"nm\">Elegante<\/div><\/div>\n                    <\/div>\n                <\/section>\n\n            <\/main>\n        <\/div>\n\n        <!-- Modal de cria\u00e7\u00e3o\/edi\u00e7\u00e3o -->\n        <div class=\"cvp-overlay\" data-cvp-overlay>\n            <div class=\"cvp-modal\">\n                <h2 data-cvp-modal-title>Novo Convite<\/h2>\n                <input type=\"hidden\" data-f=\"id\">\n                <div class=\"cvp-field\">\n                    <label>Nome do Evento<\/label>\n                    <input type=\"text\" data-f=\"nome\" placeholder=\"Ex: Casamento de Maria &amp; Jo\u00e3o\">\n                <\/div>\n                <div class=\"cvp-field\">\n                    <label>Categoria<\/label>\n                    <select data-f=\"categoria\">\n                        <option>Casamento<\/option>\n                        <option>Anivers\u00e1rio<\/option>\n                        <option>Batizado<\/option>\n                        <option>Corporativo<\/option>\n                        <option>Outro<\/option>\n                    <\/select>\n                <\/div>\n                <div class=\"cvp-field\">\n                    <label>Data do Evento<\/label>\n                    <input type=\"date\" data-f=\"data\">\n                <\/div>\n                <div class=\"cvp-field\">\n                    <label>Local<\/label>\n                    <input type=\"text\" data-f=\"local\" placeholder=\"Ex: Quinta da Lapa\">\n                <\/div>\n                <div class=\"cvp-field\">\n                    <label>Estado<\/label>\n                    <select data-f=\"estado\">\n                        <option value=\"rascunho\">Rascunho<\/option>\n                        <option value=\"enviado\">Enviado<\/option>\n                        <option value=\"concluido\">Conclu\u00eddo<\/option>\n                    <\/select>\n                <\/div>\n                <div class=\"cvp-field\">\n                    <label>Notas<\/label>\n                    <textarea data-f=\"notas\" placeholder=\"Detalhes, convidados, fornecedores...\"><\/textarea>\n                <\/div>\n                <div class=\"cvp-modal-actions\">\n                    <button class=\"cvp-btn danger\" data-cvp-delete style=\"display:none;margin-right:auto;\">Eliminar<\/button>\n                    <button class=\"cvp-btn outline\" data-cvp-cancel>Cancelar<\/button>\n                    <button class=\"cvp-btn\" data-cvp-save>Guardar<\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n                        <script>\n        (function(){\n            var root = document.getElementById(\"cvp-1-z57ldW\");\n            if (!root) return;\n            var STORAGE_KEY = 'convite_plus_data_cvp-1-z57ldW';\n\n            function loadData(){\n                try {\n                    var raw = localStorage.getItem(STORAGE_KEY);\n                    if (raw) return JSON.parse(raw);\n                } catch(e) {}\n                return seedData();\n            }\n            function saveData(){ localStorage.setItem(STORAGE_KEY, JSON.stringify(state.convites)); }\n\n            function seedData(){\n                var today = new Date();\n                function plus(d){ var dt = new Date(today); dt.setDate(dt.getDate()+d); return dt.toISOString().slice(0,10); }\n                return [\n                    { id: uid(), nome: 'Casamento de Maria & Jo\u00e3o', categoria: 'Casamento', data: plus(20), local: 'Quinta da Lapa', estado: 'enviado', notas: '' },\n                    { id: uid(), nome: 'Anivers\u00e1rio de 30 Anos', categoria: 'Anivers\u00e1rio', data: plus(8), local: 'Loft Avenida', estado: 'rascunho', notas: '' },\n                    { id: uid(), nome: 'Batizado da Sofia', categoria: 'Batizado', data: plus(-5), local: 'Igreja de Santo Ant\u00f3nio', estado: 'concluido', notas: '' }\n                ];\n            }\n            function uid(){ return 'c' + Math.random().toString(36).slice(2,9); }\n\n            var state = { convites: loadData(), filter: 'todos', view: 'painel', calDate: new Date() };\n\n            var els = {\n                navItems: root.querySelectorAll('[data-cvp-nav] li'),\n                views: root.querySelectorAll('[data-cvp-view]'),\n                list: root.querySelector('[data-cvp-list]'),\n                recent: root.querySelector('[data-cvp-recent]'),\n                filters: root.querySelectorAll('[data-cvp-filters] .cvp-chip'),\n                overlay: root.querySelector('[data-cvp-overlay]'),\n                modalTitle: root.querySelector('[data-cvp-modal-title]'),\n                save: root.querySelector('[data-cvp-save]'),\n                cancel: root.querySelector('[data-cvp-cancel]'),\n                del: root.querySelector('[data-cvp-delete]'),\n                newBtns: root.querySelectorAll('[data-cvp-new]'),\n                statTotal: root.querySelector('[data-stat=\"total\"]'),\n                statConcluidos: root.querySelector('[data-stat=\"concluidos\"]'),\n                statRascunho: root.querySelector('[data-stat=\"rascunho\"]'),\n                statProximo: root.querySelector('[data-stat=\"proximo\"]'),\n                calGrid: root.querySelector('[data-cal-grid]'),\n                calLabel: root.querySelector('[data-cal-label]'),\n                calPrev: root.querySelector('[data-cal-prev]'),\n                calNext: root.querySelector('[data-cal-next]')\n            };\n\n            function fmtDate(s){\n                if (!s) return '';\n                var d = new Date(s + 'T00:00:00');\n                return d.toLocaleDateString('pt-PT', { day:'2-digit', month:'short', year:'numeric' });\n            }\n\n            function switchView(view){\n                state.view = view;\n                els.navItems.forEach(function(li){ li.classList.toggle('active', li.getAttribute('data-view') === view); });\n                els.views.forEach(function(sec){ sec.style.display = (sec.getAttribute('data-cvp-view') === view) ? '' : 'none'; });\n                if (view === 'calendario') renderCalendar();\n                if (view === 'painel') renderPainel();\n                if (view === 'convites') renderList();\n            }\n\n            els.navItems.forEach(function(li){\n                li.addEventListener('click', function(){ switchView(li.getAttribute('data-view')); });\n            });\n\n            function statusLabel(e){\n                return e === 'rascunho' ? 'Rascunho' : (e === 'enviado' ? 'Enviado' : 'Conclu\u00eddo');\n            }\n\n            function renderList(){\n                var items = state.convites.filter(function(c){\n                    return state.filter === 'todos' || c.categoria === state.filter;\n                }).sort(function(a,b){ return (a.data||'').localeCompare(b.data||''); });\n\n                if (!items.length){\n                    els.list.innerHTML = '<div class=\"cvp-empty\">Nenhum convite encontrado. Cria o teu primeiro convite.<\/div>';\n                    return;\n                }\n                els.list.innerHTML = items.map(function(c){\n                    return '' +\n                    '<div class=\"cvp-invite-row\" data-id=\"'+c.id+'\">' +\n                        '<div class=\"cvp-invite-thumb\">\u2709<\/div>' +\n                        '<div class=\"cvp-invite-info\">' +\n                            '<div class=\"nm\">'+escapeHtml(c.nome || 'Sem nome')+'<\/div>' +\n                            '<div class=\"mt\">'+escapeHtml(c.categoria)+' \u00b7 '+fmtDate(c.data)+(c.local ? ' \u00b7 '+escapeHtml(c.local) : '')+'<\/div>' +\n                        '<\/div>' +\n                        '<span class=\"cvp-status '+c.estado+'\">'+statusLabel(c.estado)+'<\/span>' +\n                        '<button class=\"cvp-btn outline small\" data-edit=\"'+c.id+'\">Editar<\/button>' +\n                    '<\/div>';\n                }).join('');\n\n                els.list.querySelectorAll('[data-edit]').forEach(function(btn){\n                    btn.addEventListener('click', function(){ openModal(btn.getAttribute('data-edit')); });\n                });\n            }\n\n            function renderPainel(){\n                var total = state.convites.length;\n                var concluidos = state.convites.filter(function(c){ return c.estado === 'concluido'; }).length;\n                var rascunho = state.convites.filter(function(c){ return c.estado === 'rascunho'; }).length;\n                var todayStr = new Date().toISOString().slice(0,10);\n                var futuros = state.convites.filter(function(c){ return c.data && c.data >= todayStr; }).sort(function(a,b){ return a.data.localeCompare(b.data); });\n\n                els.statTotal.textContent = total;\n                els.statConcluidos.textContent = concluidos;\n                els.statRascunho.textContent = rascunho;\n                els.statProximo.textContent = futuros.length ? fmtDate(futuros[0].data) : '\u2014';\n\n                var recentes = state.convites.slice().sort(function(a,b){ return (b.id > a.id) ? 1 : -1; }).slice(0,4);\n                if (!recentes.length){\n                    els.recent.innerHTML = '<div class=\"cvp-empty\">Ainda n\u00e3o h\u00e1 convites. Cria o primeiro!<\/div>';\n                    return;\n                }\n                els.recent.innerHTML = recentes.map(function(c){\n                    return '' +\n                    '<div class=\"cvp-invite-row\" data-id=\"'+c.id+'\">' +\n                        '<div class=\"cvp-invite-thumb\">\u2709<\/div>' +\n                        '<div class=\"cvp-invite-info\">' +\n                            '<div class=\"nm\">'+escapeHtml(c.nome || 'Sem nome')+'<\/div>' +\n                            '<div class=\"mt\">'+escapeHtml(c.categoria)+' \u00b7 '+fmtDate(c.data)+'<\/div>' +\n                        '<\/div>' +\n                        '<span class=\"cvp-status '+c.estado+'\">'+statusLabel(c.estado)+'<\/span>' +\n                    '<\/div>';\n                }).join('');\n            }\n\n            function renderCalendar(){\n                var d = state.calDate;\n                var year = d.getFullYear(), month = d.getMonth();\n                var first = new Date(year, month, 1);\n                var startWeekday = (first.getDay() + 6) % 7; \/\/ segunda = 0\n                var daysInMonth = new Date(year, month+1, 0).getDate();\n                var monthNames = ['Janeiro','Fevereiro','Mar\u00e7o','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'];\n                els.calLabel.textContent = monthNames[month] + ' ' + year;\n\n                var byDay = {};\n                state.convites.forEach(function(c){\n                    if (!c.data) return;\n                    var dd = new Date(c.data + 'T00:00:00');\n                    if (dd.getFullYear() === year && dd.getMonth() === month){\n                        var key = dd.getDate();\n                        byDay[key] = byDay[key] || [];\n                        byDay[key].push(c);\n                    }\n                });\n\n                var html = ['Seg','Ter','Qua','Qui','Sex','S\u00e1b','Dom'].map(function(n){\n                    return '<div class=\"cvp-cal-day-name\">'+n+'<\/div>';\n                }).join('');\n\n                for (var i=0;i<startWeekday;i++){ html += '<div class=\"cvp-cal-cell empty\"><\/div>'; }\n                for (var day=1; day<=daysInMonth; day++){\n                    var tags = (byDay[day]||[]).map(function(c){\n                        return '<div class=\"cvp-cal-tag\">'+escapeHtml(c.nome)+'<\/div>';\n                    }).join('');\n                    html += '<div class=\"cvp-cal-cell\"><div class=\"d\">'+day+'<\/div>'+tags+'<\/div>';\n                }\n                els.calGrid.innerHTML = html;\n            }\n\n            els.calPrev && els.calPrev.addEventListener('click', function(){\n                state.calDate = new Date(state.calDate.getFullYear(), state.calDate.getMonth()-1, 1);\n                renderCalendar();\n            });\n            els.calNext && els.calNext.addEventListener('click', function(){\n                state.calDate = new Date(state.calDate.getFullYear(), state.calDate.getMonth()+1, 1);\n                renderCalendar();\n            });\n\n            els.filters.forEach(function(chip){\n                chip.addEventListener('click', function(){\n                    els.filters.forEach(function(c){ c.classList.remove('active'); });\n                    chip.classList.add('active');\n                    state.filter = chip.getAttribute('data-filter');\n                    renderList();\n                });\n            });\n\n            function escapeHtml(str){\n                return (str || '').toString().replace(\/[&<>\"']\/g, function(m){\n                    return ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'})[m];\n                });\n            }\n\n            var fields = root.querySelectorAll('[data-f]');\n            function getField(name){ return root.querySelector('[data-f=\"'+name+'\"]'); }\n            function fillForm(c){\n                fields.forEach(function(f){\n                    var key = f.getAttribute('data-f');\n                    f.value = c && c[key] ? c[key] : (key === 'categoria' ? 'Casamento' : (key === 'estado' ? 'rascunho' : ''));\n                });\n            }\n\n            function openModal(id){\n                var c = id ? state.convites.find(function(x){ return x.id === id; }) : null;\n                fillForm(c);\n                els.modalTitle.textContent = c ? 'Editar Convite' : 'Novo Convite';\n                els.del.style.display = c ? '' : 'none';\n                els.overlay.classList.add('open');\n            }\n            function closeModal(){ els.overlay.classList.remove('open'); }\n\n            els.newBtns.forEach(function(btn){ btn.addEventListener('click', function(){ openModal(null); }); });\n            els.cancel.addEventListener('click', closeModal);\n            els.overlay.addEventListener('click', function(e){ if (e.target === els.overlay) closeModal(); });\n\n            els.save.addEventListener('click', function(){\n                var id = getField('id').value;\n                var nome = getField('nome').value.trim();\n                if (!nome){ getField('nome').focus(); return; }\n                var payload = {\n                    id: id || uid(),\n                    nome: nome,\n                    categoria: getField('categoria').value,\n                    data: getField('data').value,\n                    local: getField('local').value.trim(),\n                    estado: getField('estado').value,\n                    notas: getField('notas').value.trim()\n                };\n                if (id){\n                    var idx = state.convites.findIndex(function(c){ return c.id === id; });\n                    if (idx > -1) state.convites[idx] = payload;\n                } else {\n                    state.convites.push(payload);\n                }\n                saveData();\n                closeModal();\n                renderAll();\n            });\n\n            els.del.addEventListener('click', function(){\n                var id = getField('id').value;\n                if (!id) return;\n                if (!confirm('Eliminar este convite?')) return;\n                state.convites = state.convites.filter(function(c){ return c.id !== id; });\n                saveData();\n                closeModal();\n                renderAll();\n            });\n\n            function renderAll(){\n                renderPainel();\n                renderList();\n                if (state.view === 'calendario') renderCalendar();\n            }\n\n            saveData();\n            renderAll();\n        })();\n        <\/script>\n                <\/div>\n        <\/div>\n\t\t\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":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-2604","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/pages\/2604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/comments?post=2604"}],"version-history":[{"count":4,"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/pages\/2604\/revisions"}],"predecessor-version":[{"id":2650,"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/pages\/2604\/revisions\/2650"}],"wp:attachment":[{"href":"https:\/\/app.digitalfreelancer.org\/index.php\/wp-json\/wp\/v2\/media?parent=2604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}