{"id":1302,"date":"2025-10-24T18:08:28","date_gmt":"2025-10-24T18:08:28","guid":{"rendered":"https:\/\/iepalasa.com.br\/omara\/?page_id=1302"},"modified":"2026-04-15T14:28:57","modified_gmt":"2026-04-15T14:28:57","slug":"mapas","status":"publish","type":"page","link":"https:\/\/iepalasa.com.br\/omara\/mapas\/","title":{"rendered":"Mapas"},"content":{"rendered":"        <link href=\"https:\/\/cdn.jsdelivr.net\/npm\/tailwindcss@2.2.19\/dist\/tailwind.min.css\" rel=\"stylesheet\">\r\n        <style>\r\n            .sd-container { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; }\r\n            \r\n            \/* Ajuste de dist\u00e2ncia no topo *\/\r\n            #sd-pdf-root:not(.wp-admin *) {\r\n                margin-top: 40px !important;\r\n                padding-top: 10px !important;\r\n                display: block !important;\r\n                clear: both !important;\r\n            }\r\n\r\n            .pdf-card:hover .pdf-overlay { opacity: 1 !important; }\r\n            .pdf-overlay { transition: all 0.25s ease !important; background: rgba(0,0,0,0.05) !important; }\r\n            .btn-delete-admin { background: #000 !important; color: #fff !important; width: 22px !important; height: 22px !important; border-radius: 50% !important; display: flex !important; align-items: center !important; justify-content: center !important; font-size: 9px !important; opacity: 0.8 !important; border: none !important; cursor: pointer !important; position: absolute !important; top: 12px !important; right: 12px !important; z-index: 50 !important; }\r\n            .btn-delete-admin:hover { background: #ff0000 !important; opacity: 1 !important; }\r\n            .pdf-title { font-size: 11px !important; color: #444 !important; font-weight: 400 !important; line-height: 1.4 !important; height: 32px !important; overflow: hidden !important; display: -webkit-box !important; -webkit-line-clamp: 2 !important; -webkit-box-orient: vertical !important; }\r\n            .btn-download-discreet { font-size: 10px !important; color: #999 !important; background-color: #f8f9fa !important; border: 1px solid #eeeeee !important; padding: 8px 12px !important; border-radius: 6px !important; transition: all 0.2s !important; display: flex !important; align-items: center !important; gap: 6px !important; justify-content: center !important; text-transform: uppercase !important; width: 100% !important; cursor: pointer !important; text-decoration: none !important; }\r\n            .btn-download-discreet:hover { background-color: #f0f0f0 !important; color: #333 !important; }\r\n            .visualizar-badge { font-size: 9px !important; font-weight: 500 !important; background: #fff !important; padding: 8px 16px !important; border-radius: 4px !important; box-shadow: 0 4px 12px rgba(0,0,0,0.1) !important; text-transform: uppercase !important; color: #000 !important; }\r\n            \r\n            .sd-loader { border: 2px solid #f3f3f3; border-top: 2px solid #000; border-radius: 50%; width: 20px; height: 20px; animation: spin 1s linear infinite; }\r\n            @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\r\n        <\/style>\r\n        \r\n        <script src=\"https:\/\/unpkg.com\/react@18\/umd\/react.development.js\"><\/script>\r\n        <script src=\"https:\/\/unpkg.com\/react-dom@18\/umd\/react-dom.development.js\"><\/script>\r\n        <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js\"><\/script>\r\n        \r\n        <div id=\"sd-pdf-root\" class=\"sd-container\"><\/div>\r\n\r\n        <script>\r\n            (function() {\r\n                window.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.worker.min.js';\r\n                const { useState, useEffect } = React;\r\n                const api = {\r\n                    root: 'https:\/\/iepalasa.com.br\/omara\/wp-json\/sd-pdf\/v1',\r\n                    nonce: 'd0f55d7ff3',\r\n                    isAdmin: false,\r\n                    targetFolderName: 'Mapas'                };\r\n\r\n                function App() {\r\n                    const [folders, setFolders] = useState([]);\r\n                    const [files, setFiles] = useState([]);\r\n                    const [currentFolderId, setCurrentFolderId] = useState(null);\r\n                    const [newFolderName, setNewFolderName] = useState('');\r\n                    const [loading, setLoading] = useState(true);\r\n\r\n                    useEffect(() => {\r\n                        setLoading(true);\r\n                        if (api.targetFolderName && !api.isAdmin) { fetchByFolderName(); } \r\n                        else { fetchData(); }\r\n                    }, [currentFolderId]);\r\n\r\n                    const fetchByFolderName = async () => {\r\n                        const headers = { 'X-WP-Nonce': api.nonce };\r\n                        const res = await fetch(`${api.root}\/files?folder_name=${encodeURIComponent(api.targetFolderName)}`, { headers });\r\n                        const data = await res.json();\r\n                        setFiles(data); setFolders([]); setLoading(false);\r\n                    };\r\n\r\n                    const fetchData = async () => {\r\n                        const headers = { 'X-WP-Nonce': api.nonce };\r\n                        const [fRes, flRes] = await Promise.all([\r\n                            fetch(`${api.root}\/folders`, { headers }),\r\n                            fetch(`${api.root}\/files?folder_id=${currentFolderId || ''}`, { headers })\r\n                        ]);\r\n                        const allFolders = await fRes.json();\r\n                        setFolders(allFolders.filter(f => f.parent_id == currentFolderId));\r\n                        setFiles(await flRes.json());\r\n                        setLoading(false);\r\n                    };\r\n\r\n                    const deleteItem = async (e, type, id) => {\r\n                        e.stopPropagation();\r\n                        if (!confirm(`Confirmar exclus\u00e3o?`)) return;\r\n                        await fetch(`${api.root}\/${type === 'folder' ? 'folders' : 'files'}\/${id}`, { \r\n                            method: 'DELETE', headers: { 'X-WP-Nonce': api.nonce }\r\n                        });\r\n                        fetchData();\r\n                    };\r\n\r\n                    const openMediaManager = () => {\r\n                        const frame = wp.media({ title: 'Studiodess PDF', multiple: false, library: { type: 'application\/pdf' } });\r\n                        frame.on('select', async () => {\r\n                            setLoading(true);\r\n                            const attachment = frame.state().get('selection').first().toJSON();\r\n                            let thumbnail = '';\r\n\r\n                            try {\r\n                                const pdf = await pdfjsLib.getDocument(attachment.url).promise;\r\n                                const page = await pdf.getPage(1);\r\n                                const viewport = page.getViewport({ scale: 0.5 });\r\n                                const canvas = document.createElement('canvas');\r\n                                canvas.height = viewport.height; canvas.width = viewport.width;\r\n                                await page.render({ canvasContext: canvas.getContext('2d'), viewport }).promise;\r\n                                thumbnail = canvas.toDataURL('image\/jpeg', 0.4);\r\n                            } catch (e) {\r\n                                thumbnail = 'data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8\/5+hHgAHggJ\/PchI7wAAAABJRU5ErkJggg==';\r\n                            }\r\n\r\n                            await fetch(`${api.root}\/upload`, {\r\n                                method: 'POST',\r\n                                headers: { 'Content-Type': 'application\/json', 'X-WP-Nonce': api.nonce },\r\n                                body: JSON.stringify({\r\n                                    name: attachment.title, folder_id: currentFolderId,\r\n                                    file_url: attachment.url, thumbnail: thumbnail\r\n                                })\r\n                            });\r\n                            fetchData();\r\n                        });\r\n                        frame.open();\r\n                    };\r\n\r\n                    if (loading && folders.length === 0 && files.length === 0) {\r\n                        return React.createElement('div', { className: 'flex flex-col items-center justify-center p-20' }, [\r\n                            React.createElement('div', { className: 'sd-loader mb-4' }),\r\n                            React.createElement('span', { className: 'text-[10px] font-bold text-gray-400 tracking-widest uppercase' }, 'Omara: Carregando PDF...')\r\n                        ]);\r\n                    }\r\n\r\n                    return React.createElement('div', { className: 'w-full' }, [\r\n                        api.isAdmin && React.createElement('div', { className: 'flex justify-between items-center mb-10 border-b pb-6' }, [\r\n                            React.createElement('div', { className: 'flex flex-col' }, [\r\n                                React.createElement('span', { className: 'text-[10px] font-bold text-gray-400 tracking-[2px]' }, 'STUDIODESS PDF 2.4.5'),\r\n                                currentFolderId && React.createElement('button', { onClick: () => setCurrentFolderId(null), className: 'text-blue-500 text-[10px] uppercase font-bold mt-2' }, '\u2190 Voltar')\r\n                            ]),\r\n                            React.createElement('div', { className: 'flex gap-2' }, [\r\n                                React.createElement('input', { className: 'border px-3 py-1.5 rounded-lg text-xs outline-none', value: newFolderName, onChange: e => setNewFolderName(e.target.value), placeholder: 'Nova pasta...' }),\r\n                                React.createElement('button', { onClick: async () => { if(!newFolderName) return; await fetch(`${api.root}\/folders`, { method: 'POST', headers: { 'Content-Type': 'application\/json', 'X-WP-Nonce': api.nonce }, body: JSON.stringify({ name: newFolderName, parent_id: currentFolderId }) }); setNewFolderName(''); fetchData(); }, className: 'bg-white border px-4 py-1.5 rounded-lg text-xs hover:bg-gray-50' }, 'Criar Pasta'),\r\n                                React.createElement('button', { onClick: openMediaManager, className: 'bg-black text-white px-4 py-1.5 rounded-lg text-xs font-bold hover:bg-gray-800' }, 'Adicionar PDF')\r\n                            ])\r\n                        ]),\r\n\r\n                        React.createElement('div', { className: 'grid grid-cols-2 sm:grid-cols-2 md:grid-cols-4 gap-12' }, [\r\n                            ...folders.map(f => React.createElement('div', { \r\n                                key: f.id, onClick: () => setCurrentFolderId(f.id),\r\n                                className: 'group relative cursor-pointer border border-gray-100 p-10 rounded-2xl text-center hover:bg-gray-50 transition-all'\r\n                            }, [\r\n                                api.isAdmin && React.createElement('button', { onClick: (e) => deleteItem(e, 'folder', f.id), className: 'btn-delete-admin' }, '\u2715'),\r\n                                React.createElement('div', { className: 'text-5xl mb-3 opacity-30' }, '\ud83d\udcc1'),\r\n                                React.createElement('div', { className: 'text-[11px] text-gray-400 uppercase tracking-wider' }, f.name)\r\n                            ])),\r\n\r\n                            ...files.map(f => React.createElement('div', { key: f.id, className: 'pdf-card flex flex-col' }, [\r\n                                React.createElement('div', { \r\n                                    className: 'relative aspect-[3\/4.2] cursor-pointer overflow-hidden rounded-xl border border-gray-100 shadow-sm hover:shadow-xl transition-all duration-300',\r\n                                    onClick: () => window.open(f.file_url, '_blank')\r\n                                }, [\r\n                                    api.isAdmin && React.createElement('button', { onClick: (e) => deleteItem(e, 'file', f.id), className: 'btn-delete-admin' }, '\u2715'),\r\n                                    React.createElement('img', { src: f.thumb_url, className: 'w-full h-full object-cover' }),\r\n                                    React.createElement('div', { className: 'pdf-overlay absolute inset-0 opacity-0 flex items-center justify-center' }, [\r\n                                        React.createElement('span', { className: 'visualizar-badge' }, 'Visualizar')\r\n                                    ])\r\n                                ]),\r\n                                React.createElement('div', { className: 'mt-4 space-y-3' }, [\r\n                                    React.createElement('div', { className: 'pdf-title' }, f.name),\r\n                                    React.createElement('button', { \r\n                                        onClick: () => {\r\n                                            const a = document.createElement('a'); a.href = f.file_url;\r\n                                            a.download = f.name; document.body.appendChild(a); a.click(); document.body.removeChild(a);\r\n                                        },\r\n                                        className: 'btn-download-discreet'\r\n                                    }, [\r\n                                        React.createElement('svg', { width: \"12\", height: \"12\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", strokeWidth: \"2\" }, [\r\n                                            React.createElement('path', { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3\" })\r\n                                        ]),\r\n                                        'Download'\r\n                                    ])\r\n                                ])\r\n                            ]))\r\n                        ])\r\n                    ]);\r\n                }\r\n                const root = ReactDOM.createRoot(document.getElementById('sd-pdf-root'));\r\n                root.render(React.createElement(App));\r\n            })();\r\n        <\/script>\r\n        \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1302","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/pages\/1302","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/comments?post=1302"}],"version-history":[{"count":8,"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/pages\/1302\/revisions"}],"predecessor-version":[{"id":1528,"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/pages\/1302\/revisions\/1528"}],"wp:attachment":[{"href":"https:\/\/iepalasa.com.br\/omara\/wp-json\/wp\/v2\/media?parent=1302"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}