document.addEventListener("DOMContentLoaded", async function() { const reviewsContainer = document.getElementById('reviews-container'); const response = await fetch('https://widget.nomadthinking.com/api/reviews/shieldwalltraining.com'); // const response = await fetch('/api/reviews/shieldwalltraining.com'); const data = await response.json(); const styleElement = document.createElement('style'); styleElement.textContent = ` .glow-effect {transition: box-shadow 0.3s ease-in-out;} .glow-effect:hover { box-shadow: 0 0 15px 5px rgba(72, 187, 183, 0.5); } .min-w-300px{min-width:300px;} .glow-effect{transition:box-shadow 0.3s ease-in-out;} .glow-effect:hover{box-shadow:0 0 15px 5px rgba(72, 187, 183, 0.5);} *,::before,::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scroll-snap-strictness:proximity;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;} *,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb;} ::after,::before{--tw-content:'';} html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;} body{margin:0;line-height:inherit;} h2,h3{font-size:inherit;font-weight:inherit;} a{color:inherit;text-decoration:inherit;} button{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0;} button{text-transform:none;} button{-webkit-appearance:button;background-color:transparent;background-image:none;} h2,h3,p{margin:0;} button{cursor:pointer;} :disabled{cursor:default;} img{display:block;vertical-align:middle;} img{max-width:100%;height:auto;} .relative{position:relative;} .mx-auto{margin-left:auto;margin-right:auto;} .mb-8{margin-bottom:2rem;} .flex{display:flex;} .h-16{height:4rem;} .w-16{width:4rem;} .w-full{width:100%;} .min-w-[300px]{min-width:300px;} .max-w-md{max-width:28rem;} .max-w-screen-xl{max-width:1280px;} .flex-col{flex-direction:column;} .items-center{align-items:center;} .justify-between{justify-content:space-between;} .space-x-2 > :not([hidden]) ~ :not([hidden]){--tw-space-x-reverse:0;margin-right:calc(0.5rem * var(--tw-space-x-reverse));margin-left:calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));} .space-x-4 > :not([hidden]) ~ :not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)));} .space-x-8 > :not([hidden]) ~ :not([hidden]){--tw-space-x-reverse:0;margin-right:calc(2rem * var(--tw-space-x-reverse));margin-left:calc(2rem * calc(1 - var(--tw-space-x-reverse)));} .space-y-4 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse));} .space-y-6 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse));} .overflow-x-hidden{overflow-x:hidden;} .rounded-full{border-radius:9999px;} .rounded-xl{border-radius:0.75rem;} .border-2{border-width:2px;} .border-4{border-width:4px;} .border-teal-300{--tw-border-opacity:1;border-color:rgb(94 234 212 / var(--tw-border-opacity));} .bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39 / var(--tw-bg-opacity));} .bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55 / var(--tw-bg-opacity));} .bg-teal-300{--tw-bg-opacity:1;background-color:rgb(94 234 212 / var(--tw-bg-opacity));} .p-3{padding:0.75rem;} .p-6{padding:1.5rem;} .px-4{padding-left:1rem;padding-right:1rem;} .py-12{padding-top:3rem;padding-bottom:3rem;} .text-4xl{font-size:2.25rem;line-height:2.5rem;} .text-lg{font-size:1.125rem;line-height:1.75rem;} .text-sm{font-size:0.875rem;line-height:1.25rem;} .text-xs{font-size:0.75rem;line-height:1rem;} .font-bold{font-weight:700;} .font-semibold{font-weight:600;} .uppercase{text-transform:uppercase;} .tracking-wide{letter-spacing:0.025em;} .tracking-wider{letter-spacing:0.05em;} .text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219 / var(--tw-text-opacity));} .text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39 / var(--tw-text-opacity));} .text-teal-300{--tw-text-opacity:1;color:rgb(94 234 212 / var(--tw-text-opacity));} .text-teal-400{--tw-text-opacity:1;color:rgb(45 212 191 / var(--tw-text-opacity));} .shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);} .transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms;} .duration-500{transition-duration:500ms;} .ease-in-out{transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);} .hover:border-teal-400:hover{--tw-border-opacity:1;border-color:rgb(45 212 191 / var(--tw-border-opacity));} .hover:bg-teal-400:hover{--tw-bg-opacity:1;background-color:rgb(45 212 191 / var(--tw-bg-opacity));} .hover:underline:hover{-webkit-text-decoration-line:underline;text-decoration-line:underline;} .focus:outline-none:focus{outline:2px solid transparent;outline-offset:2px;} ` document.head.appendChild(styleElement); // Create a wrapper for the reviews and navigation with spacing around it const sectionWrapper = document.createElement('div'); sectionWrapper.classList.add('w-full', 'overflow-x-hidden', 'relative', 'space-y-6', 'flex', 'flex-col', 'items-center'); // Create a flex container to hold the title and buttons in the same row const titleNavWrapper = document.createElement('div'); titleNavWrapper.classList.add('flex', 'justify-between', 'items-center', 'mb-8', 'w-full', 'max-w-screen-xl', 'mx-auto'); // Create the title for the section with modern, vibrant colors const reviewTitle = document.createElement('h2'); reviewTitle.classList.add('text-4xl', 'font-bold', 'text-teal-300', 'tracking-wide', 'uppercase'); reviewTitle.innerHTML = '
'; titleNavWrapper.appendChild(reviewTitle); // Create a button wrapper for left and right buttons const buttonWrapper = document.createElement('div'); buttonWrapper.classList.add('flex', 'space-x-4'); // Create navigation buttons const prevButton = document.createElement('button'); prevButton.id = 'prevButton'; prevButton.classList.add('bg-teal-300', 'text-gray-900', 'p-3', 'rounded-full', 'focus:outline-none', 'hover:bg-teal-400'); prevButton.textContent = '❮'; buttonWrapper.appendChild(prevButton); const nextButton = document.createElement('button'); nextButton.id = 'nextButton'; nextButton.classList.add('bg-teal-300', 'text-gray-900', 'p-3', 'rounded-full', 'focus:outline-none', 'hover:bg-teal-400'); nextButton.textContent = '❯'; buttonWrapper.appendChild(nextButton); // Append button wrapper to the titleNavWrapper titleNavWrapper.appendChild(buttonWrapper); // Append the title and buttons flex container to the section wrapper sectionWrapper.appendChild(titleNavWrapper); // Create the review card container const reviewCardContainer = document.createElement('div'); reviewCardContainer.id = 'reviewContainer'; reviewCardContainer.classList.add('flex', 'space-x-8', 'transition-transform', 'duration-500', 'ease-in-out', 'w-full', 'max-w-screen-xl', 'mx-auto'); // Dynamically create review cards based on the fetched data data.items.forEach(review => { const reviewCard = document.createElement('div'); reviewCard.classList.add('min-w-300px', 'bg-gray-800', 'p-6', 'rounded-xl', 'shadow-lg', 'w-full', 'max-w-md', 'flex', 'flex-col', 'space-y-4', 'border-2', 'border-teal-300', 'hover:border-teal-400', 'glow-effect'); // Dark card with glowing effect // Profile section const profileSection = document.createElement('div'); profileSection.classList.add('flex', 'items-center', 'space-x-4'); const profileImage = document.createElement('img'); profileImage.src = review.profile_image_url; profileImage.classList.add('w-16', 'h-16', 'rounded-full', 'border-4', 'border-teal-300'); profileSection.appendChild(profileImage); const profileInfo = document.createElement('div'); const profileName = document.createElement('h3'); profileName.classList.add('text-lg', 'font-semibold', 'text-teal-300', 'uppercase', 'tracking-wider'); profileName.textContent = review.profile_name; const localGuideText = document.createElement('p'); localGuideText.classList.add('text-xs', 'text-teal-400'); localGuideText.textContent = review.local_guide ? 'Local Guide' : ''; profileInfo.appendChild(profileName); profileInfo.appendChild(localGuideText); profileSection.appendChild(profileInfo); reviewCard.appendChild(profileSection); // Rating and time const ratingSection = document.createElement('div'); ratingSection.classList.add('flex', 'items-center', 'space-x-2'); const ratingStars = document.createElement('span'); const ratingValue = '★'.repeat(review.rating.value) + '☆'.repeat(5 - review.rating.value); ratingStars.classList.add('text-teal-300', 'text-lg'); ratingStars.textContent = ratingValue; ratingSection.appendChild(ratingStars); const reviewTime = document.createElement('p'); reviewTime.classList.add('text-xs', 'text-teal-400'); reviewTime.textContent = review.time_ago; ratingSection.appendChild(reviewTime); reviewCard.appendChild(ratingSection); // Review text const reviewText = document.createElement('p'); reviewText.classList.add('text-sm', 'text-gray-300'); const fullText = review.review_text; // Full review text const shortText = fullText ? fullText.substring(0, 250) : ""; // Shortened version of the text // Set initial text to short version if the text is longer if (fullText && fullText.length > 250) { reviewText.textContent = shortText + "..."; // Add button for "More" and "Less" const toggleButton = document.createElement('button'); toggleButton.textContent = "More"; toggleButton.classList.add('text-teal-400', 'hover:underline', 'text-sm'); // Add event listener to toggle text toggleButton.addEventListener('click', () => { if (toggleButton.textContent === "More") { reviewText.textContent = fullText; toggleButton.textContent = "Less"; } else { reviewText.textContent = shortText + "..."; toggleButton.textContent = "More"; } }); reviewCard.appendChild(reviewText); reviewCard.appendChild(toggleButton); } else { reviewText.textContent = fullText; // If text is short, show full text without "More" button reviewCard.appendChild(reviewText); } reviewCardContainer.appendChild(reviewCard); }); // Append the review card container to the section sectionWrapper.appendChild(reviewCardContainer); reviewsContainer.appendChild(sectionWrapper); // Add scrolling logic let currentPosition = 0; nextButton.addEventListener('click', () => { const containerWidth = sectionWrapper.offsetWidth; currentPosition -= containerWidth; reviewCardContainer.style.transform = 'translateX(' + currentPosition + 'px)'; }); prevButton.addEventListener('click', () => { const containerWidth = sectionWrapper.offsetWidth; currentPosition += containerWidth; reviewCardContainer.style.transform = 'translateX(' + currentPosition + 'px)'; }); function checkBounds() { const maxScroll = -(reviewCardContainer.scrollWidth - sectionWrapper.offsetWidth); if (currentPosition < maxScroll) { currentPosition = maxScroll; } if (currentPosition > 0) { currentPosition = 0; } reviewCardContainer.style.transform = 'translateX(' + currentPosition + 'px)'; } nextButton.addEventListener('click', checkBounds); prevButton.addEventListener('click', checkBounds); });