Browse Source

feat: integrate SliderPage as an overlay in intro-client with hardware back button support

master
mortezaei 5 days ago
parent
commit
58100b685f
  1. 70
      src/app/intro/intro-client.tsx
  2. 10
      src/components/Componentes/slider-page.tsx

70
src/app/intro/intro-client.tsx

@ -2,15 +2,18 @@
import Image from "next/image"; import Image from "next/image";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react";
import { useCallback, useEffect, useState } from "react";
import Button from "@/components/Componentes/button"; import Button from "@/components/Componentes/button";
import NetworkImage from "@/components/Componentes/network-image"; import NetworkImage from "@/components/Componentes/network-image";
import PageHeader from "@/components/Componentes/page-header"; import PageHeader from "@/components/Componentes/page-header";
import ReportActionsSheet from "@/components/Componentes/report-actions-sheet"; import ReportActionsSheet from "@/components/Componentes/report-actions-sheet";
import SectionOverlayHost from "@/components/Componentes/section-overlay-host";
import SliderPage from "@/components/Componentes/slider-page";
import VideoPlayer from "@/components/Componentes/video-player"; import VideoPlayer from "@/components/Componentes/video-player";
import { useMarriageConfigQuery } from "@/hooks/marriage/use-marriage-config"; import { useMarriageConfigQuery } from "@/hooks/marriage/use-marriage-config";
import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main"; import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main";
import { useHabibWebReady } from "@/hooks/use-habib-web-ready"; import { useHabibWebReady } from "@/hooks/use-habib-web-ready";
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { authBridge } from "@/lib/auth-bridge"; import { authBridge } from "@/lib/auth-bridge";
import { getSubmitPath } from "@/lib/get-submit-path"; import { getSubmitPath } from "@/lib/get-submit-path";
import { localizePath } from "@/translations/config"; import { localizePath } from "@/translations/config";
@ -26,6 +29,7 @@ export default function IntroClient() {
const [isReportSheetOpen, setIsReportSheetOpen] = useState(false); const [isReportSheetOpen, setIsReportSheetOpen] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [isPlayerOpen, setIsPlayerOpen] = useState(false); const [isPlayerOpen, setIsPlayerOpen] = useState(false);
const [isStepsOpen, setIsStepsOpen] = useState(false);
const { data: config } = useMarriageConfigQuery(); const { data: config } = useMarriageConfigQuery();
@ -33,6 +37,47 @@ export default function IntroClient() {
// image so we don't need to wait for it — announce immediately on mount. // image so we don't need to wait for it — announce immediately on mount.
useHabibWebReady(true); useHabibWebReady(true);
useEffect(() => {
const readStepsFromUrl = () => {
if (typeof window === "undefined") return;
const params = new URLSearchParams(window.location.search);
setIsStepsOpen(params.get("steps") === "open");
};
readStepsFromUrl();
window.addEventListener("popstate", readStepsFromUrl);
return () => window.removeEventListener("popstate", readStepsFromUrl);
}, []);
const handleOpenSteps = useCallback(() => {
setIsStepsOpen(true);
if (typeof window !== "undefined") {
const url = new URL(window.location.href);
url.searchParams.set("steps", "open");
window.history.pushState({ steps: "open" }, "", url.toString());
}
}, []);
const handleCloseSteps = useCallback(() => {
if (typeof window !== "undefined") {
const params = new URLSearchParams(window.location.search);
if (params.get("steps") === "open") {
setIsStepsOpen(false);
window.history.back();
return;
}
}
setIsStepsOpen(false);
}, []);
useHardwareBackHandler(() => {
if (isStepsOpen) {
handleCloseSteps();
return true; // handled: keep WebView open, just close the overlay
}
return false; // Root: tell Flutter to close WebView screen
}, isStepsOpen);
const handleSubmit = async () => { const handleSubmit = async () => {
if (isSubmitting) { if (isSubmitting) {
return; return;
@ -61,20 +106,21 @@ export default function IntroClient() {
} }
const submitPath = getSubmitPath(profileResponse); const submitPath = getSubmitPath(profileResponse);
const nextPath = localizePath(
submitPath === "/intro" ? "/terms" : submitPath,
locale,
);
router.push(nextPath);
if (submitPath === "/intro" || submitPath === "/terms") {
handleOpenSteps();
} else {
router.push(localizePath(submitPath, locale));
}
} catch (error) { } catch (error) {
console.error("Submission/redirect failed", error); console.error("Submission/redirect failed", error);
router.push(localizePath("/terms", locale));
handleOpenSteps();
} finally { } finally {
setIsSubmitting(false); setIsSubmitting(false);
} }
}; };
return ( return (
<>
<div className="pt-[max(12px,calc(var(--safe-top)+4px))]"> <div className="pt-[max(12px,calc(var(--safe-top)+4px))]">
{isReportSheetOpen && ( {isReportSheetOpen && (
<ReportActionsSheet onClose={() => setIsReportSheetOpen(false)} /> <ReportActionsSheet onClose={() => setIsReportSheetOpen(false)} />
@ -193,5 +239,15 @@ export default function IntroClient() {
</div> </div>
</main> </main>
</div> </div>
<SectionOverlayHost
open={isStepsOpen}
onClose={handleCloseSteps}
>
{isStepsOpen && (
<SliderPage onClose={handleCloseSteps} />
)}
</SectionOverlayHost>
</>
); );
} }

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

@ -24,7 +24,11 @@ const FINAL_SLIDE_COUNT = 5;
const SWIPE_THRESHOLD = 40; const SWIPE_THRESHOLD = 40;
const SLIDER_ANSWERS_STORAGE_KEY = "marriage-slider-answers"; const SLIDER_ANSWERS_STORAGE_KEY = "marriage-slider-answers";
export default function SliderPage() {
export type SliderPageProps = {
onClose?: () => void;
};
export default function SliderPage({ onClose }: SliderPageProps = {}) {
const router = useRouter(); const router = useRouter();
const { locale } = useI18n(); const { locale } = useI18n();
const [activeSlide, setActiveSlide] = useState(0); const [activeSlide, setActiveSlide] = useState(0);
@ -169,7 +173,11 @@ export default function SliderPage() {
console.warn("sessionStorage is not accessible:", e); console.warn("sessionStorage is not accessible:", e);
} }
} }
if (onClose) {
onClose();
} else {
router.back(); router.back();
}
}} }}
/> />
<nav <nav

Loading…
Cancel
Save