Browse Source

test action habib

master
mortezaei 2 months ago
parent
commit
aca314fc4b
  1. 12
      src/app/intro/page.tsx
  2. 16
      src/components/ui/navigation-button.tsx
  3. 129
      src/components/ui/report-actions-sheet.tsx

12
src/app/intro/page.tsx

@ -1,8 +1,10 @@
"use client";
import Image from "next/image";
import { useState } from "react";
import Button from "@/components/ui/button";
import NavigationButton from "@/components/ui/navigation-button";
import ReportActionsSheet from "@/components/ui/report-actions-sheet";
import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main";
import { localizePath } from "@/i18n/config";
import { useI18n } from "@/i18n/provider";
@ -10,6 +12,7 @@ import { useI18n } from "@/i18n/provider";
export default function Intro() {
const { dictionary: t, locale } = useI18n();
const { data: profile } = useMarriageProfileQuery();
const [isReportSheetOpen, setIsReportSheetOpen] = useState(false);
const isInCase = profile?.status === "in_case";
const isFemaleAcceptedFlow =
isInCase &&
@ -33,10 +36,17 @@ export default function Intro() {
return (
<div className="pt-7">
{isReportSheetOpen && (
<ReportActionsSheet onClose={() => setIsReportSheetOpen(false)} />
)}
<header className="flex items-center justify-between">
<NavigationButton icon="back" />
<h1 className="font-faminela">{t.common.appName}</h1>
<NavigationButton icon="support" iconLabel={t.common.support} />
<NavigationButton
icon="support"
iconLabel={t.common.support}
onClick={() => setIsReportSheetOpen(true)}
/>
</header>
<main>
<div className="flex flex-col items-center mt-16">

16
src/components/ui/navigation-button.tsx

@ -108,13 +108,19 @@ export function NavigationButton({
onClick={(event) => {
props.onClick?.(event);
if (
!event.defaultPrevented &&
(icon === "back" || icon === "close") &&
!props.onClick
) {
if (!event.defaultPrevented && !props.onClick) {
if (icon === "back") {
if (typeof window !== "undefined" && (window as any).HabibApp) {
(window as any).HabibApp.postMessage(
JSON.stringify({ action: "close_service" })
);
} else {
router.back();
}
} else if (icon === "close") {
router.back();
}
}
}}
className={[
"inline-flex items-center justify-center rounded-[15px] p-2",

129
src/components/ui/report-actions-sheet.tsx

@ -0,0 +1,129 @@
"use client";
import { useEffect, useState } from "react";
import Button from "@/components/ui/button";
const EXIT_ANIMATION_MS = 220;
type ReportActionsSheetProps = {
onClose?: () => void;
};
declare global {
interface Window {
HabibApp?: {
postMessage: (message: string) => void;
};
onFlutterResponse?: (event: {
action: string;
success: boolean;
data?: { latitude: number; longitude: number };
}) => void;
}
}
export function ReportActionsSheet({ onClose }: ReportActionsSheetProps) {
const [isVisible, setIsVisible] = useState(true);
const [isEntering, setIsEntering] = useState(true);
const [isClosing, setIsClosing] = useState(false);
const closeSheet = () => {
if (isClosing) return;
setIsClosing(true);
};
const handleGetLocation = () => {
if (typeof window !== "undefined" && window.HabibApp) {
window.HabibApp.postMessage(JSON.stringify({ action: "get_location" }));
closeSheet();
}
};
const handleOpenConsultant = () => {
if (typeof window !== "undefined" && window.HabibApp) {
window.HabibApp.postMessage(
JSON.stringify({
action: "open_consultant_page",
data: { consultant: "habib@gmail.com" },
})
);
closeSheet();
}
};
useEffect(() => {
const frameId = window.requestAnimationFrame(() => {
setIsEntering(false);
});
return () => window.cancelAnimationFrame(frameId);
}, []);
useEffect(() => {
if (!isVisible) return;
const previousBodyOverflow = document.body.style.overflow;
const previousHtmlOverflow = document.documentElement.style.overflow;
document.body.style.overflow = "hidden";
document.documentElement.style.overflow = "hidden";
return () => {
document.body.style.overflow = previousBodyOverflow;
document.documentElement.style.overflow = previousHtmlOverflow;
};
}, [isVisible]);
useEffect(() => {
if (!isClosing) return;
const timeoutId = window.setTimeout(() => {
setIsVisible(false);
onClose?.();
}, EXIT_ANIMATION_MS);
return () => window.clearTimeout(timeoutId);
}, [isClosing, onClose]);
useEffect(() => {
window.onFlutterResponse = (event) => {
if (event.action === "get_location" && event.success && event.data) {
const message = `Location: ${event.data.latitude}, ${event.data.longitude}`;
alert(message);
}
};
return () => {
window.onFlutterResponse = undefined;
};
}, []);
if (!isVisible) return null;
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms]",
isClosing || isEntering
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
]
.filter(Boolean)
.join(" ")}
role="dialog"
aria-modal="true"
onClick={(event) => {
if (event.target === event.currentTarget) closeSheet();
}}
>
<section
className={[
"w-full max-w-[375px] rounded-t-[15px] bg-[#F9F8F8] p-3.5 shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out",
isClosing || isEntering ? "translate-y-full" : "translate-y-0",
]
.filter(Boolean)
.join(" ")}
>
<div className="flex flex-col gap-3">
<Button onClick={handleGetLocation}>دریافت موقعیت مکانی</Button>
<Button onClick={handleOpenConsultant}>مشاوره با حبیب</Button>
</div>
</section>
</div>
);
}
export default ReportActionsSheet;
Loading…
Cancel
Save