mirror of
https://github.com/dathere/qsvpro.dathere.com.git
synced 2025-12-19 05:59:24 +00:00
chore: lazy load images and hide download button on vertical mobile view
This commit is contained in:
parent
6d0f0d2177
commit
e65a720026
2 changed files with 133 additions and 123 deletions
|
|
@ -1,68 +1,68 @@
|
||||||
import React, { useState, useEffect, useCallback } from 'react'
|
import React, { useState, useEffect, useCallback } from 'react'
|
||||||
import useEmblaCarousel from 'embla-carousel-react'
|
import useEmblaCarousel from 'embla-carousel-react'
|
||||||
import { Thumb } from './EmblaCarouselThumbsButton'
|
import { Thumb } from './EmblaCarouselThumbsButton'
|
||||||
|
|
||||||
const EmblaCarousel = (props) => {
|
const EmblaCarousel = (props) => {
|
||||||
const { slides, options, plugins } = props
|
const { slides, options, plugins } = props
|
||||||
const [selectedIndex, setSelectedIndex] = useState(0)
|
const [selectedIndex, setSelectedIndex] = useState(0)
|
||||||
const [emblaMainRef, emblaMainApi] = useEmblaCarousel(options, plugins)
|
const [emblaMainRef, emblaMainApi] = useEmblaCarousel(options, plugins)
|
||||||
const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel({
|
const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel({
|
||||||
containScroll: 'keepSnaps',
|
containScroll: 'keepSnaps',
|
||||||
dragFree: true,
|
dragFree: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const onThumbClick = useCallback(
|
const onThumbClick = useCallback(
|
||||||
(index) => {
|
(index) => {
|
||||||
if (!emblaMainApi || !emblaThumbsApi) return
|
if (!emblaMainApi || !emblaThumbsApi) return
|
||||||
emblaMainApi.scrollTo(index)
|
emblaMainApi.scrollTo(index)
|
||||||
},
|
},
|
||||||
[emblaMainApi, emblaThumbsApi]
|
[emblaMainApi, emblaThumbsApi]
|
||||||
)
|
)
|
||||||
|
|
||||||
const onSelect = useCallback(() => {
|
const onSelect = useCallback(() => {
|
||||||
if (!emblaMainApi || !emblaThumbsApi) return
|
if (!emblaMainApi || !emblaThumbsApi) return
|
||||||
setSelectedIndex(emblaMainApi.selectedScrollSnap())
|
setSelectedIndex(emblaMainApi.selectedScrollSnap())
|
||||||
emblaThumbsApi.scrollTo(emblaMainApi.selectedScrollSnap())
|
emblaThumbsApi.scrollTo(emblaMainApi.selectedScrollSnap())
|
||||||
}, [emblaMainApi, emblaThumbsApi, setSelectedIndex])
|
}, [emblaMainApi, emblaThumbsApi, setSelectedIndex])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!emblaMainApi) return
|
if (!emblaMainApi) return
|
||||||
onSelect()
|
onSelect()
|
||||||
|
|
||||||
emblaMainApi.on('select', onSelect).on('reInit', onSelect)
|
emblaMainApi.on('select', onSelect).on('reInit', onSelect)
|
||||||
}, [emblaMainApi, onSelect])
|
}, [emblaMainApi, onSelect])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="embla">
|
<div className="embla">
|
||||||
<div className="embla__viewport lg:mb-4" ref={emblaMainRef}>
|
<div className="embla__viewport lg:mb-4" ref={emblaMainRef}>
|
||||||
<div className="embla__container">
|
<div className="embla__container">
|
||||||
{slides.map((slide, index) => (
|
{slides.map((slide, index) => (
|
||||||
<div key={index} className="embla__slide space-y-2">
|
<div key={index} className="embla__slide space-y-2">
|
||||||
<img src={slide.image.src} alt="qsv pro feature demo GIF" className={index === slides.length - 1 ? `border-4 rounded h-[35rem] mx-auto border-zinc-600` : `border-4 rounded border-zinc-600`} />
|
<img decoding="async" loading="lazy" src={slide.image.src} alt="qsv pro feature demo GIF" className={index === slides.length - 1 ? `border-4 rounded h-[35rem] mx-auto border-zinc-600` : `border-4 rounded border-zinc-600`} />
|
||||||
<h2 className="text-2xl font-bold pt-4 text-[#F2F2F2]">{slide.title}</h2>
|
<h2 className="text-2xl font-bold pt-4 text-[#F2F2F2]">{slide.title}</h2>
|
||||||
<p className="text-lg text-center text-[#F2F2F2]">{slide.description}</p>
|
<p className="text-lg text-center text-[#F2F2F2]">{slide.description}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="embla-thumbs">
|
<div className="embla-thumbs">
|
||||||
<div className="embla-thumbs__viewport" ref={emblaThumbsRef}>
|
<div className="embla-thumbs__viewport" ref={emblaThumbsRef}>
|
||||||
<div className="embla-thumbs__container flex gap-2 w-full justify-evenly">
|
<div className="embla-thumbs__container flex gap-2 w-full justify-evenly">
|
||||||
{slides.map((slide, index) => (
|
{slides.map((slide, index) => (
|
||||||
<Thumb
|
<Thumb
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => onThumbClick(index)}
|
onClick={() => onThumbClick(index)}
|
||||||
selected={index === selectedIndex}
|
selected={index === selectedIndex}
|
||||||
index={slide}
|
index={slide}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EmblaCarousel
|
export default EmblaCarousel
|
||||||
|
|
|
||||||
|
|
@ -105,13 +105,17 @@ export const Hero = () => {
|
||||||
transition={{ duration: 0.5, delay: 0.1 }}
|
transition={{ duration: 0.5, delay: 0.1 }}
|
||||||
>
|
>
|
||||||
<div className="text-customGrayText text-sm lg:text-base xl:text-lg sm:text-base mt-10 px-12 sm:px-48 ">
|
<div className="text-customGrayText text-sm lg:text-base xl:text-lg sm:text-base mt-10 px-12 sm:px-48 ">
|
||||||
Transform spreadsheet data and view statistics in interactive data tables, download/upload from/to compatible <a
|
Transform spreadsheet data and view statistics in
|
||||||
|
interactive data tables, download/upload from/to
|
||||||
|
compatible{" "}
|
||||||
|
<a
|
||||||
href="https://ckan.org"
|
href="https://ckan.org"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="text-blue-300"
|
className="text-blue-300"
|
||||||
>
|
>
|
||||||
CKAN
|
CKAN
|
||||||
</a> instances, and explore qsv pro.
|
</a>{" "}
|
||||||
|
instances, and explore qsv pro.
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
@ -121,62 +125,63 @@ export const Hero = () => {
|
||||||
>
|
>
|
||||||
<div className="grid grid-cols-1 place-items-center gap-2 sm:flex-row mt-14 mb-24 sm:mb-40 justify-center">
|
<div className="grid grid-cols-1 place-items-center gap-2 sm:flex-row mt-14 mb-24 sm:mb-40 justify-center">
|
||||||
{downloadData && OS !== "unknown" ? (
|
{downloadData && OS !== "unknown" ? (
|
||||||
<>
|
<>
|
||||||
<p className="text-white text-md text-center mx-auto mb-4">
|
<p className="text-white text-md text-center mx-auto mb-4">
|
||||||
Download qsv pro and explore the free plan
|
Download qsv pro and explore the free plan
|
||||||
or unlock features with a paid plan.
|
or unlock features with a paid plan.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
{Object.keys(downloadData).map(
|
{Object.keys(downloadData).map(
|
||||||
(platform) => (
|
(platform) => (
|
||||||
<div
|
<div
|
||||||
key={platform}
|
key={platform}
|
||||||
className={`mx-4 ${
|
className={`mx-4 ${
|
||||||
platform === OS
|
platform === OS
|
||||||
? "text-white text-xl font-bold"
|
? "text-white text-xl font-bold"
|
||||||
: "text-white"
|
: "text-white"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{downloadData[platform].map(
|
{downloadData[platform].map(
|
||||||
(download, index) => (
|
(download, index) => (
|
||||||
<>
|
<>
|
||||||
{platform ===
|
{platform ===
|
||||||
"windows" && (
|
"windows" && (
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
<a href="https://apps.microsoft.com/detail/xpffdj3f1jsztf?mode=full">
|
<a href="https://apps.microsoft.com/detail/xpffdj3f1jsztf?mode=full">
|
||||||
<img
|
<img
|
||||||
src="https://get.microsoft.com/images/en-us%20light.svg"
|
src="https://get.microsoft.com/images/en-us%20light.svg"
|
||||||
width="200"
|
width="200"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<a
|
<a
|
||||||
key={index}
|
key={index}
|
||||||
href={`https://github.com/dathere/qsv-pro-releases/releases/download/${name}/${download[1]}`} // Replace with actual download path
|
href={`https://github.com/dathere/qsv-pro-releases/releases/download/${name}/${download[1]}`} // Replace with actual download path
|
||||||
className={`block lg:min-w-96 text-white font-bold py-2 px-4 rounded mt-4 ${
|
className={`block lg:min-w-96 text-white font-bold py-2 px-4 rounded mt-4 ${
|
||||||
platform ===
|
platform ===
|
||||||
OS
|
OS
|
||||||
? " bg-teal-600 hover:bg-teal-700"
|
? " bg-teal-600 hover:bg-teal-700"
|
||||||
: " bg-blue-500 hover:bg-blue-700"
|
: " bg-blue-500 hover:bg-blue-700"
|
||||||
}`}
|
}`}
|
||||||
download
|
download
|
||||||
>
|
>
|
||||||
{download[0]}
|
{download[0]}
|
||||||
</a>
|
</a>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<a
|
<a
|
||||||
href="https://github.com/dathere/qsv-pro-releases/releases/latest"
|
href="https://github.com/dathere/qsv-pro-releases/releases/latest"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
className="hidden md:block"
|
||||||
>
|
>
|
||||||
<div className="custom-button-colored w-64 h-12 mb-2 sm:mb-0">
|
<div className="custom-button-colored w-64 h-12 mb-2 sm:mb-0">
|
||||||
<Download />
|
<Download />
|
||||||
|
|
@ -185,8 +190,13 @@ export const Hero = () => {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<p className="md:hidden text-white sm:text-base text-sm text-center mx-auto">
|
||||||
|
You may access download links here on a
|
||||||
|
desktop device.
|
||||||
|
</p>
|
||||||
<p className="text-white text-sm sm:text-base text-center mx-auto">
|
<p className="text-white text-sm sm:text-base text-center mx-auto">
|
||||||
Download qsv pro and explore the free plan or unlock features with a paid plan.
|
Download qsv pro and explore the free plan
|
||||||
|
or unlock features with a paid plan.
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
@ -206,7 +216,7 @@ export const Hero = () => {
|
||||||
>
|
>
|
||||||
<div className="relative w-full flex justify-center">
|
<div className="relative w-full flex justify-center">
|
||||||
<FeatureCarousel />
|
<FeatureCarousel />
|
||||||
{/*<img
|
{/*<img
|
||||||
src={dashboard.src}
|
src={dashboard.src}
|
||||||
alt="123"
|
alt="123"
|
||||||
className="w-4/5 2xl:w-[1200px] mx-auto absolute z-10 rounded-xl custom-border-gray hero-dashboard-border-gradient lg:top-6 xl:top-0"
|
className="w-4/5 2xl:w-[1200px] mx-auto absolute z-10 rounded-xl custom-border-gray hero-dashboard-border-gradient lg:top-6 xl:top-0"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue