diff --git a/src/components/sections/BentoGrid.astro b/src/components/sections/BentoGrid.astro index 3cea048..7ce2f2a 100644 --- a/src/components/sections/BentoGrid.astro +++ b/src/components/sections/BentoGrid.astro @@ -8,7 +8,7 @@ interface Props { const { config } = Astro.props; --- -
+

{config.sectionTitle}

{config.sectionSubtitle}

@@ -16,7 +16,7 @@ const { config } = Astro.props;
{config.cards.map((card) => ( -
+
{card.badge && ( diff --git a/src/components/sections/HeroSection.astro b/src/components/sections/HeroSection.astro index ef6eed4..f49f993 100644 --- a/src/components/sections/HeroSection.astro +++ b/src/components/sections/HeroSection.astro @@ -13,7 +13,7 @@ const actionElements = elements.filter((el: UIComponent) => el.slotId === 'hero- const customElements = elements.filter((el: UIComponent) => !el.slotId || el.slotId === 'hero-custom-slot'); --- -
+
@@ -27,7 +27,7 @@ const customElements = elements.filter((el: UIComponent) => !el.slotId || el.slo
)} {badgeElements.map(el => ( - + {el.content} ))} @@ -54,7 +54,7 @@ const customElements = elements.filter((el: UIComponent) => !el.slotId || el.slo )} {actionElements.map(el => ( - + {el.content} ))} diff --git a/src/pages/admin/editor.astro b/src/pages/admin/editor.astro index 0ebc6fb..7c38631 100644 --- a/src/pages/admin/editor.astro +++ b/src/pages/admin/editor.astro @@ -83,16 +83,16 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
- +

Sektionen Reihenfolge (Layout) - Drag & Drop + Drag & Drop

{siteConfig.sectionsOrder.map((sec, idx) => ( -
+
#{idx + 1} {sec} @@ -107,6 +107,63 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
+ +
+

+ Hero Sektion: Inhalt & Animation +

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+

+ Bento Grid: Inhalt & Animation +

+
+
+ + +
+
+ + +
+
+ + +
+
+
+

@@ -150,6 +207,18 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u

+
+ + +
+
@@ -180,7 +249,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
{((siteConfig.hero.elements || [])).map((el, idx) => ( -
+
{el.type} (Slot: {el.slotId}) @@ -404,11 +473,48 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u renderSectionsList(); }; + // --- Drag & Drop for Section Items --- + let draggedSecIndex = -1; + + function initSectionDragAndDrop() { + const listContainer = document.getElementById('sections-list'); + if (!listContainer) return; + + const items = listContainer.querySelectorAll('.section-item'); + items.forEach((item, index) => { + item.addEventListener('dragstart', (e) => { + draggedSecIndex = index; + e.dataTransfer.effectAllowed = 'move'; + item.classList.add('opacity-40'); + }); + + item.addEventListener('dragend', () => { + item.classList.remove('opacity-40'); + draggedSecIndex = -1; + }); + + item.addEventListener('dragover', (e) => { + e.preventDefault(); + e.dataTransfer.dropEffect = 'move'; + }); + + item.addEventListener('drop', (e) => { + e.preventDefault(); + if (draggedSecIndex !== -1 && draggedSecIndex !== index) { + const arr = siteConfigState.sectionsOrder; + const movedItem = arr.splice(draggedSecIndex, 1)[0]; + arr.splice(index, 0, movedItem); + renderSectionsList(); + } + }); + }); + } + function renderSectionsList() { const listContainer = document.getElementById('sections-list'); if (!listContainer) return; listContainer.innerHTML = siteConfigState.sectionsOrder.map((sec, idx) => ( - '
' + + '
' + '
' + '#' + (idx + 1) + '' + '' + sec + '' + @@ -420,8 +526,13 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u '
' + '
' )).join(''); + + initSectionDragAndDrop(); } + // Initial call for drag and drop setup + initSectionDragAndDrop(); + function updateSectionSelectors() { const newElSec = document.getElementById('new-el-section'); const filterSec = document.getElementById('filter-section-select'); @@ -443,6 +554,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u const section = document.getElementById('new-el-section').value; const slotId = document.getElementById('new-el-slot').value; const type = document.getElementById('new-el-type').value; + const anim = document.getElementById('new-el-anim').value; const content = document.getElementById('new-el-content').value || 'Neues Element'; const newComp = { @@ -450,6 +562,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u slotId: section + '-' + slotId, type, content, + animation0: anim || undefined, style: 'primary' }; @@ -509,7 +622,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u if (countEl) countEl.textContent = els.length; container.innerHTML = els.map((el, idx) => ( - '
' + + '
' + '
' + '
' + '' + el.type + ' (Slot: ' + el.slotId + ')' + @@ -544,6 +657,28 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u saveBtn.disabled = true; saveBtn.textContent = 'Wird gespeichert...'; + // Collect Hero Section Inputs & Animation + const heroTitle = document.getElementById('hero-title-input')?.value; + const heroSubtitle = document.getElementById('hero-subtitle-input')?.value; + const heroBadge = document.getElementById('hero-badge-input')?.value; + const heroAnim = document.getElementById('hero-anim-select')?.value; + + if (!siteConfigState.hero) siteConfigState.hero = {}; + if (heroTitle !== undefined) siteConfigState.hero.title = heroTitle; + if (heroSubtitle !== undefined) siteConfigState.hero.subtitle = heroSubtitle; + if (heroBadge !== undefined) siteConfigState.hero.badge = heroBadge; + siteConfigState.hero.animation = heroAnim || undefined; + + // Collect Bento Section Inputs & Animation + const bentoTitle = document.getElementById('bento-title-input')?.value; + const bentoSubtitle = document.getElementById('bento-subtitle-input')?.value; + const bentoAnim = document.getElementById('bento-anim-select')?.value; + + if (!siteConfigState.bento) siteConfigState.bento = {}; + if (bentoTitle !== undefined) siteConfigState.bento.sectionTitle = bentoTitle; + if (bentoSubtitle !== undefined) siteConfigState.bento.sectionSubtitle = bentoSubtitle; + siteConfigState.bento.animation = bentoAnim || undefined; + // Collect Header Inputs const brandName = document.getElementById('header-brand-name')?.value; const brandHighlight = document.getElementById('header-brand-highlight')?.value; diff --git a/src/styles/glassmorphism.css b/src/styles/glassmorphism.css index 80c4232..5825fb6 100644 --- a/src/styles/glassmorphism.css +++ b/src/styles/glassmorphism.css @@ -46,3 +46,37 @@ body { background: radial-gradient(circle, var(--theme-accent) 0%, transparent 70%); } +/* Preset Animations */ +.anim-spring-fade { + animation: springFade 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; +} +.anim-hover-bounce:hover { + transform: translateY(-6px); + transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); +} +.anim-pulse-glow { + animation: pulseGlow 3s infinite ease-in-out; +} +.anim-slide-up { + animation: slideUp 0.6s ease-out forwards; +} +.anim-zoom-in { + animation: zoomIn 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards; +} + +@keyframes springFade { + 0% { opacity: 0; transform: translateY(20px) scale(0.95); } + 100% { opacity: 1; transform: translateY(0) scale(1); } +} +@keyframes pulseGlow { + 0%, 100% { box-shadow: 0 0 15px -3px var(--theme-accent); } + 50% { box-shadow: 0 0 35px 5px var(--theme-accent); } +} +@keyframes slideUp { + 0% { opacity: 0; transform: translateY(30px); } + 100% { opacity: 1; transform: translateY(0); } +} +@keyframes zoomIn { + 0% { opacity: 0; transform: scale(0.85); } + 100% { opacity: 1; transform: scale(1); } +} diff --git a/src/utils/configLoader.ts b/src/utils/configLoader.ts index 3423da4..3730a39 100644 --- a/src/utils/configLoader.ts +++ b/src/utils/configLoader.ts @@ -18,6 +18,7 @@ export interface SectionConfig { title?: string; subtitle?: string; badge?: string; + animation?: string; elements?: UIComponent[]; } @@ -45,11 +46,13 @@ export interface SiteConfig { ctaPrimaryLink: string; ctaSecondaryText: string; ctaSecondaryLink: string; + animation?: string; elements?: UIComponent[]; }; bento: { sectionTitle: string; sectionSubtitle: string; + animation?: string; cards: Array<{ id: string; title: string; @@ -57,6 +60,7 @@ export interface SiteConfig { colSpan?: number; badge?: string; icon?: string; + animation?: string; }>; }; contact: {