Adiciona configurações de tamanho e layout em formato de cards para cartazes

This commit is contained in:
2026-06-07 15:26:11 +00:00
parent 00bd9ecace
commit 9bc47ed258
3 changed files with 76 additions and 21 deletions
+45 -11
View File
@@ -6933,10 +6933,12 @@ document.addEventListener('DOMContentLoaded', () => {
const font = cartazFontSelect.value; const font = cartazFontSelect.value;
const border = cartazBorderSelect.value; const border = cartazBorderSelect.value;
const title = cartazTituloInput.value.trim() || 'Título do Cartaz'; const title = cartazTituloInput.value.trim() || 'Título do Cartaz';
const orientacao = document.getElementById('cartazOrientacaoSelect') ? document.getElementById('cartazOrientacaoSelect').value : 'retrato';
cartazPrintableArea.style.backgroundColor = bg; cartazPrintableArea.style.backgroundColor = bg;
cartazPrintableArea.style.color = text; cartazPrintableArea.style.color = text;
cartazPrintableArea.style.fontFamily = font; cartazPrintableArea.style.fontFamily = font;
cartazPrintableArea.style.maxWidth = orientacao === 'paisagem' ? '800px' : '500px';
cartazPreviewTitle.textContent = title; cartazPreviewTitle.textContent = title;
cartazPreviewTitle.style.borderColor = text; cartazPreviewTitle.style.borderColor = text;
@@ -6947,8 +6949,9 @@ document.addEventListener('DOMContentLoaded', () => {
} }
} }
[cartazBgColor, cartazTextColor, cartazFontSelect, cartazBorderSelect, cartazTituloInput].forEach(elem => { [cartazBgColor, cartazTextColor, cartazFontSelect, cartazBorderSelect, cartazTituloInput, document.getElementById('cartazOrientacaoSelect')].forEach(elem => {
if (elem) elem.addEventListener('input', updateLivePreview); if (elem) elem.addEventListener('input', updateLivePreview);
if (elem && elem.tagName === 'SELECT') elem.addEventListener('change', updateLivePreview);
}); });
// Preset Palettes // Preset Palettes
@@ -6989,6 +6992,8 @@ document.addEventListener('DOMContentLoaded', () => {
const tema = cartazTemaInput.value.trim(); const tema = cartazTemaInput.value.trim();
const layout = cartazLayoutSelect.value; const layout = cartazLayoutSelect.value;
const promptImagem = cartazPromptImagem.value.trim(); const promptImagem = cartazPromptImagem.value.trim();
const tamanho = document.getElementById('cartazTamanhoSelect') ? document.getElementById('cartazTamanhoSelect').value : 'A4';
const orientacao = document.getElementById('cartazOrientacaoSelect') ? document.getElementById('cartazOrientacaoSelect').value : 'retrato';
if (!titulo || !tema) { if (!titulo || !tema) {
showToast('Por favor, defina o Título e o Tema do Cartaz.', 'error'); showToast('Por favor, defina o Título e o Tema do Cartaz.', 'error');
@@ -7011,7 +7016,9 @@ document.addEventListener('DOMContentLoaded', () => {
corFundo: cartazBgColor.value, corFundo: cartazBgColor.value,
corTexto: cartazTextColor.value, corTexto: cartazTextColor.value,
layout, layout,
promptImagem promptImagem,
tamanho,
orientacao
}) })
}); });
@@ -7053,8 +7060,11 @@ document.addEventListener('DOMContentLoaded', () => {
const text = cartazTextColor.value; const text = cartazTextColor.value;
const font = cartazFontSelect.value; const font = cartazFontSelect.value;
const border = cartazBorderSelect.value; const border = cartazBorderSelect.value;
const tamanho = document.getElementById('cartazTamanhoSelect') ? document.getElementById('cartazTamanhoSelect').value : 'A4';
const orientacao = document.getElementById('cartazOrientacaoSelect') ? document.getElementById('cartazOrientacaoSelect').value : 'retrato';
const imgContainerHtml = cartazPreviewImageContainer.style.display === 'block' const imgContainerHtml = cartazPreviewImageContainer.style.display === 'block'
? `<div style="width: 100%; margin-bottom: 20px; border-radius: 8px; overflow: hidden; max-height: 350px; border: 2px solid rgba(0,0,0,0.1);"><img src="${cartazPreviewImage.src}" style="width: 100%; height: 100%; object-fit: cover;"></div>` ? `<div style="width: 100%; margin-bottom: 20px; border-radius: 8px; overflow: hidden; max-height: 400px; border: 2px solid rgba(0,0,0,0.1);"><img src="${cartazPreviewImage.src}" style="width: 100%; height: 100%; object-fit: cover;"></div>`
: ''; : '';
const printWindow = window.open('', '_blank'); const printWindow = window.open('', '_blank');
@@ -7066,10 +7076,14 @@ document.addEventListener('DOMContentLoaded', () => {
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&family=Caveat:wght@400;700&family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Outfit:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&family=Caveat:wght@400;700&family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Outfit:wght@400;600;700&display=swap" rel="stylesheet">
<style> <style>
@page {
size: ${tamanho} ${orientacao === 'paisagem' ? 'landscape' : 'portrait'};
margin: 10mm;
}
body { body {
font-family: ${font}; font-family: ${font};
margin: 0; margin: 0;
padding: 40px; padding: 20px;
background-color: #f7fafc; background-color: #f7fafc;
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -7079,10 +7093,10 @@ document.addEventListener('DOMContentLoaded', () => {
.cartaz-frame { .cartaz-frame {
background-color: ${bg}; background-color: ${bg};
color: ${text}; color: ${text};
padding: 50px; padding: 40px;
border-radius: 16px; border-radius: 16px;
width: 100%; width: 100%;
max-width: 800px; max-width: ${orientacao === 'paisagem' ? '1200px' : '800px'};
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
box-sizing: border-box; box-sizing: border-box;
border: ${border === 'none' ? 'none' : `${border} ${text}`}; border: ${border === 'none' ? 'none' : `${border} ${text}`};
@@ -7090,14 +7104,26 @@ document.addEventListener('DOMContentLoaded', () => {
h1 { h1 {
text-align: center; text-align: center;
margin-top: 0; margin-top: 0;
font-size: 3rem; font-size: 3.5rem;
border-bottom: 3px solid ${text}; border-bottom: 3px solid ${text};
padding-bottom: 16px; padding-bottom: 16px;
margin-bottom: 30px; margin-bottom: 30px;
} }
.content-area { .content-area {
font-size: 1.4rem; font-size: 1.5rem;
line-height: 1.8; line-height: 1.6;
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: center;
}
/* Suporte para cards na content-area */
.content-area > div, .content-area > p, .content-area > ul {
background: rgba(255, 255, 255, 0.3);
padding: 20px;
border-radius: 12px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
width: 100%;
} }
ul { ul {
margin-left: 20px; margin-left: 20px;
@@ -7106,8 +7132,16 @@ document.addEventListener('DOMContentLoaded', () => {
margin-bottom: 12px; margin-bottom: 12px;
} }
@media print { @media print {
body { background: transparent; padding: 0; } body { background: transparent; padding: 0; display: block; }
.cartaz-frame { box-shadow: none; border-radius: 0; max-width: 100%; width: 100%; height: 100%; padding: 30px; } .cartaz-frame {
box-shadow: none;
border-radius: 0;
max-width: 100%;
width: 100%;
height: auto;
min-height: 100%;
padding: 30px;
}
button { display: none; } button { display: none; }
} }
</style> </style>
+19
View File
@@ -1733,6 +1733,25 @@
</select> </select>
</div> </div>
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
<div class="settings-group" style="flex: 1; min-width: 140px;">
<label style="color: var(--text-secondary); font-size: 0.75rem; font-weight: 600; text-transform: uppercase;">Tamanho do Papel</label>
<select id="cartazTamanhoSelect" class="obs-select" style="width: 100%; margin-top: 4px;">
<option value="A4" selected>A4 (21 x 29,7 cm)</option>
<option value="A3">A3 (29,7 x 42 cm)</option>
<option value="A2">A2 (42 x 59,4 cm)</option>
<option value="A1">A1 (59,4 x 84,1 cm)</option>
</select>
</div>
<div class="settings-group" style="flex: 1; min-width: 140px;">
<label style="color: var(--text-secondary); font-size: 0.75rem; font-weight: 600; text-transform: uppercase;">Orientação</label>
<select id="cartazOrientacaoSelect" class="obs-select" style="width: 100%; margin-top: 4px;">
<option value="retrato">Retrato (Vertical)</option>
<option value="paisagem">Paisagem (Horizontal)</option>
</select>
</div>
</div>
<h4 style="margin: 0; color: var(--text-primary); border-bottom: 1px dashed var(--border-light); padding-bottom: 8px; margin-top: 8px;">2. Estilo e Cores</h4> <h4 style="margin: 0; color: var(--text-primary); border-bottom: 1px dashed var(--border-light); padding-bottom: 8px; margin-top: 8px;">2. Estilo e Cores</h4>
<div style="display: flex; gap: 12px; flex-wrap: wrap;"> <div style="display: flex; gap: 12px; flex-wrap: wrap;">
+12 -10
View File
@@ -1377,7 +1377,7 @@ app.delete('/api/poesias/:id', requireAuth, async (req, res) => {
// ROTAS DO CRIAR CARTAZES // ROTAS DO CRIAR CARTAZES
// ============================================================ // ============================================================
app.post('/api/cartazes/generate', requireAuth, async (req, res) => { app.post('/api/cartazes/generate', requireAuth, async (req, res) => {
const { titulo, tema, corFundo, corTexto, layout, promptImagem } = req.body; const { titulo, tema, corFundo, corTexto, layout, promptImagem, tamanho, orientacao } = req.body;
const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000'; const usuarioId = req.user?.id || '00000000-0000-0000-0000-000000000000';
if (!titulo || !tema || !layout) { if (!titulo || !tema || !layout) {
@@ -1396,17 +1396,19 @@ Detalhes do Cartaz:
- Título: "${titulo}" - Título: "${titulo}"
- Tema / Foco Pedagógico: "${tema}" - Tema / Foco Pedagógico: "${tema}"
- Layout Selecionado: "${layout}" (Opções: regras, mural, calendario, livre) - Layout Selecionado: "${layout}" (Opções: regras, mural, calendario, livre)
- Tamanho: "${tamanho || 'A4'}"
- Orientação: "${orientacao === 'paisagem' ? 'Paisagem/Horizontal' : 'Retrato/Vertical'}"
Por favor, gere o CONTEÚDO textual estruturado do cartaz. Por favor, gere o CONTEÚDO textual e estrutural do cartaz em HTML.
REGRAS: REGRAS FUNDAMENTAIS E ESTÉTICAS:
- Deve ser acolhedor, lúdico e muito bem estruturado. - Distribua a informação em CARDS (pequenos cartões ou blocos curtos) bem espaçados, parecidos com pôsteres infantis modernos, onde o texto NÃO ocupa uma folha corrida.
- Os textos devem ser extremamente curtos, visuais e fáceis de ler.
- Use emojis apropriados para crianças. - Use emojis apropriados para crianças.
- Se for layout "regras", crie uma lista de combinados da sala (max 5) de forma positiva (ex: "Cuidar dos nossos brinquedos" ao invés de "Não quebrar os brinquedos"). - Se for layout "regras", crie os combinados (max 5) de forma positiva, colocando cada regra em um card <div> separado.
- Se for "calendario", estruture áreas para o dia da semana, ajudante do dia e tempo (ensolarado, chuvoso). - Se for "calendario", estruture áreas para o dia da semana, ajudante e clima.
- Se for "mural", crie seções de recados e novidades da semana. - Considere a orientação ${orientacao === 'paisagem' ? 'Paisagem (horizontal)' : 'Retrato (vertical)'} ao organizar o fluxo: para paisagem, use \`display: flex; flex-wrap: wrap; gap: 20px;\` para os cards ficarem lado a lado; para retrato, de cima para baixo.
- Se for "livre", crie um texto poético ou explicativo baseado no tema. - Não use textos que extrapolem o tamanho de 1 página de ${tamanho || 'A4'}.
- Mantenha os textos curtos, visuais e fáceis de ler para crianças ou pais. - Retorne apenas o formato HTML (use <div>, <p>, <ul>, <li>, <strong>, <span>). Não adicione <html> ou <body>, retorne apenas o conteúdo interno. Não inclua o título <h1> pois ele já é colocado no topo pela interface.`;
- Retorne apenas o conteúdo em formato HTML simples (use tags como <h1>, <p>, <ul>, <li>, <strong>, <span> e estilos inline simples se necessário) para renderizarmos no preview do cartaz. Não adicione tags <html> ou <body>, apenas o bloco de conteúdo interno.`;
let conteudoHtml = ''; let conteudoHtml = '';