/* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */ import { FileBrowser } from '@components/admin/FileBrowser.js'; import { InputField } from '@components/common/form/InputField.js'; import { Button } from '@components/common/ui/Button.js'; import { Checkbox } from '@components/common/ui/Checkbox.js'; import { Input } from '@components/common/ui/Input.js'; import { Item, ItemContent, ItemTitle } from '@components/common/ui/Item.js'; import { Label } from '@components/common/ui/Label.js'; import React, { useEffect } from 'react'; import { useFieldArray, useFormContext } from 'react-hook-form'; import { v4 as uuidv4 } from 'uuid'; interface SlideData { id: string; image: string; width?: number; // Image natural width (automatically detected) height?: number; // Image natural height (automatically detected) headline: string; subText: string; buttonText: string; buttonLink: string; buttonColor: string; } interface SlideshowSettingProps { slideshowWidget?: { slides?: SlideData[]; autoplay?: boolean; autoplaySpeed?: number; arrows?: boolean; dots?: boolean; fullWidth?: boolean; widthValue?: number; heightValue?: number; heightType?: 'auto' | 'fixed' | 'full'; }; } export default function SlideshowSetting({ slideshowWidget }: SlideshowSettingProps) { const { slides = [], autoplay = true, autoplaySpeed = 3000, arrows = true, dots = true, fullWidth = true, widthValue = 1920, heightValue = 800, heightType = 'auto' } = slideshowWidget || {}; const { control, setValue, watch } = useFormContext(); const { fields, append, remove, move } = useFieldArray({ control, name: 'settings.slides' }); const currentSlides = watch('settings.slides', slides); const currentAutoplay = watch('settings.autoplay', autoplay); const currentAutoplaySpeed = watch('settings.autoplaySpeed', autoplaySpeed); const currentArrows = watch('settings.arrows', arrows); const currentDots = watch('settings.dots', dots); const currentFullWidth = watch('settings.fullWidth', fullWidth); useEffect(() => { // Initialize slides with existing data setValue('settings.slides', currentSlides?.length ? currentSlides : []); // Initialize the autoplay settings const handleAutoplay = currentAutoplay === undefined || currentAutoplay === null ? autoplay : Boolean(currentAutoplay); setValue('settings.autoplay', handleAutoplay); // Initialize the autoplay speed const speed = Number(currentAutoplaySpeed) || Number(autoplaySpeed) || 3000; setValue('settings.autoplaySpeed', speed); // Initialize the arrows setting const handleArrows = currentArrows === undefined || currentArrows === null ? arrows : Boolean(currentArrows); setValue('settings.arrows', handleArrows); // Initialize the dots setting const handleDots = currentDots === undefined || currentDots === null ? dots : Boolean(currentDots); setValue('settings.dots', handleDots); // Initialize the fullWidth setting const handleFullWidth = currentFullWidth === undefined || currentFullWidth === null ? fullWidth : Boolean(currentFullWidth); setValue('settings.fullWidth', handleFullWidth); // Always use adaptive height for the slideshow setValue('settings.heightType', 'auto'); // Process all slides to detect image dimensions if they don't have them yet if (currentSlides?.length) { currentSlides.forEach((slide, index) => { if (slide.image && (!slide.width || !slide.height)) { getImageDimensions(slide.image, index); } }); } }, []); const [activeSlideIndex, setActiveSlideIndex] = React.useState( null ); const [openFileBrowser, setOpenFileBrowser] = React.useState(false); // Function to get image dimensions const getImageDimensions = (imageUrl: string, slideIndex: number) => { if (!imageUrl) return; const img = new Image(); img.onload = () => { const width = img.naturalWidth; const height = img.naturalHeight; // Update the current slides with the new dimensions const newSlides = [...currentSlides]; newSlides[slideIndex] = { ...newSlides[slideIndex], width, height }; setValue('settings.slides', newSlides); }; img.src = imageUrl; }; const handleImageSelect = (image: string) => { if (activeSlideIndex !== null) { setValue(`settings.slides.${activeSlideIndex}.image`, image); // Detect image dimensions when a new image is selected getImageDimensions(image, activeSlideIndex); setOpenFileBrowser(false); } }; const addSlide = () => { const newSlide: SlideData = { id: uuidv4(), image: '', width: 0, // Will be automatically set when image is selected height: 0, // Will be automatically set when image is selected headline: '', subText: '', buttonText: '', buttonLink: '', buttonColor: '#3B82F6' // Default blue color }; append(newSlide); setTimeout(() => { setActiveSlideIndex(fields.length); }, 50); }; const moveUp = (index: number) => { if (index > 0) { move(index, index - 1); setActiveSlideIndex(index - 1); } }; const moveDown = (index: number) => { if (index < fields.length - 1) { move(index, index + 1); setActiveSlideIndex(index + 1); } }; return (
{openFileBrowser && (
setOpenFileBrowser(false)} />
)} Slideshow Settings
{ setValue('settings.arrows', checked); }} className="mr-2 h-4 w-4" />
{ setValue('settings.autoplay', checked); }} className="mr-2 h-4 w-4" />
{Boolean(currentAutoplay) && ( )}
{/*
{ const isChecked = Boolean(e.target.checked); setValue('settings.dots', isChecked); }} className="mr-2 h-4 w-4" />
*/}

