diff --git a/src/components/bannieres/BannerBuilder.tsx b/src/components/bannieres/BannerBuilder.tsx index cb211bc..e1979d8 100644 --- a/src/components/bannieres/BannerBuilder.tsx +++ b/src/components/bannieres/BannerBuilder.tsx @@ -48,6 +48,9 @@ export function BannerBuilder({ onApply, onClose }: Props) { const [price, setPrice] = useState('') const [comparePrice, setComparePrice] = useState('') const [selectedImageUrl, setSelectedImageUrl] = useState(null) + const [backgroundBlob, setBackgroundBlob] = useState(null) + const [backgroundPreview, setBackgroundPreview] = useState(null) + const bgFileRef = useRef(null) // Generation const [rendering, setRendering] = useState(false) @@ -112,6 +115,22 @@ export function BannerBuilder({ onApply, onClose }: Props) { } } + const handleBgFile = (e: React.ChangeEvent) => { + const file = e.target.files?.[0] + if (!file) return + setBackgroundBlob(file) + const url = URL.createObjectURL(file) + if (backgroundPreview) URL.revokeObjectURL(backgroundPreview) + setBackgroundPreview(url) + e.target.value = '' + } + + const removeBg = () => { + if (backgroundPreview) URL.revokeObjectURL(backgroundPreview) + setBackgroundBlob(null) + setBackgroundPreview(null) + } + const getConfig = useCallback((): BannerConfig => ({ scheme, promoLabel, @@ -119,7 +138,8 @@ export function BannerBuilder({ onApply, onClose }: Props) { price, comparePrice, productImageUrl: selectedImageUrl, - }), [scheme, promoLabel, title, price, comparePrice, selectedImageUrl]) + backgroundImageBlob: backgroundBlob, + }), [scheme, promoLabel, title, price, comparePrice, selectedImageUrl, backgroundBlob]) const generate = useCallback(async () => { setRendering(true) @@ -142,7 +162,7 @@ export function BannerBuilder({ onApply, onClose }: Props) { if (!title && !product) return const t = setTimeout(() => { generate() }, 600) return () => clearTimeout(t) - }, [scheme, promoLabel, title, price, comparePrice, selectedImageUrl]) // eslint-disable-line react-hooks/exhaustive-deps + }, [scheme, promoLabel, title, price, comparePrice, selectedImageUrl, backgroundBlob]) // eslint-disable-line react-hooks/exhaustive-deps const applyToSlide = async () => { if (!previewRef.current) return @@ -248,9 +268,40 @@ export function BannerBuilder({ onApply, onClose }: Props) { )} + {/* Image de fond */} +
+

Image de fond

+ {backgroundPreview ? ( +
+ Fond + +
+ ) : ( + + )} + + {backgroundPreview && ( +

Un overlay sombre est appliqué automatiquement pour la lisibilité du texte.

+ )} +
+ {/* Thème couleur */}
-

Thème couleur

+

+ {backgroundPreview ? 'Couleur du texte' : 'Thème couleur'} +

{schemeEntries.map(([key, s]) => (