{t.common.appName}
diff --git a/src/app/globals.css b/src/app/globals.css index 96f73c3..23f5425 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -54,6 +54,7 @@ html:lang(ar) body, width: 100%; min-height: 100vh; padding-inline: 17px; + padding-bottom: var(--safe-bottom, 0px); box-sizing: border-box; background-color: var(--background); background-image: var(--default-page-background-image); diff --git a/src/app/intro/page.tsx b/src/app/intro/page.tsx index 7f6d42a..f4517f2 100644 --- a/src/app/intro/page.tsx +++ b/src/app/intro/page.tsx @@ -114,6 +114,12 @@ export default function Intro() { return; } } + + const profileResponse = profile ?? (await refetch()).data; + const nextPath = localizePath(getSubmitPath(profileResponse), locale); + router.push(nextPath); + } catch (error) { + console.error("Submission/redirect failed", error); } finally { setIsSubmitting(false); } @@ -211,7 +217,10 @@ export default function Intro() { className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" /> -{t.common.appName}
diff --git a/src/app/questions-list/[slug]/question-detail-client.tsx b/src/app/questions-list/[slug]/question-detail-client.tsx index dae47bd..f8db512 100644 --- a/src/app/questions-list/[slug]/question-detail-client.tsx +++ b/src/app/questions-list/[slug]/question-detail-client.tsx @@ -3,6 +3,7 @@ import { useRouter } from "next/navigation"; import { useEffect, useMemo } from "react"; import { + hasQuestionAnswerValue, QuestionAnswersProvider, useQuestionAnswers, } from "@/components/questions/question-answer-storage"; @@ -319,11 +320,25 @@ function QuestionFlowWrapper({ } } + const answer = getAnswerValue(question, questionIndex); + let isAnswered = hasQuestionAnswerValue(answer ?? null); + + if (isAnswered) { + const isEmailQuestion = + question.title.toLowerCase().includes("email") || + question.title.includes("ایمیل"); + if (isEmailQuestion) { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + isAnswered = emailRegex.test(String(answer).trim()); + } + } + return (Habib Marriage
diff --git a/src/app/request-sent/page.tsx b/src/app/request-sent/page.tsx index 1118901..c13f9f3 100644 --- a/src/app/request-sent/page.tsx +++ b/src/app/request-sent/page.tsx @@ -21,7 +21,10 @@ export default function RequestSentPage() { <>Habib Marriage
diff --git a/src/components/dev/dev-click-to-component.tsx b/src/components/dev/dev-click-to-component.tsx index a549c12..c47f797 100644 --- a/src/components/dev/dev-click-to-component.tsx +++ b/src/components/dev/dev-click-to-component.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect } from "react"; +import { useEffect, useState, useRef } from "react"; const IDE_SCHEMES = [ { @@ -46,9 +46,54 @@ function parseLocator(locator: string) { } export function DevClickToComponent() { + const [isInspecting, setIsInspecting] = useState(false); + const [isMobile, setIsMobile] = useState(false); + const [position, setPosition] = useState<{ x: number; y: number } | null>(null); + const [isDragging, setIsDragging] = useState(false); + + const dragStart = useRef({ x: 0, y: 0, buttonX: 0, buttonY: 0, hasMoved: false }); + + // Detect mobile size + useEffect(() => { + const checkSize = () => { + setIsMobile(window.innerWidth <= 768); + }; + checkSize(); + window.addEventListener("resize", checkSize); + return () => window.removeEventListener("resize", checkSize); + }, []); + + // Initialize button position + useEffect(() => { + if (typeof window !== "undefined") { + setPosition({ + x: window.innerWidth - 66, // 50px width + 16px margin + y: window.innerHeight - 66, // 50px height + 16px margin + }); + } + }, [isMobile]); + + // Keep button in bounds on resize + useEffect(() => { + const handleResize = () => { + if (!isMobile) return; + setPosition((prev) => { + if (!prev) return null; + return { + x: Math.max(16, Math.min(window.innerWidth - 66, prev.x)), + y: Math.max(16, Math.min(window.innerHeight - 66, prev.y)), + }; + }); + }; + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); + }, [isMobile]); + useEffect(() => { const userAgent = navigator.userAgent.toLowerCase(); - const handleClick = (event: MouseEvent) => { + + // Desktop: Alt + Click logic + const handleDesktopClick = (event: MouseEvent) => { if (!event.altKey) { return; } @@ -86,14 +131,482 @@ export function DevClickToComponent() { } }; - document.addEventListener("click", handleClick, true); + document.addEventListener("click", handleDesktopClick, true); + return () => { + document.removeEventListener("click", handleDesktopClick, true); + }; + }, []); + + // Mobile: Inspect Mode click interception + useEffect(() => { + if (!isMobile || !isInspecting) return; + + const userAgent = navigator.userAgent.toLowerCase(); + + const handleInspectClick = async (event: MouseEvent) => { + const target = event.target; + if (!(target instanceof Element)) return; + + // Ignore clicks on the inspect button itself + if (target.closest(".dev-inspect-btn")) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + const locator = target + .closest("[data-locator]") + ?.getAttribute("data-locator"); + + if (locator) { + console.log(`[DevClickToComponent] Inspect Mode matched element. Opening in IDE:`, locator); + + // Flash target element outline briefly as visual feedback + const element = target.closest{t.questions.requiredSteps} @@ -88,7 +105,9 @@ export default function RequiredStepsCard() {
- {t.questions.requiredStepsDescription} + {isCompleted + ? t.questions.requiredStepsDescriptionCompleted + : t.questions.requiredStepsDescription}