<!DOCTYPE html>
<html lang="he" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RIZE | ממשק ניהול מיתוג</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Heebo:wght@400;700;900&family=Assistant:wght@400;700&family=Rubik:wght@400;700;900&family=Playfair+Display:wght@700&display=swap" rel="stylesheet">
<script src="https://unpkg.com/lucide@latest"></script>
<style>
:root {
--primary-color: #1e3a8a;
--secondary-color: #be123c;
--text-color: #ffffff;
--overlay-color-rgba: rgba(0, 0, 0, 0.2);
}
body { font-family: 'Heebo', sans-serif; background-color: #f7fafc; }
.font-heebo { font-family: 'Heebo', sans-serif; }
.font-assistant { font-family: 'Assistant', sans-serif; }
.font-rubik { font-family: 'Rubik', sans-serif; }
.font-playfair-display { font-family: 'Playfair Display', serif; }
.preview-post {
aspect-ratio: 1 / 1;
transition: background-color 0.3s ease-in-out;
overflow: hidden;
position: relative;
background-size: cover;
background-position: center;
}
.loader {
width: 48px; height: 48px; border: 5px solid #FFF;
border-bottom-color: transparent; border-radius: 50%;
animation: rotation 1s linear infinite;
}
@keyframes rotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
.loader-container {
position: absolute; inset: 0;
background: rgba(0,0,0,0.6); display: flex;
justify-content: center; align-items: center; z-index: 30;
}
.preview-overlay {
position: absolute;
inset: 0;
background-color: var(--overlay-color-rgba);
z-index: 1;
transition: background-color 0.3s ease;
}
.preview-content-area {
position: relative;
width: 100%;
height: 100%;
display: flex;
padding: 1.25rem;
box-sizing: border-box;
z-index: 2;
}
.logo-container, .text-container-wrapper {
position: absolute;
display: flex;
width: 100%;
height: 100%;
top:0;
left:0;
}
/* Vertical Alignment */
.align-y-start { align-items: flex-start; }
.align-y-center { align-items: center; }
.align-y-end { align-items: flex-end; }
/* Horizontal Alignment */
.align-x-start { justify-content: flex-start; }
.align-x-center { justify-content: center; }
.align-x-end { justify-content: flex-end; }
/* Text Alignment Fix */
.text-container {
color: var(--text-color);
width: 100%; /* Ensures text-align works correctly */
}
.text-container-background {
background-color: var(--secondary-color);
padding: 1rem;
border-radius: 0.75rem;
width: auto;
max-width: 90%;
}
.control-btn-group button.active { background-color: #3b82f6; color: white; }
</style>
</head>
<body class="bg-gray-50 text-gray-800">
<div class="container mx-auto p-4 md:p-8">
<header class="mb-8 text-center">
<h1 class="text-4xl md:text-5xl font-black text-gray-800">ממשק הגדרות מיתוג</h1>
<p class="text-lg text-gray-600 mt-2">הגדירו פעם אחת, והפוסטים יווצרו אוטומטית בסגנון שלכם</p>
</header>
<div class="grid grid-cols-1 lg:grid-cols-7 gap-8">
<!-- Left Side: Controls -->
<div class="lg:col-span-3 bg-white p-6 rounded-2xl shadow-lg self-start">
<div class="space-y-6">
<!-- Logo Upload -->
<div>
<h3 class="text-xl font-bold mb-3 flex items-center"><i data-lucide="image" class="w-5 h-5 ml-2 text-blue-500"></i> לוגו</h3>
<div class="flex items-center space-x-4 space-x-reverse">
<img id="logo-preview" src="https://placehold.co/100x100/E2E8F0/A0AEC0?text=לוגו" alt="תצוגה מקדימה" class="object-contain w-24 h-24 bg-gray-100 rounded-xl border">
<label for="logo-upload-input" class="bg-blue-500 text-white px-4 py-2 rounded-lg shadow-md cursor-pointer hover:bg-blue-600 transition-colors">העלאת לוגו</label>
<input type="file" id="logo-upload-input" class="hidden" accept="image/*">
</div>
</div>
<!-- AI Background -->
<div>
<h3 class="text-xl font-bold mb-3 flex items-center"><i data-lucide="sparkles" class="w-5 h-5 ml-2 text-yellow-500"></i> רקע בבינה מלאכותית</h3>
<div class="space-y-4 p-4 bg-gray-50 rounded-lg border">
<label for="ai-style-select" class="block text-sm font-medium text-gray-700">בחר סגנון</label>
<select id="ai-style-select" class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option value="cinematic">צילום קולנועי</option>
<option value="line_art">אמנות קו מינימליסטית</option>
<option value="watercolor">ציור בצבעי מים</option>
<option value="3d_render">עיבוד תלת מימד חלומי</option>
<option value="vintage">צילום וינטג'</option>
</select>
<label for="ai-prompt-input" class="block text-sm font-medium text-gray-700">תאר את נושא התמונה</label>
<input type="text" id="ai-prompt-input" class="mt-1 block w-full border-gray-300 shadow-sm rounded-md sm:text-sm" placeholder="לדוגמה: יער קסום עם קרני אור">
<button id="generate-image-button" class="w-full bg-indigo-600 text-white px-4 py-2 rounded-lg shadow-md hover:bg-indigo-700 flex items-center justify-center transition-colors">
<i data-lucide="wand-2" class="w-5 h-5 mr-2"></i>צור לי תמונה!
</button>
</div>
</div>
<!-- Overlay Controls -->
<div>
<h3 class="text-xl font-bold mb-3 flex items-center"><i data-lucide="layers" class="w-5 h-5 ml-2 text-cyan-500"></i> שכבת כיסוי לתמונה</h3>
<div class="space-y-4 p-4 bg-gray-50 rounded-lg border">
<div class="flex items-center space-x-4 space-x-reverse">
<label for="overlay-color" class="text-sm font-medium text-gray-700">צבע שכבה</label>
<input type="color" id="overlay-color" value="#000000" class="w-10 h-10 p-1 border-0 rounded-md cursor-pointer">
</div>
<div>
<label for="overlay-opacity" class="block text-sm font-medium text-gray-700">שקיפות: <span id="overlay-opacity-value">20</span>%</label>
<input type="range" id="overlay-opacity" min="0" max="1" step="0.05" value="0.2" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
</div>
</div>
</div>
<!-- Layout & Positioning -->
<div>
<h3 class="text-xl font-bold mb-3 flex items-center"><i data-lucide="move" class="w-5 h-5 ml-2 text-teal-500"></i> סידור אלמנטים</h3>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">מיקום הלוגו</label>
<div id="logo-position-controls" class="control-btn-group grid grid-cols-3 gap-1 rounded-lg bg-gray-200 p-1">
<button data-pos="start-start" class="py-1 rounded-md"><i data-lucide="move-up-left"></i></button><button data-pos="start-center" class="py-1 rounded-md"><i data-lucide="move-up"></i></button><button data-pos="start-end" class="py-1 rounded-md"><i data-lucide="move-up-right"></i></button>
<button data-pos="center-start" class="py-1 rounded-md"><i data-lucide="move-left"></i></button><button data-pos="center-center" class="py-1 rounded-md"><i data-lucide="move"></i></button><button data-pos="center-end" class="py-1 rounded-md"><i data-lucide="move-right"></i></button>
<button data-pos="end-start" class="py-1 rounded-md"><i data-lucide="move-down-left"></i></button><button data-pos="end-center" class="py-1 rounded-md active"><i data-lucide="move-down"></i></button><button data-pos="end-end" class="py-1 rounded-md"><i data-lucide="move-down-right"></i></button>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">מיקום הטקסט</label>
<div id="text-position-controls" class="control-btn-group grid grid-cols-3 gap-1 rounded-lg bg-gray-200 p-1">
<button data-pos="start-start" class="py-1 rounded-md"><i data-lucide="move-up-left"></i></button><button data-pos="start-center" class="py-1 rounded-md"><i data-lucide="move-up"></i></button><button data-pos="start-end" class="py-1 rounded-md"><i data-lucide="move-up-right"></i></button>
<button data-pos="center-start" class="py-1 rounded-md"><i data-lucide="move-left"></i></button><button data-pos="center-center" class="py-1 rounded-md active"><i data-lucide="move"></i></button><button data-pos="center-end" class="py-1 rounded-md"><i data-lucide="move-right"></i></button>
<button data-pos="end-start" class="py-1 rounded-md"><i data-lucide="move-down-left"></i></button><button data-pos="end-center" class="py-1 rounded-md"><i data-lucide="move-down"></i></button><button data-pos="end-end" class="py-1 rounded-md"><i data-lucide="move-down-right"></i></button>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">יישור הטקסט</label>
<div id="text-align-controls" class="control-btn-group grid grid-cols-3 gap-1 rounded-lg bg-gray-200 p-1">
<button data-align="right" class="py-1 rounded-md"><i data-lucide="align-right"></i></button>
<button data-align="center" class="py-1 rounded-md active"><i data-lucide="align-center"></i></button>
<button data-align="left" class="py-1 rounded-md"><i data-lucide="align-left"></i></button>
</div>
</div>
</div>
</div>
<!-- Brand Colors & Typography -->
<div class="grid grid-cols-2 gap-6">
<div>
<h3 class="text-xl font-bold mb-3"><i data-lucide="palette" class="inline w-5 h-5 ml-2 text-green-500"></i> צבעים</h3>
<div class="space-y-2">
<div class="flex items-center justify-between"><label class="text-sm">רקע חלופי</label><input type="color" id="primary-color" value="#1e3a8a" class="w-8 h-8 p-0 border-0 rounded-md cursor-pointer"></div>
<div class="flex items-center justify-between"><label class="text-sm">רקע טקסט</label><input type="color" id="secondary-color" value="#be123c" class="w-8 h-8 p-0 border-0 rounded-md cursor-pointer"></div>
<div class="flex items-center justify-between"><label class="text-sm">טקסט</label><input type="color" id="text-color" value="#ffffff" class="w-8 h-8 p-0 border-0 rounded-md cursor-pointer"></div>
</div>
</div>
<div>
<h3 class="text-xl font-bold mb-3"><i data-lucide="type" class="inline w-5 h-5 ml-2 text-purple-500"></i> פונטים</h3>
<div class="space-y-2">
<label for="headline-font" class="block text-sm font-medium text-gray-700">כותרת</label>
<select id="headline-font" class="block w-full text-sm border-gray-300 rounded-md">
<option value="font-playfair-display" selected>Playfair</option><option value="font-heebo">Heebo</option><option value="font-rubik">Rubik</option><option value="font-assistant">Assistant</option>
</select>
<label for="body-font" class="block text-sm font-medium text-gray-700">טקסט רץ</label>
<select id="body-font" class="block w-full text-sm border-gray-300 rounded-md">
<option value="font-assistant" selected>Assistant</option><option value="font-heebo">Heebo</option><option value="font-rubik">Rubik</option><option value="font-playfair-display">Playfair</option>
</select>
</div>
</div>
</div>
</div>
</div>
<!-- Right Side: Preview & Templates -->
<div class="lg:col-span-4">
<div class="sticky top-8">
<h3 class="text-2xl font-bold mb-4 text-center">תצוגה מקדימה חיה</h3>
<div class="max-w-md mx-auto mb-8">
<div id="live-preview" class="preview-post shadow-2xl rounded-2xl">
<!-- Content generated by JS -->
</div>
</div>
<!-- Save Style Section -->
<div class="text-center mt-8 p-4 bg-white rounded-2xl shadow-lg">
<h3 class="text-xl font-bold mb-3">שמירת סגנון</h3>
<div class="flex flex-col sm:flex-row gap-2">
<input type="text" id="style-name-input" class="flex-grow border-gray-300 shadow-sm rounded-md sm:text-sm" placeholder="תן שם לסגנון שלך (למשל: קמפיין חורף)">
<button id="save-button" class="bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-6 rounded-lg shadow-lg transition-transform transform hover:scale-105">
<i data-lucide="save" class="inline w-5 h-5 mr-2"></i>שמור סגנון
</button>
</div>
<p id="save-feedback" class="text-green-600 mt-2 h-5"></p>
</div>
</div>
</div>
</div>
</div>
<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
import { getFirestore, collection, addDoc } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
const firebaseConfig = { /* TODO: PASTE YOUR FIREBASE CONFIG HERE */ };
let db = null;
try {
if (!firebaseConfig.projectId || firebaseConfig.projectId === "your-project-id") throw new Error("Firebase config is not set");
const app = initializeApp(firebaseConfig);
db = getFirestore(app);
} catch (e) {
console.warn("Firebase not configured. Save feature will be disabled.");
}
document.addEventListener('DOMContentLoaded', () => {
const refs = {
logoInput: document.getElementById('logo-upload-input'),
logoPreview: document.getElementById('logo-preview'),
livePreview: document.getElementById('live-preview'),
primaryColor: document.getElementById('primary-color'),
secondaryColor: document.getElementById('secondary-color'),
textColor: document.getElementById('text-color'),
headlineFont: document.getElementById('headline-font'),
bodyFont: document.getElementById('body-font'),
saveButton: document.getElementById('save-button'),
saveFeedback: document.getElementById('save-feedback'),
aiStyle: document.getElementById('ai-style-select'),
aiPrompt: document.getElementById('ai-prompt-input'),
generateImageBtn: document.getElementById('generate-image-button'),
logoPosControls: document.getElementById('logo-position-controls'),
textAlignControls: document.getElementById('text-align-controls'),
textPositionControls: document.getElementById('text-position-controls'),
overlayColor: document.getElementById('overlay-color'),
overlayOpacity: document.getElementById('overlay-opacity'),
overlayOpacityValue: document.getElementById('overlay-opacity-value'),
styleNameInput: document.getElementById('style-name-input'),
};
let state = {
logoUrl: refs.logoPreview.src,
bgImageUrl: null,
primaryColor: refs.primaryColor.value,
secondaryColor: refs.secondaryColor.value,
textColor: refs.textColor.value,
headlineFont: refs.headlineFont.value,
bodyFont: refs.bodyFont.value,
logoPosition: 'end-center',
textPosition: 'center-center',
textAlign: 'center',
overlayColor: refs.overlayColor.value,
overlayOpacity: refs.overlayOpacity.value,
styleName: ''
};
const AI_STYLES = {
cinematic: 'Cinematic, realistic photograph of [PROMPT], dramatic lighting, professional quality',
line_art: 'Minimalist one-line black and white line art of [PROMPT], on a clean plain background, vector style',
watercolor: 'Vibrant watercolor painting of [PROMPT], soft edges, paper texture',
'3d_render': 'Dreamy 3D render of [PROMPT], pastel colors, soft studio lighting',
vintage: 'Authentic vintage film photograph of [PROMPT], grainy texture, faded warm colors, 1970s aesthetic'
};
function renderPreview() {
const preview = refs.livePreview;
const root = document.documentElement;
const hex = state.overlayColor;
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
const rgba = `rgba(${r}, ${g}, ${b}, ${state.overlayOpacity})`;
root.style.setProperty('--primary-color', state.primaryColor);
root.style.setProperty('--secondary-color', state.secondaryColor);
root.style.setProperty('--text-color', state.textColor);
root.style.setProperty('--overlay-color-rgba', rgba);
preview.style.backgroundImage = state.bgImageUrl ? `url(${state.bgImageUrl})` : 'none';
preview.style.backgroundColor = !state.bgImageUrl ? 'var(--primary-color)' : 'transparent';
const [logoY, logoX] = state.logoPosition.split('-');
const [textY, textX] = state.textPosition.split('-');
preview.innerHTML = `
<div class="preview-overlay"></div>
<div class="preview-content-area">
<div class="logo-container align-y-${logoY} align-x-${logoX}">
<img src="${state.logoUrl}" alt="לוגו" class="max-h-16 max-w-[120px] object-contain">
</div>
<div class="text-container-wrapper align-y-${textY} align-x-${textX}">
<div class="text-container" style="text-align: ${state.textAlign};">
<h2 class="preview-headline text-3xl font-bold mb-2 ${state.headlineFont}">כותרת פוסט לדוגמה</h2>
<p class="preview-body text-lg ${state.bodyFont}">זהו טקסט דוגמה קצר שיראה ללקוח איך ייראה הפוסט הסופי עם המיתוג שבחר.</p>
</div>
</div>
</div>
<div id="loader-container" class="loader-container hidden"><div class="loader"></div></div>
`;
}
function updateState(key, value) {
state[key] = value;
if (key === 'primaryColor') state.bgImageUrl = null;
renderPreview();
}
// --- Event Handlers ---
refs.logoInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
updateState('logoUrl', e.target.result);
refs.logoPreview.src = e.target.result;
};
reader.readAsDataURL(file);
}
});
refs.generateImageBtn.addEventListener('click', async () => {
const userPrompt = refs.aiPrompt.value.trim();
if (!userPrompt) { alert('אנא תאר את נושא התמונה.'); return; }
const stylePrompt = AI_STYLES[refs.aiStyle.value];
const fullPrompt = stylePrompt.replace('[PROMPT]', userPrompt);
const loader = refs.livePreview.querySelector('#loader-container');
loader.classList.remove('hidden');
refs.generateImageBtn.disabled = true;
try {
const apiKey = ""; // Provided by Canvas
const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-002:predict?key=${apiKey}`;
const payload = { instances: [{ prompt: fullPrompt }], parameters: { "sampleCount": 1 } };
const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) });
if (!response.ok) throw new Error(`Google API error! status: ${response.status}`);
const result = await response.json();
if (result.predictions && result.predictions[0].bytesBase64Encoded) {
updateState('bgImageUrl', `data:image/png;base64,${result.predictions[0].bytesBase64Encoded}`);
} else { throw new Error("Invalid API response from Google."); }
} catch (error) {
console.error("Error generating image:", error);
alert(`שגיאה ביצירת התמונה: ${error.message}`);
} finally {
loader.classList.add('hidden');
refs.generateImageBtn.disabled = false;
}
});
function setupControlGroup(element, datasetKey, stateKey) {
element.addEventListener('click', (e) => {
const button = e.target.closest('button');
if (button) {
const value = button.dataset[datasetKey];
updateState(stateKey, value);
element.querySelectorAll('button').forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
}
});
}
setupControlGroup(refs.logoPosControls, 'pos', 'logoPosition');
setupControlGroup(refs.textPositionControls, 'pos', 'textPosition');
setupControlGroup(refs.textAlignControls, 'align', 'textAlign');
const simpleInputs = ['primaryColor', 'secondaryColor', 'textColor', 'headlineFont', 'bodyFont', 'overlayColor', 'styleNameInput'];
simpleInputs.forEach(key => {
const refKey = key.endsWith('Input') ? key : key;
if(refs[refKey]){
refs[refKey].addEventListener('input', e => updateState(key.replace('Input', ''), e.target.value));
}
});
refs.overlayOpacity.addEventListener('input', e => {
updateState('overlayOpacity', e.target.value);
refs.overlayOpacityValue.textContent = Math.round(e.target.value * 100);
});
// --- Save Button Logic ---
if (!db) {
refs.saveButton.disabled = true;
refs.saveButton.innerHTML = `<i data-lucide="x-circle" class="inline w-5 h-5 mr-2"></i>נדרש חיבור Firebase`;
refs.saveButton.classList.add('bg-gray-400', 'cursor-not-allowed');
refs.saveButton.classList.remove('bg-green-500', 'hover:bg-green-600');
} else {
refs.saveButton.addEventListener('click', async () => {
const styleName = state.styleName;
if (!styleName || styleName.trim() === '') {
alert('אנא תן שם לסגנון לפני השמירה.');
refs.styleNameInput.focus();
return;
}
refs.saveButton.disabled = true;
refs.saveButton.textContent = 'שומר...';
try {
const { bgImageUrl, ...settingsToSave } = state;
await addDoc(collection(db, "brandingStyles"), { ...settingsToSave, createdAt: new Date() });
refs.saveFeedback.textContent = `סגנון "${styleName}" נשמר בהצלחה!`;
} catch (e) {
console.error("Error saving to Firebase: ", e);
refs.saveFeedback.textContent = 'שגיאה בשמירה!'; refs.saveFeedback.style.color = 'red';
} finally {
setTimeout(() => {
refs.saveButton.disabled = false;
refs.saveButton.innerHTML = `<i data-lucide="save" class="inline w-5 h-5 mr-2"></i>שמור סגנון`;
lucide.createIcons();
refs.saveFeedback.textContent = ''; refs.saveFeedback.style.color = '';
}, 3000);
}
});
}
lucide.createIcons();
renderPreview();
});
</script>
</body>
</html>
הגדירו פעם אחת, והפוסטים יווצרו אוטומטית בסגנון שלכם