feat/fix: improve responsive constraints & add live ThemeListener

This commit is contained in:
AI Studio 2026-05-15 18:41:59 +00:00
parent da869be0bd
commit 11dc19ac93
6 changed files with 126 additions and 0 deletions

View file

@ -1,3 +1,4 @@
import { ThemeListener } from './components/layout/ThemeListener';
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { motion, AnimatePresence } from "motion/react"; import { motion, AnimatePresence } from "motion/react";
import { import {
@ -59,6 +60,7 @@ export default function App() {
return ( return (
<div className="min-h-screen bg-zinc-50 text-zinc-900 selection:bg-brand-gold selection:text-white font-sans overflow-x-hidden"> <div className="min-h-screen bg-zinc-50 text-zinc-900 selection:bg-brand-gold selection:text-white font-sans overflow-x-hidden">
<ThemeListener />
<Analytics /> <Analytics />
<Helmet> <Helmet>
<title>Rafael Fontes | Corretor de Imóveis Premium</title> <title>Rafael Fontes | Corretor de Imóveis Premium</title>

View file

@ -0,0 +1,50 @@
import { useEffect } from 'react';
export function ThemeListener() {
useEffect(() => {
const handleMessage = (event: MessageEvent) => {
// Allow messages from any origin since preview is generic
if (event.data?.type === 'UPDATE_APPEARANCE') {
const settings = event.data.settings;
if (!settings) return;
const root = document.documentElement;
// Update Primary Color
if (settings.primaryColor) {
root.style.setProperty('--color-brand-primary', settings.primaryColor);
root.style.setProperty('--color-brand-blue', settings.primaryColor);
root.style.setProperty('--color-brand-gold', settings.primaryColor);
}
// Update Background Color
if (settings.backgroundColor) {
root.style.setProperty('--color-brand-bg', settings.backgroundColor);
document.body.style.backgroundColor = settings.backgroundColor;
}
// Update Font Family
if (settings.fontFamily) {
const fontLink = document.getElementById('dynamic-font') as HTMLLinkElement;
const fontName = settings.fontFamily.replace(/ /g, '+');
if (fontLink) {
fontLink.href = `https://fonts.googleapis.com/css2?family=${fontName}:wght@300;400;500;600;700&display=swap`;
} else {
const link = document.createElement('link');
link.id = 'dynamic-font';
link.rel = 'stylesheet';
link.href = `https://fonts.googleapis.com/css2?family=${fontName}:wght@300;400;500;600;700&display=swap`;
document.head.appendChild(link);
}
root.style.setProperty('--font-sans', `"${settings.fontFamily}", sans-serif`);
document.body.style.fontFamily = `"${settings.fontFamily}", sans-serif`;
}
}
};
window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}, []);
return null;
}

View file

@ -18,3 +18,14 @@ body {
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@apply font-serif; @apply font-serif;
} }
html, body {
overflow-x: hidden;
width: 100%;
max-width: 100vw;
}
img {
max-width: 100%;
}

View file

@ -1,3 +1,4 @@
import { ThemeListener } from './components/layout/ThemeListener';
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { motion, AnimatePresence } from "motion/react"; import { motion, AnimatePresence } from "motion/react";
import { import {
@ -60,6 +61,7 @@ export default function App() {
return ( return (
<div className="min-h-screen bg-[#FCFAFA] text-brand-dark selection:bg-brand-gold selection:text-white font-sans overflow-x-hidden"> <div className="min-h-screen bg-[#FCFAFA] text-brand-dark selection:bg-brand-gold selection:text-white font-sans overflow-x-hidden">
<ThemeListener />
<Analytics /> <Analytics />
<Helmet> <Helmet>
<title>Helena Fontes | Corretora de Imóveis Premium</title> <title>Helena Fontes | Corretora de Imóveis Premium</title>

View file

@ -0,0 +1,50 @@
import { useEffect } from 'react';
export function ThemeListener() {
useEffect(() => {
const handleMessage = (event: MessageEvent) => {
// Allow messages from any origin since preview is generic
if (event.data?.type === 'UPDATE_APPEARANCE') {
const settings = event.data.settings;
if (!settings) return;
const root = document.documentElement;
// Update Primary Color
if (settings.primaryColor) {
root.style.setProperty('--color-brand-primary', settings.primaryColor);
root.style.setProperty('--color-brand-blue', settings.primaryColor);
root.style.setProperty('--color-brand-gold', settings.primaryColor);
}
// Update Background Color
if (settings.backgroundColor) {
root.style.setProperty('--color-brand-bg', settings.backgroundColor);
document.body.style.backgroundColor = settings.backgroundColor;
}
// Update Font Family
if (settings.fontFamily) {
const fontLink = document.getElementById('dynamic-font') as HTMLLinkElement;
const fontName = settings.fontFamily.replace(/ /g, '+');
if (fontLink) {
fontLink.href = `https://fonts.googleapis.com/css2?family=${fontName}:wght@300;400;500;600;700&display=swap`;
} else {
const link = document.createElement('link');
link.id = 'dynamic-font';
link.rel = 'stylesheet';
link.href = `https://fonts.googleapis.com/css2?family=${fontName}:wght@300;400;500;600;700&display=swap`;
document.head.appendChild(link);
}
root.style.setProperty('--font-sans', `"${settings.fontFamily}", sans-serif`);
document.body.style.fontFamily = `"${settings.fontFamily}", sans-serif`;
}
}
};
window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}, []);
return null;
}

View file

@ -18,3 +18,14 @@ body {
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@apply font-serif; @apply font-serif;
} }
html, body {
overflow-x: hidden;
width: 100%;
max-width: 100vw;
}
img {
max-width: 100%;
}