Slides

{fields.length > 0 ? (
{fields.map((slide, index) => (
setActiveSlideIndex(index)} className={`relative border border-border rounded overflow-hidden cursor-pointer ${ activeSlideIndex === index ? 'ring-2 ring-blue-500' : '' }`} >
{currentSlides[index]?.image ? ( {`Slide ) : (
No Image
)}

{currentSlides[index]?.headline || `Slide ${index + 1}`}

))}
) : (

No slides have been added yet.

)}
{activeSlideIndex !== null && fields[activeSlideIndex] && (

Edit Slide {activeSlideIndex + 1}

{currentSlides[activeSlideIndex]?.image ? (
{`Slide { // Additional dimensions detection when the preview image loads const img = e.target as HTMLImageElement; if (img.naturalWidth > 0 && img.naturalHeight > 0) { if ( !currentSlides[activeSlideIndex]?.width || !currentSlides[activeSlideIndex]?.height ) { const newSlides = [...currentSlides]; newSlides[activeSlideIndex] = { ...newSlides[activeSlideIndex], width: img.naturalWidth, height: img.naturalHeight }; setValue('settings.slides', newSlides); } } }} />
{currentSlides[activeSlideIndex]?.headline && (

{currentSlides[activeSlideIndex].headline}

)} {currentSlides[activeSlideIndex]?.subText && (

{currentSlides[activeSlideIndex].subText}

)} {currentSlides[activeSlideIndex]?.buttonText && ( )}
) : (
)} {currentSlides[activeSlideIndex]?.image && ( )}
{/* Hidden fields for image dimensions */} {/* Display image dimensions if available */} {currentSlides[activeSlideIndex]?.image && (
{currentSlides[activeSlideIndex]?.width && currentSlides[activeSlideIndex]?.height ? (

Image dimensions: {currentSlides[activeSlideIndex].width}{' '} × {currentSlides[activeSlideIndex].height} pixels

) : (

Detecting image dimensions...

)}
)}
{ const newSlides = [...currentSlides]; newSlides[activeSlideIndex] = { ...newSlides[activeSlideIndex], headline: e.target.value }; setValue('settings.slides', newSlides); }} placeholder="e.g., New Collection Available" />
{ const newSlides = [...currentSlides]; newSlides[activeSlideIndex] = { ...newSlides[activeSlideIndex], buttonText: e.target.value }; setValue('settings.slides', newSlides); }} placeholder="e.g., Shop Now" />
{ const newSlides = [...currentSlides]; newSlides[activeSlideIndex] = { ...newSlides[activeSlideIndex], buttonLink: e.target.value }; setValue('settings.slides', newSlides); }} placeholder="e.g., /category/new-arrivals" />
{ const newSlides = [...currentSlides]; newSlides[activeSlideIndex] = { ...newSlides[activeSlideIndex], buttonColor: e.target.value }; setValue('settings.slides', newSlides); }} className="w-10 h-10 rounded border-border mr-2 cursor-pointer" /> { const newSlides = [...currentSlides]; newSlides[activeSlideIndex] = { ...newSlides[activeSlideIndex], buttonColor: e.target.value }; setValue('settings.slides', newSlides); }} placeholder="#3B82F6" />
)}
); } export const query = ` query Query($slides: [SlideInput], $autoplay: Boolean, $autoplaySpeed: Int, $arrows: Boolean, $dots: Boolean) { slideshowWidget( slides: $slides, autoplay: $autoplay, autoplaySpeed: $autoplaySpeed, arrows: $arrows, dots: $dots, ) { slides { id image width height headline subText buttonText buttonLink buttonColor } autoplay autoplaySpeed arrows dots } } `; export const fragments = ` fragment SlideData on Slide { id image width height headline subText buttonText buttonLink buttonColor } `; export const variables = `{ slides: getWidgetSetting("slides"), autoplay: getWidgetSetting("autoplay"), autoplaySpeed: getWidgetSetting("autoplaySpeed"), arrows: getWidgetSetting("arrows"), dots: getWidgetSetting("dots"), }`;