Browse Source

feat(ui): improve slider touch gestures and add i18n support

- Enhance touch swipe logic in SliderPage by tracking vertical movement to prevent accidental swipes during vertical scrolling
- Implement internationalization (i18n) in SliderSlideTwo using the `useI18n` hook
- Refactor SliderSlideTwo layout and styling for better responsiveness and content alignment
- Update aspect ratios and spacing for video thumbnail components
master
mortezaei 5 days ago
parent
commit
31fd5b8f50
  1. 13
      src/components/Componentes/slider-page.tsx
  2. 32
      src/components/Componentes/slider-slide-two.tsx

13
src/components/Componentes/slider-page.tsx

@ -33,6 +33,7 @@ export default function SliderPage() {
useState<RegistrationAnswer>("self"); useState<RegistrationAnswer>("self");
const [hasReadRules, setHasReadRules] = useState(false); const [hasReadRules, setHasReadRules] = useState(false);
const [touchStartX, setTouchStartX] = useState<number | null>(null); const [touchStartX, setTouchStartX] = useState<number | null>(null);
const [touchStartY, setTouchStartY] = useState<number | null>(null);
const updateProfileBasicMutation = useUpdateMarriageProfileBasicMutation(); const updateProfileBasicMutation = useUpdateMarriageProfileBasicMutation();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const [submitError, setSubmitError] = useState<string | null>(null); const [submitError, setSubmitError] = useState<string | null>(null);
@ -120,20 +121,27 @@ export default function SliderPage() {
const handleTouchStart = (event: TouchEvent<HTMLDivElement>) => { const handleTouchStart = (event: TouchEvent<HTMLDivElement>) => {
setTouchStartX(event.touches[0]?.clientX ?? null); setTouchStartX(event.touches[0]?.clientX ?? null);
setTouchStartY(event.touches[0]?.clientY ?? null);
}; };
const handleTouchEnd = (event: TouchEvent<HTMLDivElement>) => { const handleTouchEnd = (event: TouchEvent<HTMLDivElement>) => {
if (touchStartX === null) {
if (touchStartX === null || touchStartY === null) {
return; return;
} }
const touchEndX = event.changedTouches[0]?.clientX ?? touchStartX; const touchEndX = event.changedTouches[0]?.clientX ?? touchStartX;
const touchEndY = event.changedTouches[0]?.clientY ?? touchStartY;
const deltaX = touchStartX - touchEndX; const deltaX = touchStartX - touchEndX;
const deltaY = touchStartY - touchEndY;
if (Math.abs(deltaX) >= SWIPE_THRESHOLD) {
if (
Math.abs(deltaX) >= SWIPE_THRESHOLD &&
Math.abs(deltaX) > Math.abs(deltaY) * 1.5
) {
if (deltaX > 0) { if (deltaX > 0) {
if (activeSlide === 0 && !hasReadRules) { if (activeSlide === 0 && !hasReadRules) {
setTouchStartX(null); setTouchStartX(null);
setTouchStartY(null);
return; return;
} }
goToNextSlide(); goToNextSlide();
@ -143,6 +151,7 @@ export default function SliderPage() {
} }
setTouchStartX(null); setTouchStartX(null);
setTouchStartY(null);
}; };
return ( return (

32
src/components/Componentes/slider-slide-two.tsx

@ -3,6 +3,7 @@
import Image from "next/image"; import Image from "next/image";
import { useState } from "react"; import { useState } from "react";
import { useMarriageConfigQuery } from "@/hooks/marriage/use-marriage-config"; import { useMarriageConfigQuery } from "@/hooks/marriage/use-marriage-config";
import { useI18n } from "@/translations/provider";
import { SliderHeader } from "./slider-header"; import { SliderHeader } from "./slider-header";
import type { SliderSlideProps } from "./slider-slide"; import type { SliderSlideProps } from "./slider-slide";
import VideoPlayer from "./video-player"; import VideoPlayer from "./video-player";
@ -11,6 +12,7 @@ import NetworkImage from "./network-image";
export function SliderSlideTwo({ index }: SliderSlideProps) { export function SliderSlideTwo({ index }: SliderSlideProps) {
const [isPlayerOpen, setIsPlayerOpen] = useState(false); const [isPlayerOpen, setIsPlayerOpen] = useState(false);
const { data: config } = useMarriageConfigQuery(); const { data: config } = useMarriageConfigQuery();
const { dictionary: t } = useI18n();
const thumbnailSrc = const thumbnailSrc =
config?.video_step_2_thumbnail_url || config?.video_step_2_thumbnail_url ||
@ -24,13 +26,16 @@ export function SliderSlideTwo({ index }: SliderSlideProps) {
aria-label={`Slide ${index + 1}`} aria-label={`Slide ${index + 1}`}
className="flex h-full min-h-0 w-full shrink-0 flex-col" className="flex h-full min-h-0 w-full shrink-0 flex-col"
> >
<div className="min-h-0 flex-1 overflow-y-auto pb-[86px]">
<SliderHeader index={index} title="Watch Video" />
<div className="min-h-0 flex-1 overflow-y-auto overscroll-y-contain pb-[110px] sm:pb-[130px] flex flex-col items-center">
<div className="w-full">
<SliderHeader index={index} title={t["Watch Video"] || "Watch Video"} />
</div>
<div <div
className="mt-6 flex min-h-0 justify-center cursor-pointer group"
className="mt-3 sm:mt-5 flex min-h-0 justify-center cursor-pointer group w-full"
onClick={() => setIsPlayerOpen(true)} onClick={() => setIsPlayerOpen(true)}
> >
<div className="relative w-full max-w-[344px] aspect-[344/488] overflow-hidden rounded-[24px] shadow-xs">
<div className="relative w-full max-w-[344px] aspect-[344/430] max-h-[46dvh] overflow-hidden rounded-[24px] shadow-xs">
<NetworkImage <NetworkImage
src={thumbnailSrc} src={thumbnailSrc}
fallbackSrc="/assets/images/Frame 20953586523.png" fallbackSrc="/assets/images/Frame 20953586523.png"
@ -43,28 +48,31 @@ export function SliderSlideTwo({ index }: SliderSlideProps) {
<Image <Image
src={"/assets/images/Frame 1116607280.svg"} src={"/assets/images/Frame 1116607280.svg"}
alt="play" alt="play"
width={68}
height={68}
width={64}
height={64}
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transition-transform duration-300 group-hover:scale-110 active:scale-95 z-10" className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 transition-transform duration-300 group-hover:scale-110 active:scale-95 z-10"
/> />
</div> </div>
</div> </div>
<div className="mt-4">
<div className="mt-2.5 sm:mt-3.5 shrink-0">
<div className="flex items-center justify-center gap-1.5"> <div className="flex items-center justify-center gap-1.5">
<Image <Image
src={"/assets/images/Avatar Image.png"} src={"/assets/images/Avatar Image.png"}
alt="Dr. Hasti Masoudi"
alt={t["Dr. Hasti Masoudi"] || "Dr. Hasti Masoudi"}
width={20} width={20}
height={20} height={20}
className="rounded-full" className="rounded-full"
/> />
<p className="text-[#2F3A48] group-14 font-semibold"> <p className="text-[#2F3A48] group-14 font-semibold">
Dr. Hasti Masoudi
{t["Dr. Hasti Masoudi"] || "Dr. Hasti Masoudi"}
</p> </p>
</div> </div>
<p className="group-12 text-[#4D4D4D] text-center mt-2 max-w-[340px] mx-auto leading-relaxed">
We have come together with the goal of creating a secure and
confidential path for "permanent marriage" among Muslims
<p className="group-12 text-[#4D4D4D] text-center mt-1.5 max-w-[340px] mx-auto leading-relaxed px-2">
{t[
'We have come together with the goal of creating a secure and confidential path for "permanent marriage" among Muslims'
] ||
'We have come together with the goal of creating a secure and confidential path for "permanent marriage" among Muslims'}
</p> </p>
</div> </div>
</div> </div>

Loading…
Cancel
Save