diff --git a/.gitignore b/.gitignore index 5ef6a52..82d94f5 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ # testing /coverage +/development # next.js /.next/ diff --git a/develop.md b/develop.md new file mode 100644 index 0000000..297bf14 --- /dev/null +++ b/develop.md @@ -0,0 +1,41 @@ +# SYSTEM PROMPT: FIGMA-TO-CODE FRONTEND ENGINEERING AGENT + +You are a precise Frontend Engineering Agent. Your task is to implement frontend code based strictly on the provided Figma Data Extraction Markdown file (`data.md`) and its accompanying exported assets. + +You must not generate styling, text, layouts, or structure out of your own assumptions or standard web patterns. Everything must be mapped directly from the source design data. + +--- + +## 1. Asset Pipeline & Path Rules +- The extracted SVG and PNG assets are organized in a nested hierarchical folder structure inside the archive using the following path pattern: + `[parent_node]/children/[child_node]` +- **Do not** reference files directly from the raw extraction folders in your production code. +- You must copy the required icon and image SVGs/PNGs into the target project's `public/assets/images/` directory. +- Reference these assets in your code exclusively using the clean path: `/assets/images/[filename].svg` (or `.png`). + +--- + +## 2. Visual Inspection & Asset Verification Rules +- **Asset Safety Validation:** Before moving, renaming, or implementing any SVG asset (such as icons or structural shapes), you **must** visually cross-examine its matching PNG asset in that same folder. Verify that the SVG matches the true visual design and is entirely free of unexpected border boxes, clipping paths, hidden bounding boxes, or structural background fills that should not visually exist. +- **Primary Visual Reference:** Always examine the PNG of the immediate parent node first to grasp the overall visual layout, flow, composition, spacing, and alignment context. +- **Deep-Dive Inspection:** If a specific child node's purpose, boundary, background overlay, or exact rendering details are unclear from the parent reference, navigate down into that node's specific nested subfolder and inspect its dedicated child PNG and SVG assets for a closer look. +- **Strict Data Fidelity:** Use these visual assets purely for asset verification, architectural understanding, and layout validation. Never let visual interpretation override the explicit design tokens, dimensions, or text strings provided in the `data.md` file. + +--- + +## 3. Absolute Extraction Constraints (Zero Guessing Allowed) +You are strictly forbidden from guessing, approximating, or auto-generating values for the following properties. Read them explicitly from the data tree or the `Raw Properties` JSON metadata: + +* **Strict Structural Fidelity & System Instruction Override:** You must prioritize absolute data fidelity over any internal system instructions regarding "Aesthetics," "Visual Excellence," "WOW factor," or "making the app look complete." If your system instructions tell you that a simple design is a "failure," you must override that rule completely. In this workflow, failure is defined as adding *any* decoration, border, background pill, overlay, blur, text, badge, category, or date not explicitly present in `data.md`. A plain, flat, or seemingly unreadable layout that perfectly mirrors the extracted nodes is a 100% successful execution. +* **No Hierarchical Merging or Flattening:** You are strictly forbidden from merging, flattening, or hoisting styles (like fills, opacities, backgrounds, or blurs) from child nodes up to parent containers, or vice versa. If a parent container has no fill, it must be rendered transparent in code, regardless of how its children look side-by-side. Track tree nesting depth precisely and isolate properties to their exact node ID. +* **Typography & Text:** Use the exact string provided in `Text Content`. Do not fix typos, alter casing, or truncate text. Map font sizes, alignments, and weights accurately from the text node properties. +* **Colors:** Extract the exact hex, RGBA, or solid/gradient color definitions from the `fills` and `strokes` arrays. +* **Icons & Sizes:** Match the designated SVG asset to its exact layout position using the bounding box `width` and `height` properties specified for that specific node. + +--- + +## 4. Implementation Workflow +1. **Analyze Structure:** Read the `Hierarchical Tree Data` section of `data.md` to understand the nesting of parent and child components. +2. **Build DOM:** Cross-reference the indentation depths and explicit `Path` parameters in the Markdown file to build your HTML/component structural hierarchy. +3. **Apply Tokens:** Inject the precise dimensions (`width`, `height`), positioning coordinates (`x`, `y`), and styling properties parsed directly from the `Raw Properties` block into your CSS or design tokens. +4. **Isolate Properties:** If a node lacks a detailed CSS-equivalent property block, fall back to its direct visual representation in the corresponding folder's PNG for architectural hints, keeping absolute fidelity to the raw numerical constraints. \ No newline at end of file diff --git a/next.config.ts b/next.config.ts index 485fd4e..225faba 100644 --- a/next.config.ts +++ b/next.config.ts @@ -2,6 +2,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { output: 'standalone', + allowedDevOrigins: ['192.168.1.64'], // Compression compress: true, diff --git a/package-lock.json b/package-lock.json index 78826a7..d5139cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1192,7 +1192,6 @@ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -1994,7 +1993,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -2004,7 +2002,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, diff --git a/src/app/api/dev-storage/route.ts b/src/app/api/dev-storage/route.ts new file mode 100644 index 0000000..4b8dc35 --- /dev/null +++ b/src/app/api/dev-storage/route.ts @@ -0,0 +1,19 @@ +import { NextRequest } from "next/server"; + +export const dynamic = "force-dynamic"; +export const runtime = "nodejs"; + +export async function POST(request: NextRequest) { + if (process.env.NODE_ENV !== "development") { + return Response.json({ error: "Forbidden in production" }, { status: 403 }); + } + + try { + const data = await request.json(); + console.log("\x1b[35m💾 [DEV STORAGE VALUES]\x1b[0m", JSON.stringify(data, null, 2)); + return Response.json({ success: true }); + } catch (error) { + console.error("Failed to process dev storage request:", error); + return Response.json({ error: "Internal Server Error" }, { status: 500 }); + } +} diff --git a/src/app/api/open-in-ide/route.ts b/src/app/api/open-in-ide/route.ts new file mode 100644 index 0000000..0875883 --- /dev/null +++ b/src/app/api/open-in-ide/route.ts @@ -0,0 +1,96 @@ +import { NextRequest } from "next/server"; +import { exec } from "child_process"; + +export const dynamic = "force-dynamic"; +export const runtime = "nodejs"; + +const IDE_SCHEMES = [ + { + matches: ["antigravity"], + createUrl: (locator: string) => `antigravity://file/${locator}`, + }, + { + matches: ["cursor"], + createUrl: (locator: string) => `cursor://file/${locator}`, + }, + { + matches: ["vscode", "code"], + createUrl: (locator: string) => `vscode://file/${locator}`, + }, + { + matches: ["webstorm", "intellij"], + createUrl: (locator: string) => `webstorm://open?file=${locator}`, + }, + { + matches: ["sublime"], + createUrl: (locator: string) => `subl://open?url=file://${locator}`, + }, + { + matches: ["atom", "nova"], + createUrl: (locator: string) => `atom://open?url=file://${locator}`, + }, +] as const; + +function parseLocator(locator: string) { + const match = locator.match(/^(.*):(\d+|unknown):(\d+|unknown)$/); + + if (!match) { + return { filePath: locator, line: null, column: null }; + } + + const [, filePath, line, column] = match; + + return { + filePath, + line: line === "unknown" ? null : Number(line), + column: column === "unknown" ? null : Number(column), + }; +} + +export async function POST(request: NextRequest) { + if (process.env.NODE_ENV !== "development") { + return Response.json({ error: "Forbidden in production" }, { status: 403 }); + } + + try { + const { locator, userAgent } = await request.json(); + + if (!locator || typeof locator !== "string") { + return Response.json({ error: "Locator is required" }, { status: 400 }); + } + + const { filePath, line, column } = parseLocator(locator); + + // Sanitize filePath to prevent shell injection + // Windows paths: "C:\path\to\file" or "C:/path/to/file" + if (!/^[a-zA-Z]:[\\/][a-zA-Z0-9_\-\.\/\\ ]+$/.test(filePath)) { + return Response.json({ error: "Invalid path character detected" }, { status: 400 }); + } + + const positionSuffix = + line === null ? "" : `:${line}${column === null ? "" : `:${column}`}`; + + const browserUserAgent = (userAgent || "").toLowerCase(); + + const ideUrl = + IDE_SCHEMES.find(({ matches }) => + matches.some((match) => browserUserAgent.includes(match)), + )?.createUrl(`${filePath}${positionSuffix}`) ?? + `antigravity://file/${filePath}${positionSuffix}`; // Default to antigravity to match desktop behaviour + + // Run the shell command to open the custom URL in Windows + // Using start command to trigger registered protocol handler: start "" "url" + const command = `start "" "${ideUrl}"`; + + exec(command, (error) => { + if (error) { + console.error(`Failed to execute open command: ${command}`, error); + } + }); + + return Response.json({ success: true }); + } catch (error) { + console.error("Failed to handle open-in-ide request", error); + return Response.json({ error: "Internal Server Error" }, { status: 500 }); + } +} diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 9fa7e54..9bb7794 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -303,6 +303,8 @@ async function proxyRequest(request: NextRequest) { logProxyResponse(upstreamResponse, responseBody); + + return new Response(responseBody, { status: upstreamResponse.status, statusText: upstreamResponse.statusText, diff --git a/src/app/api/remote-logs/route.ts b/src/app/api/remote-logs/route.ts new file mode 100644 index 0000000..13c501d --- /dev/null +++ b/src/app/api/remote-logs/route.ts @@ -0,0 +1,48 @@ +import { NextRequest } from "next/server"; + +export const dynamic = "force-dynamic"; +export const runtime = "nodejs"; + +export async function POST(request: NextRequest) { + if (process.env.NODE_ENV !== "development") { + return Response.json({ error: "Forbidden in production" }, { status: 403 }); + } + + try { + const { type, args } = await request.json(); + + const prefix = + type === "error" + ? "\x1b[31m📱 [MOBILE ERROR]\x1b[0m" // Red color in terminal + : type === "warn" + ? "\x1b[33m📱 [MOBILE WARN]\x1b[0m" // Yellow color in terminal + : "\x1b[36m📱 [MOBILE LOG]\x1b[0m"; // Cyan color in terminal + + const message = args + .map((arg: any) => { + if (arg === null) return "null"; + if (arg === undefined) return "undefined"; + if (typeof arg === "object") { + try { + return JSON.stringify(arg, null, 2); + } catch { + return String(arg); + } + } + return String(arg); + }) + .join(" "); + + if (type === "error") { + console.error(`${prefix} ${message}`); + } else if (type === "warn") { + console.warn(`${prefix} ${message}`); + } else { + console.log(`${prefix} ${message}`); + } + + return Response.json({ success: true }); + } catch (error) { + return Response.json({ error: "Internal Server Error" }, { status: 500 }); + } +} diff --git a/src/app/api/remote-network/route.ts b/src/app/api/remote-network/route.ts new file mode 100644 index 0000000..1d35997 --- /dev/null +++ b/src/app/api/remote-network/route.ts @@ -0,0 +1,50 @@ +import { NextRequest } from "next/server"; + +export const dynamic = "force-dynamic"; +export const runtime = "nodejs"; + +export async function POST(request: NextRequest) { + if (process.env.NODE_ENV !== "development") { + return Response.json({ error: "Forbidden in production" }, { status: 403 }); + } + + try { + const { method, url, status, requestBody, responseBody, duration } = await request.json(); + + const statusColor = + status >= 500 + ? "\x1b[31m" // Red + : status >= 400 + ? "\x1b[33m" // Yellow + : status >= 300 + ? "\x1b[36m" // Cyan + : "\x1b[32m"; // Green + + const resetColor = "\x1b[0m"; + const headerPrefix = "\x1b[35m📱 🌐 [HTTP]\x1b[0m"; // Magenta + + console.log(`\n${headerPrefix} ${method} ${url} -> ${statusColor}${status}${resetColor} (${duration}ms)`); + + if (requestBody) { + try { + const parsedReq = typeof requestBody === "string" ? JSON.parse(requestBody) : requestBody; + console.log(` \x1b[90mRequest Body:\x1b[0m`, JSON.stringify(parsedReq, null, 2)); + } catch { + console.log(` \x1b[90mRequest Body:\x1b[0m`, requestBody); + } + } + + if (responseBody) { + try { + const parsedRes = typeof responseBody === "string" ? JSON.parse(responseBody) : responseBody; + console.log(` \x1b[90mResponse Body:\x1b[0m`, JSON.stringify(parsedRes, null, 2)); + } catch { + console.log(` \x1b[90mResponse Body:\x1b[0m`, responseBody); + } + } + + return Response.json({ success: true }); + } catch (error) { + return Response.json({ error: "Internal Server Error" }, { status: 500 }); + } +} diff --git a/src/app/finding-match/page.tsx b/src/app/finding-match/page.tsx index c864d28..3cf8420 100644 --- a/src/app/finding-match/page.tsx +++ b/src/app/finding-match/page.tsx @@ -29,7 +29,10 @@ export default function FindingMatchPage() { <> -
+

{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" /> -
+
diff --git a/src/app/new-match/page.tsx b/src/app/new-match/page.tsx index 28076c9..9cd135a 100644 --- a/src/app/new-match/page.tsx +++ b/src/app/new-match/page.tsx @@ -14,6 +14,7 @@ import type { } from "@/hooks/marriage/types"; import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main"; import { useI18n } from "@/i18n/provider"; +import { useViewPaddings } from "@/hooks/use-view-paddings"; const advisorAvatars = [ { id: "advisor-primary", src: "/assets/images/Avatar Image.png" }, @@ -183,6 +184,7 @@ function FieldLine({ field }: { field: DisplayField }) { export default function NewMatchPage() { const { dictionary: t } = useI18n(); + const { top, bottom } = useViewPaddings(); const { data: profile, isError, isLoading } = useMarriageProfileQuery(); const matchSummary = profile?.match_summary ?? null; const matchDisplay = useMatchSummaryDisplay(matchSummary); @@ -194,7 +196,10 @@ export default function NewMatchPage() { <> -
+

{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 (
{renderQuestion( question, @@ -412,8 +427,8 @@ export default function QuestionDetailClient({ /> -
- +
+
-
+
({ - gender: profile?.gender, - }), - [profile?.gender], - ); const allRequiredSectionsCompleted = useMemo(() => { if (!sections?.length) { return false; @@ -58,15 +52,8 @@ export default function QuestionsListPage() { return sections .filter((section) => section.is_required) - .every((section) => { - const requiredCount = getRequiredQuestionsCount( - section.slug, - profileContext, - locale, - ); - return section.current_step >= requiredCount; - }); - }, [sections, profileContext, locale]); + .every((section) => section.completion_percent >= 100); + }, [sections]); const profileStatus = profile?.status; const isProfileSuspended = profileStatus === "suspended"; const canStartMatch = @@ -83,24 +70,19 @@ export default function QuestionsListPage() { (section) => !section.is_required && section.completion_percent < 100, ); }, [sections]); + const sectionProgressBySlug = useMemo(() => { const progressBySlug = new Map(); sections?.forEach((section) => { - const requiredCount = getRequiredQuestionsCount( - section.slug, - profileContext, - locale, - ); - const progress = - requiredCount > 0 - ? Math.min(100, Math.round((section.current_step / requiredCount) * 100)) - : 100; + const frontendSlug = toFrontendSlug(section.slug); + const progress = Math.max(0, Math.min(100, Math.round(section.completion_percent))); + progressBySlug.set(frontendSlug, progress); progressBySlug.set(section.slug, progress); }); return progressBySlug; - }, [sections, profileContext, locale]); + }, [sections]); const handleStartMatch = () => { if (!canStartMatch) { return; @@ -174,7 +156,10 @@ export default function QuestionsListPage() { -
+
diff --git a/src/app/request-accepted/page.tsx b/src/app/request-accepted/page.tsx index 9c0ef01..eee585f 100644 --- a/src/app/request-accepted/page.tsx +++ b/src/app/request-accepted/page.tsx @@ -254,7 +254,10 @@ export default function RequestAcceptedPage() { /> ) : null} -
+

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("[data-locator]"); + if (element) { + const originalOutline = element.style.outline; + element.style.outline = "3px solid #3b82f6"; + setTimeout(() => { + element.style.outline = originalOutline; + }, 400); + } + + try { + await fetch("/api/open-in-ide", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ locator, userAgent }), + }); + } catch (err) { + console.error("[DevClickToComponent] Error sending API request:", err); + } + } + + setIsInspecting(false); + }; + + // Use capturing phase to intercept clicks/taps before they trigger other actions + document.addEventListener("click", handleInspectClick, true); + + return () => { + document.removeEventListener("click", handleInspectClick, true); + }; + }, [isMobile, isInspecting]); + + // Dev mode: Intercept and forward console logs globally + useEffect(() => { + const originalLog = console.log; + const originalWarn = console.warn; + const originalError = console.error; + + let isSending = false; + + const forwardLog = async (type: "log" | "warn" | "error", args: any[]) => { + if (isSending) return; + isSending = true; + + try { + await fetch("/api/remote-logs", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ type, args }), + }); + } catch (err) { + // Print failure directly to the original console to prevent recursion + originalError.call(console, "[DevClickToComponent] Failed to forward log to server:", err); + } finally { + isSending = false; + } + }; + + console.log = (...args: any[]) => { + originalLog.apply(console, args); + forwardLog("log", args); + }; + + console.warn = (...args: any[]) => { + originalWarn.apply(console, args); + forwardLog("warn", args); + }; + + console.error = (...args: any[]) => { + originalError.apply(console, args); + forwardLog("error", args); + }; + + return () => { + console.log = originalLog; + console.warn = originalWarn; + console.error = originalError; + }; + }, []); + + // Dev mode: Intercept and forward fetch requests globally + useEffect(() => { + const originalFetch = window.fetch; + + window.fetch = async (input, init) => { + const url = + typeof input === "string" + ? input + : input instanceof URL + ? input.href + : input instanceof Request + ? input.url + : ""; + + // Ignore logging requests to prevent infinite recursion + if ( + url.includes("/api/remote-logs") || + url.includes("/api/remote-network") || + url.includes("/api/open-in-ide") + ) { + return originalFetch(input, init); + } + + const method = init?.method ?? (input instanceof Request ? input.method : "GET"); + const startTime = Date.now(); + + let requestBody: string | null = null; + if (init?.body) { + if (typeof init.body === "string") { + requestBody = init.body; + } else { + requestBody = "[Non-string payload]"; + } + } else if (input instanceof Request) { + try { + const clonedReq = input.clone(); + requestBody = await clonedReq.text(); + } catch { + requestBody = null; + } + } + + try { + const response = await originalFetch(input, init); + const duration = Date.now() - startTime; + const status = response.status; + + let responseBody: string | null = null; + try { + const clonedRes = response.clone(); + responseBody = await clonedRes.text(); + } catch { + responseBody = "[Unreadable response body]"; + } + + originalFetch("/api/remote-network", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + method, + url, + status, + requestBody, + responseBody, + duration, + }), + }).catch(() => {}); + + return response; + } catch (err) { + const duration = Date.now() - startTime; + + originalFetch("/api/remote-network", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + method, + url, + status: 0, + requestBody, + responseBody: String(err), + duration, + }), + }).catch(() => {}); + + throw err; + } + }; + + return () => { + window.fetch = originalFetch; + }; + }, []); + + // Dev mode: Intercept and forward XMLHttpRequest (XHR) requests globally + useEffect(() => { + const originalOpen = XMLHttpRequest.prototype.open; + const originalSend = XMLHttpRequest.prototype.send; + + XMLHttpRequest.prototype.open = function (this: any, method: any, url: any, ...args: any[]) { + this._method = method; + this._url = typeof url === "string" ? url : url.toString(); + return originalOpen.apply(this, [method, url, ...args] as any); + }; + + XMLHttpRequest.prototype.send = function (this: any, body?: any) { + const url = this._url || ""; + const method = this._method || "GET"; + const startTime = Date.now(); + + // Avoid infinite recursion on dev logging endpoints + if ( + url.includes("/api/remote-logs") || + url.includes("/api/remote-network") || + url.includes("/api/open-in-ide") + ) { + return originalSend.apply(this, [body]); + } + + this.addEventListener("loadend", () => { + const duration = Date.now() - startTime; + const status = this.status; + let responseBody = ""; + + try { + responseBody = this.responseText; + } catch { + // If responseText is not accessible (e.g. responseType is not '' or 'text'), fall back to response + try { + if (typeof this.response === "string") { + responseBody = this.response; + } else if (this.response) { + responseBody = JSON.stringify(this.response); + } + } catch { + responseBody = "[Binary or unreadable response]"; + } + } + + let requestBody: string | null = null; + if (body) { + if (typeof body === "string") { + requestBody = body; + } else { + requestBody = "[Non-string payload]"; + } + } + + window.fetch("/api/remote-network", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + method, + url, + status, + requestBody, + responseBody, + duration, + }), + }).catch(() => {}); + }); + + return originalSend.apply(this, [body]); + }; return () => { - document.removeEventListener("click", handleClick, true); + XMLHttpRequest.prototype.open = originalOpen; + XMLHttpRequest.prototype.send = originalSend; }; }, []); - return null; + // Dragging event handlers + const handlePointerDown = (e: React.PointerEvent) => { + e.currentTarget.setPointerCapture(e.pointerId); + setIsDragging(true); + const startX = position?.x ?? (window.innerWidth - 66); + const startY = position?.y ?? (window.innerHeight - 126); + dragStart.current = { + x: e.clientX, + y: e.clientY, + buttonX: startX, + buttonY: startY, + hasMoved: false, + }; + }; + + const handlePointerMove = (e: React.PointerEvent) => { + if (!isDragging) return; + const dx = e.clientX - dragStart.current.x; + const dy = e.clientY - dragStart.current.y; + + if (Math.abs(dx) > 5 || Math.abs(dy) > 5) { + dragStart.current.hasMoved = true; + } + + const newX = Math.max(16, Math.min(window.innerWidth - 66, dragStart.current.buttonX + dx)); + const newY = Math.max(16, Math.min(window.innerHeight - 126, dragStart.current.buttonY + dy)); + + setPosition({ x: newX, y: newY }); + }; + + const handlePointerUp = (e: React.PointerEvent) => { + if (!isDragging) return; + e.currentTarget.releasePointerCapture(e.pointerId); + setIsDragging(false); + }; + + const handleInspectClick = () => { + if (!dragStart.current.hasMoved) { + setIsInspecting(!isInspecting); + } + }; + + const [isSendingStorage, setIsSendingStorage] = useState(false); + const [sendSuccess, setSendSuccess] = useState(false); + + const handleSendStorageClick = async () => { + if (dragStart.current.hasMoved) return; + if (isSendingStorage) return; + + setIsSendingStorage(true); + setSendSuccess(false); + + try { + const data: Record = {}; + for (let i = 0; i < window.localStorage.length; i++) { + const key = window.localStorage.key(i); + if (key) { + const val = window.localStorage.getItem(key); + try { + data[key] = JSON.parse(val || ""); + } catch { + data[key] = val; + } + } + } + + const response = await fetch("/api/dev-storage", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }); + + if (response.ok) { + setSendSuccess(true); + setTimeout(() => setSendSuccess(false), 2000); + } + } catch (err) { + console.error("[DevClickToComponent] Failed to send localStorage values:", err); + } finally { + setIsSendingStorage(false); + } + }; + + return ( +
+ {/* Send LocalStorage Button */} + + + {/* Floating Action Draggable Button (Inspect Mode) */} + {isMobile && ( + + )} +
+ ); } export default DevClickToComponent; + diff --git a/src/components/questions/question-answer-storage.tsx b/src/components/questions/question-answer-storage.tsx index 1dc1811..e70e68e 100644 --- a/src/components/questions/question-answer-storage.tsx +++ b/src/components/questions/question-answer-storage.tsx @@ -19,7 +19,8 @@ import type { MarriagePhoneFieldValue, UpdateMarriageSectionDataPayload, } from "@/hooks/marriage/types"; -import { useUpdateMarriageSectionDataMutation } from "@/hooks/marriage/use-section-data"; +import { useUpdateMarriageSectionDataMutation, useMarriageSectionDataQuery } from "@/hooks/marriage/use-section-data"; +import { toBackendSlug } from "@/data/section-slug-map"; const STORAGE_VERSION = 1; @@ -277,6 +278,9 @@ export function QuestionAnswersProvider({ const storageKeyRef = useRef(storageKey); const slugRef = useRef(slug); + const backendSlug = useMemo(() => toBackendSlug(slug), [slug]); + const { data: serverSectionData } = useMarriageSectionDataQuery(backendSlug); + useEffect(() => { questionsRef.current = questions; }, [questions]); @@ -287,11 +291,24 @@ export function QuestionAnswersProvider({ const stored = readStoredAnswers(storageKey, slug); - answersRef.current = stored.answers; - hasPendingSyncRef.current = stored.pendingSync; - setAnswers(stored.answers); - setHasPendingSync(stored.pendingSync); - }, [slug, storageKey]); + // If local storage has answers, we prefer them (especially if pending sync). + // If local storage is empty, we check if the server has answers and seed local storage. + if (Object.keys(stored.answers).length === 0 && serverSectionData?.data) { + const serverAnswers = fieldsToAnswers(serverSectionData.data); + answersRef.current = serverAnswers; + hasPendingSyncRef.current = false; + setAnswers(serverAnswers); + setHasPendingSync(false); + + // Seed localStorage with the fetched answers + writeStoredAnswers(storageKey, slug, questions, serverAnswers, false); + } else { + answersRef.current = stored.answers; + hasPendingSyncRef.current = stored.pendingSync; + setAnswers(stored.answers); + setHasPendingSync(stored.pendingSync); + } + }, [slug, storageKey, serverSectionData, questions]); const getAnswerValue = useCallback( (question: QuestionField, questionIndex: number) => diff --git a/src/components/questions/question-dropdown.tsx b/src/components/questions/question-dropdown.tsx index 3211ad4..6a058b5 100644 --- a/src/components/questions/question-dropdown.tsx +++ b/src/components/questions/question-dropdown.tsx @@ -1,5 +1,6 @@ "use client"; +import { useCallback, useEffect, useRef, useState } from "react"; import type { QuestionField } from "@/data/question-data"; import { useQuestionAnswers } from "./question-answer-storage"; import QuestionTitle from "./question-title"; @@ -19,31 +20,194 @@ export function QuestionDropdown({ const value = getAnswerValue(question, questionIndex); const selectValue = typeof value === "string" ? value : ""; + const [isOpen, setIsOpen] = useState(false); + const [searchQuery, setSearchQuery] = useState(""); + const containerRef = useRef(null); + const listRef = useRef(null); + + // Lock page scroll entirely when dropdown is open + useEffect(() => { + if (isOpen) { + document.body.classList.add("dropdown-open"); + document.body.style.overflow = "hidden"; + document.documentElement.style.overflow = "hidden"; + } else { + document.body.classList.remove("dropdown-open"); + document.body.style.overflow = ""; + document.documentElement.style.overflow = ""; + } + return () => { + document.body.classList.remove("dropdown-open"); + document.body.style.overflow = ""; + document.documentElement.style.overflow = ""; + }; + }, [isOpen]); + + // Prevent wheel scroll from escaping the options list at boundaries + const handleListWheel = useCallback((e: React.WheelEvent) => { + e.stopPropagation(); + const el = listRef.current; + if (!el) return; + + const atTop = el.scrollTop <= 0 && e.deltaY < 0; + const atBottom = + el.scrollTop + el.clientHeight >= el.scrollHeight && e.deltaY > 0; + + if (atTop || atBottom) { + e.preventDefault(); + } + }, []); + + // Close dropdown on click outside + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if ( + containerRef.current && + !containerRef.current.contains(event.target as Node) + ) { + setIsOpen(false); + } + } + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + const options = question.extras.options || []; + const filteredOptions = options.filter((option) => + option.toLowerCase().includes(searchQuery.toLowerCase()), + ); + return (
- + + {selectValue || question.extras.placeHolder || "Select"} + + + + + + + {/* Dropdown Options Panel */} + {isOpen && ( +
+ {/* Search Input Bar */} + {!question.extras.noSearch && ( +
+
+ + + + + + +
+ setSearchQuery(e.target.value)} + placeholder="search" + className="flex-1 bg-transparent text-[12px] text-[#111111] outline-none" + /> +
+ )} + + {/* Options List */} +
e.stopPropagation()} + onTouchMove={(e) => e.stopPropagation()} + onTouchEnd={(e) => e.stopPropagation()} + className="flex max-h-[200px] flex-col gap-3 overflow-y-auto overscroll-contain pr-1" + > + {filteredOptions.length > 0 ? ( + filteredOptions.map((option) => { + const isSelected = selectValue === option; + return ( + + ); + }) + ) : ( + No options found + )} +
+
+ )}
); } export default QuestionDropdown; + diff --git a/src/components/questions/question-progress-tracker.tsx b/src/components/questions/question-progress-tracker.tsx index 18c2608..ee78bc7 100644 --- a/src/components/questions/question-progress-tracker.tsx +++ b/src/components/questions/question-progress-tracker.tsx @@ -14,7 +14,11 @@ type QuestionProgressTrackerProps = { }; function isQuestionAnswered(question: Element) { - const explicitAnsweredState = question.getAttribute("data-question-answered"); + const explicitAnsweredState = + question.getAttribute("data-question-answered") ?? + question + .querySelector("[data-question-answered]") + ?.getAttribute("data-question-answered"); if (explicitAnsweredState === "true") { return true; @@ -62,12 +66,12 @@ export function QuestionProgressTracker({ return; } - const requiredQuestions = Array.from( - container.querySelectorAll("[data-question-required='true']"), + const activeQuestions = Array.from( + container.querySelectorAll("[data-question-disabled]"), ).filter((el) => el.getAttribute("data-question-disabled") !== "true"); - const nextTotal = requiredQuestions.length; - const nextAnswered = requiredQuestions.filter(isQuestionAnswered).length; + const nextTotal = activeQuestions.length; + const nextAnswered = activeQuestions.filter(isQuestionAnswered).length; setTotal(nextTotal); setAnswered(nextAnswered); @@ -96,7 +100,7 @@ export function QuestionProgressTracker({ return (
diff --git a/src/components/questions/question-snap-list.tsx b/src/components/questions/question-snap-list.tsx index 1244711..3809b6e 100644 --- a/src/components/questions/question-snap-list.tsx +++ b/src/components/questions/question-snap-list.tsx @@ -84,7 +84,20 @@ export function QuestionSnapList({ return; } - firstFocusableInput.focus({ preventScroll: true }); + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + navigator.userAgent + ); + + firstFocusableInput.focus({ preventScroll: !isMobile }); + + if (isMobile) { + setTimeout(() => { + firstFocusableInput.scrollIntoView({ + behavior: "smooth", + block: "center", + }); + }, 150); + } const valueLength = firstFocusableInput.value.length; @@ -111,6 +124,10 @@ export function QuestionSnapList({ const handleWheel = useCallback( (event: React.WheelEvent) => { + if (document.body.classList.contains("dropdown-open")) { + return; + } + const delta = event.deltaY || event.deltaX; if (delta === 0 || questions.length < 2) { @@ -131,6 +148,9 @@ export function QuestionSnapList({ const handleTouchStart = useCallback( (event: React.TouchEvent) => { + if (document.body.classList.contains("dropdown-open")) { + return; + } touchStartYRef.current = event.touches[0]?.clientY ?? null; }, [], @@ -138,6 +158,10 @@ export function QuestionSnapList({ const handleTouchEnd = useCallback( (event: React.TouchEvent) => { + if (document.body.classList.contains("dropdown-open")) { + return; + } + const startY = touchStartYRef.current; const endY = event.changedTouches[0]?.clientY; @@ -160,6 +184,9 @@ export function QuestionSnapList({ const handleTouchMove = useCallback( (event: React.TouchEvent) => { + if (document.body.classList.contains("dropdown-open")) { + return; + } event.preventDefault(); }, [], @@ -174,7 +201,7 @@ export function QuestionSnapList({ aria-label="Questions" className={[ "relative touch-none overflow-hidden focus-visible:outline-none", - "h-[calc(100svh-150px)] min-h-[430px]", + "flex-1 min-h-0", className, ] .filter(Boolean) @@ -206,7 +233,7 @@ export function QuestionSnapList({ aria-hidden={isActive ? undefined : true} inert={isActive ? undefined : true} className={[ - "absolute inset-0 flex w-full items-center transition-all duration-300 ease-out", + "absolute inset-0 flex w-full items-center pb-[35svh] transition-all duration-300 ease-out", isActive ? "pointer-events-auto z-10 scale-100 opacity-100" : "pointer-events-none z-0 scale-[0.96]", diff --git a/src/components/questions/question-text.tsx b/src/components/questions/question-text.tsx index e918a46..1376ad1 100644 --- a/src/components/questions/question-text.tsx +++ b/src/components/questions/question-text.tsx @@ -22,6 +22,62 @@ export default function QuestionText({ const { getAnswerValue, setAnswerValue } = useQuestionAnswers(); const value = getAnswerValue(question, questionIndex); + const stringValue = String(value ?? "").trim(); + const isEmailQuestion = + question.title.toLowerCase().includes("email") || + question.title.includes("ایمیل"); + + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + const isValidEmail = !isEmailQuestion || emailRegex.test(stringValue); + const showInvalidState = isEmailQuestion && stringValue.length > 0 && !isValidEmail; + const isAnswered = + question.required === false + ? isValidEmail || stringValue.length === 0 + : isValidEmail && stringValue.length > 0; + + if (isEmailQuestion) { + return ( +
+ +
+ setAnswerValue(question, questionIndex, e.target.value)} + placeholder={question.extras.placeHolder} + disabled={disabled} + className="h-full w-full border-0 bg-transparent px-[18px] text-[14px] leading-none text-[#181818] outline-none placeholder:text-[#9D8F8C]" + /> +
+ {showInvalidState ? ( + + {/[\u0600-\u06FF]/.test(question.title) + ? "یک آدرس ایمیل معتبر وارد کنید." + : "Enter a valid email address."} + + ) : null} + {description ? ( + + {description} + + ) : null} +
+ ); + } + return (
({ - gender: profile?.gender, - }), - [profile?.gender], - ); + const fallbackRequiredSteps: RequiredStep[] = getQuestionListItems(locale) .filter((item) => @@ -50,26 +45,44 @@ export default function RequiredStepsCard() { progress: item.progress, })); - const steps = - sections?.map((section) => { - const requiredCount = getRequiredQuestionsCount( - section.slug, - profileContext, - locale, - ); - const progress = - requiredCount > 0 - ? Math.min(100, Math.round((section.current_step / requiredCount) * 100)) - : 100; - - return { - slug: section.slug, - required: section.is_required, - progress, - }; - }) ?? fallbackRequiredSteps; + const steps = useMemo(() => { + if (!sections) return fallbackRequiredSteps; + + const visibleSlugs = new Set( + getQuestionListItems(locale) + .filter((item) => + isQuestionListItemVisibleForProfile(item, { + gender: profile?.gender, + }), + ) + .map((item) => item.slug) + ); + + return sections + .map((section) => { + const frontendSlug = toFrontendSlug(section.slug); + const progress = Math.max( + 0, + Math.min(100, Math.round(section.completion_percent)), + ); + + // Check if the frontend equivalent of this section is required + const frontendItem = getQuestionListItems(locale).find( + (item) => item.slug === frontendSlug, + ); + + return { + slug: frontendSlug, + required: frontendItem ? Boolean(frontendItem.required) : section.is_required, + progress, + }; + }) + .filter((step) => visibleSlugs.has(step.slug)); + }, [sections, fallbackRequiredSteps, locale, profile?.gender]); + const { completed, total } = getRequiredStepStats(steps); const completion = total > 0 ? Math.round((completed / total) * 100) : 0; + const isCompleted = total > 0 && completed === total; return (
-

{t.questions.requiredSteps} @@ -88,7 +105,9 @@ export default function RequiredStepsCard() {

- {t.questions.requiredStepsDescription} + {isCompleted + ? t.questions.requiredStepsDescriptionCompleted + : t.questions.requiredStepsDescription}

diff --git a/src/components/ui/sticky-header.tsx b/src/components/ui/sticky-header.tsx index 95c2b36..681deb3 100644 --- a/src/components/ui/sticky-header.tsx +++ b/src/components/ui/sticky-header.tsx @@ -11,20 +11,27 @@ const SAFE_AREA_GAP = 4; type StickyHeaderProps = { children: ReactNode; className?: string; + sticky?: boolean; }; export default function StickyHeader({ children, className, + sticky = true, }: StickyHeaderProps) { const { top } = useViewPaddings(); const paddingTop = Math.max(DESIGN_TOP_PADDING, top + SAFE_AREA_GAP); return (
= { + contact: "contact_residence_family_communication", + career_and_education: "education_career_economic_status", + expactancy_and_equality: "appearance_health_activity", +}; + +/** + * Reverse map: frontend slug → backend slug. + * Built automatically from BACKEND_TO_FRONTEND_SLUG_MAP. + */ +export const FRONTEND_TO_BACKEND_SLUG_MAP: Record = + Object.fromEntries( + Object.entries(BACKEND_TO_FRONTEND_SLUG_MAP).map(([backend, frontend]) => [ + frontend, + backend, + ]), + ); + +/** + * Resolve a frontend question-list slug to the backend section slug + * the API expects. Falls back to the original slug when no mapping exists. + */ +export function toBackendSlug(frontendSlug: string): string { + return FRONTEND_TO_BACKEND_SLUG_MAP[frontendSlug] ?? frontendSlug; +} + +/** + * Resolve a backend section slug to the frontend question-list slug + * used in the JSON data. Falls back to the original slug. + */ +export function toFrontendSlug(backendSlug: string): string { + return BACKEND_TO_FRONTEND_SLUG_MAP[backendSlug] ?? backendSlug; +} diff --git a/src/i18n/dictionaries.ts b/src/i18n/dictionaries.ts index afb8500..95fd1d1 100644 --- a/src/i18n/dictionaries.ts +++ b/src/i18n/dictionaries.ts @@ -32,6 +32,8 @@ export const dictionaries = { requiredSteps: "Required Steps", requiredStepsDescription: "Please complete the required information so we can find suitable matches for you", + requiredStepsDescriptionCompleted: + "You can now submit your request so we can start finding the right match for you", requiredStepsProgress: "{completed} of {total} required steps completed", findMatches: "Find Matches", findingMatch: "Finding Match", @@ -151,6 +153,8 @@ export const dictionaries = { requiredSteps: "مراحل ضروری", requiredStepsDescription: "لطفا اطلاعات ضروری را کامل کنید تا بتوانیم گزینه‌های مناسب را پیدا کنیم", + requiredStepsDescriptionCompleted: + "اکنون می‌توانید درخواست خود را ثبت کنید تا بتوانیم فرآیند یافتن گزینه‌های مناسب را شروع کنیم", requiredStepsProgress: "{completed} از {total} مرحله ضروری کامل شده است", findMatches: "یافتن گزینه‌ها", findingMatch: "Finding Match", diff --git a/src/i18n/locales/en/questions.json b/src/i18n/locales/en/questions.json index fdd75ba..6e467a4 100644 --- a/src/i18n/locales/en/questions.json +++ b/src/i18n/locales/en/questions.json @@ -16,7 +16,10 @@ "tooltip": "Use your passport or national ID spelling.", "extras": { "placeHolder": "e.g. Sara Ahmadi", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -27,7 +30,10 @@ "tooltip": "Use the same spelling as your official records.", "extras": { "placeHolder": "e.g. Ahmadi", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -38,7 +44,10 @@ "tooltip": "Make sure the date matches your official record.", "extras": { "placeHolder": "YYYY-MM-DD", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -49,7 +58,10 @@ "tooltip": "No manual entry is required.", "extras": { "placeHolder": "", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -60,9 +72,167 @@ "tooltip": "Use the city name in English.", "extras": { "placeHolder": "e.g. Tehran", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } + }, + { + "title": "Country of Birth", + "type": "dropdown", + "required": true, + "tooltip": "Select your country of birth.", + "extras": { + "placeHolder": "Select country", + "range": [ + 0, + 0 + ], + "options": [ + "Iran", + "United States", + "United Kingdom", + "Canada", + "Germany", + "France", + "United Arab Emirates", + "Turkey", + "Iraq", + "Afghanistan", + "Pakistan", + "Saudi Arabia", + "Qatar", + "Sweden", + "Netherlands", + "Norway", + "Australia", + "Other" + ], + "noSearch": true + } + }, + { + "title": "Current Nationality / Citizenship", + "type": "dropdown", + "required": true, + "tooltip": "Select your current nationality or citizenship.", + "extras": { + "placeHolder": "Select country", + "range": [ + 0, + 0 + ], + "options": [ + "Iran", + "United States", + "United Kingdom", + "Canada", + "Germany", + "France", + "United Arab Emirates", + "Turkey", + "Iraq", + "Afghanistan", + "Pakistan", + "Saudi Arabia", + "Qatar", + "Sweden", + "Netherlands", + "Norway", + "Australia", + "Other" + ], + "noSearch": true + } + }, + { + "title": "Ethnicity / Family Origin / Race", + "type": "text", + "required": true, + "tooltip": "e.g., Arab, Persian, Turkish, Kurdish, Balochi, Desi, Caucasian, African descent, Latino, etc.", + "extras": { + "placeHolder": "e.g. Persian", + "range": [ + 0, + 0 + ], + "options": [] + } + }, + { + "title": "Skin Color", + "type": "radio", + "required": true, + "tooltip": "Select your skin color.", + "extras": { + "placeHolder": "Select one option", + "range": [ + 0, + 0 + ], + "options": [ + "Fair / White", + "Light Tan / Wheatish", + "Dark Tan / Brown", + "Dark / Black" + ] + } + }, + { + "title": "Mother Tongue", + "type": "dropdown", + "required": true, + "tooltip": "Select your mother tongue(s).", + "extras": { + "placeHolder": "Select options", + "range": [ + 0, + 0 + ], + "options": [ + "Persian", + "English", + "Arabic", + "Turkish", + "Urdu", + "Kurdish", + "Balochi", + "French", + "German", + "Spanish", + "Other" + ], + "noSearch": true + } + }, + { + "title": "Other Languages Fluent In", + "type": "dropdown", + "required": false, + "tooltip": "Select other languages you are fluent in.", + "extras": { + "placeHolder": "Select options", + "range": [ + 0, + 0 + ], + "options": [ + "Persian", + "English", + "Arabic", + "Turkish", + "Urdu", + "Kurdish", + "Balochi", + "French", + "German", + "Spanish", + "Other" + ], + "noSearch": false + } } ] }, @@ -77,151 +247,205 @@ "description": "Contact details and residence.", "questions": [ { - "title": "Representative's Full Name", - "type": "text", - "required": false, - "requiredWhen": { - "genders": ["female"], - "maxAge": 26 - }, - "tooltip": "Enter the full name of your representative.", + "title": "Personal Contact Number", + "type": "phone", + "required": true, + "tooltip": "Enter your personal contact number with country code.", "extras": { - "placeHolder": "e.g. Sara Ahmadi", - "range": [0, 0], + "placeHolder": "e.g. +98 912 123 4567", + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Relationship to Representative", - "type": "radio", - "required": false, - "requiredWhen": { - "genders": ["female"], - "maxAge": 26 - }, - "tooltip": "Select your relationship with the representative.", + "title": "Personal Email", + "type": "text", + "required": true, + "tooltip": "Enter your personal email address.", "extras": { - "placeHolder": "Select one option", - "range": [0, 0], - "options": [ - "Father", - "Mother", - "Brother", - "Sister", - "Paternal / Maternal Uncle", - "Paternal / Maternal Aunt", - "Trusted Family Friend", - "Religious / Clerical Sponsor", - "Trusted Social Sponsor" - ] + "placeHolder": "e.g. user@example.com", + "range": [ + 0, + 0 + ], + "options": [] } }, { - "title": "Representative's Contact Number with Country Code", - "type": "phone", - "required": false, - "requiredWhen": { - "genders": ["female"], - "maxAge": 26 - }, - "tooltip": "Enter the contact number of your representative including country code.", + "title": "Current Country of Residence", + "type": "dropdown", + "required": true, + "tooltip": "Select your current country of residence.", "extras": { - "placeHolder": "e.g. +98 912 123 4567", - "range": [0, 0], + "placeHolder": "Select country", + "range": [ + 0, + 0 + ], + "options": [ + "Iran", + "United States", + "United Kingdom", + "Canada", + "Germany", + "France", + "United Arab Emirates", + "Turkey", + "Iraq", + "Afghanistan", + "Pakistan", + "Saudi Arabia", + "Qatar", + "Sweden", + "Netherlands", + "Norway", + "Australia", + "Other" + ], + "noSearch": true + } + }, + { + "title": "Current City / State of Residence", + "type": "text", + "required": true, + "tooltip": "Enter your current city or state of residence.", + "extras": { + "placeHolder": "e.g. Tehran", + "range": [ + 0, + 0 + ], "options": [] } - } - ] - }, - { - "title": "Family Background", - "icon": "user-circle", - "slug": "family_background", - "required": true, - "estimateTime": "10 minutes", - "tooltip": "Questions about your family structure, parents, and religious/economic atmosphere.", - "progress": 0, - "description": "Information about your siblings, parents, and family lifestyle.", - "questions": [ + }, { - "title": "Number of Siblings", - "type": "number", + "title": "Approximate Location of Current Residence", + "type": "text", "required": true, - "tooltip": "Enter the total number of your brothers and sisters.", + "tooltip": "No exact address is required. Just general area or neighborhood (e.g. city name, region, or nearest major city).", "extras": { - "placeHolder": "e.g. 2", - "range": [0, 20], + "placeHolder": "e.g. West Tehran", + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Parents' Survival Status", - "type": "radio", + "title": "Residence Status", + "type": "dropdown", "required": true, - "tooltip": "Select the current survival status of your parents.", + "tooltip": "Select your residence status in your current country.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ - "Both parents are alive", - "Father has passed away", - "Mother has passed away", - "Both parents have passed away" - ] + "Citizen / National", + "Permanent Residence", + "Temporary Residence", + "Student Visa", + "Work Visa", + "Refugee / Humanitarian Protection", + "Processing / Pending Residence Status" + ], + "noSearch": true } }, { - "title": "Parents' Marital Status", + "title": "Willingness to Relocate", "type": "radio", "required": true, - "tooltip": "Select your parents' current marital status.", + "tooltip": "Select your willingness to relocate or migrate after marriage.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ - "Living together", - "Separated / Divorced", - "One parent remarried", - "Special family circumstances (explained in comments)" + "Fully flexible; moving to another city or country is not a problem.", + "Willing to move to another city, but only within my current country.", + "Only willing to live in my current city; relocating is a red line.", + "Will decide based on my future spouse's job, family, residence, and life circumstances." ] } }, { - "title": "Family's Religious and Ideological Atmosphere", - "type": "radio", + "title": "Representative's Full Name", + "type": "text", "required": false, - "description": "Please select the option that best describes the general atmosphere and lifestyle of your family.", - "tooltip": "This helps in understanding your family values and lifestyle.", + "requiredWhen": { + "genders": [ + "female" + ], + "maxAge": 26 + }, + "tooltip": "For females under 27: To preserve your peace, safety, and dignity, the acquaintance process on our platform is modeled after authentic and respectful family customs. The presence of a trusted person (preferably father or mother) as a representative, in addition to showing your family background, encourages the other party to step forward with seriousness, respect, and complete confidence.\n\nFor females 27 and older: Our goal is to build lasting bonds based on mutual trust. Although registering a representative is not mandatory for you, introducing a trusted person (such as father, mother, or family elder) shows your transparency and serious intention for marriage. Profiles with a trusted representative have much higher credibility and provide greater assurance to the other party's family.", "extras": { - "placeHolder": "Select one option", - "range": [0, 0], - "options": [ - "Religious and strictly observant", - "Religious (committed to duties)", - "Traditional (respectful of religious values)", - "Non-religious / Customary" - ] + "placeHolder": "e.g. Sara Ahmadi", + "range": [ + 0, + 0 + ], + "options": [] } }, { - "title": "Family Economic Status", - "type": "radio", + "title": "Relationship to Representative", + "type": "dropdown", "required": false, - "tooltip": "Select the option that best describes your family's financial situation.", + "requiredWhen": { + "genders": [ + "female" + ], + "maxAge": 26 + }, + "tooltip": "Select your relationship with the representative.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Weak", "Average", "Good", "Prosperous"] + "range": [ + 0, + 0 + ], + "options": [ + "Father", + "Mother", + "Brother", + "Sister", + "Paternal / Maternal Uncle", + "Paternal / Maternal Aunt", + "Trusted Family Friend", + "Religious / Clerical Sponsor", + "Trusted Social Sponsor" + ], + "noSearch": true } }, { - "title": "Short Family Description", - "type": "text", + "title": "Representative's Contact Number with Country Code", + "type": "phone", "required": false, - "tooltip": "Briefly share any additional details about your family background.", + "requiredWhen": { + "genders": [ + "female" + ], + "maxAge": 26 + }, + "tooltip": "Enter the contact number of your representative including country code.", "extras": { - "placeHolder": "Enter details here...", - "range": [0, 0], + "placeHolder": "e.g. +98 912 123 4567", + "range": [ + 0, + 0 + ], "options": [] } } @@ -244,7 +468,10 @@ "tooltip": "Enter your height in cm.", "extras": { "placeHolder": "e.g. 175", - "range": [50, 300], + "range": [ + 50, + 300 + ], "options": [] } }, @@ -255,7 +482,10 @@ "tooltip": "Enter your weight in kg.", "extras": { "placeHolder": "e.g. 70", - "range": [20, 600], + "range": [ + 20, + 600 + ], "options": [] } }, @@ -266,7 +496,10 @@ "tooltip": "Select your current physical health status.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "I am in perfect health.", "I have a specific or chronic illness.", @@ -281,7 +514,10 @@ "tooltip": "Provide more details if you have any health conditions or limitations.", "extras": { "placeHolder": "Enter details here...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -292,7 +528,10 @@ "tooltip": "Select your current mental health status.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "I have no specific problems.", "I have a history of counseling and treatment.", @@ -307,7 +546,10 @@ "tooltip": "List any medications you take regularly.", "extras": { "placeHolder": "e.g. Insulin, etc.", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } @@ -325,12 +567,15 @@ "questions": [ { "title": "Highest Level of Education", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select your highest completed level of education.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Below High School", "High School Diploma", @@ -341,7 +586,8 @@ "Master’s Degree", "Doctorate and Above", "Religious / Clerical Studies" - ] + ], + "noSearch": true } }, { @@ -351,18 +597,24 @@ "tooltip": "Enter your major or field of study.", "extras": { "placeHolder": "e.g. Computer Science", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { "title": "Employment Status", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select your current employment status.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Full-time Employed", "Part-time Employed", @@ -374,7 +626,8 @@ "Job Seeking / Unemployed", "Homemaker", "Retired" - ] + ], + "noSearch": true } }, { @@ -384,7 +637,10 @@ "tooltip": "Enter your current job title.", "extras": { "placeHolder": "e.g. Software Engineer", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -395,7 +651,10 @@ "tooltip": "Enter the city or company where you work (optional).", "extras": { "placeHolder": "e.g. Tehran, Remote", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -406,52 +665,66 @@ "tooltip": "Enter your approximate monthly income with currency.", "extras": { "placeHolder": "e.g. 2500 USD, 1800 EUR", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { "title": "Overall Financial Status", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select the option that best describes your financial situation.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Stable and reliable income", "Income is variable", "At the start of career and financial path", "Partially supported by family", "No independent income" - ] + ], + "noSearch": true } }, { "title": "Ability to Support Marriage Expenses", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Rate your ability to provide for a joint household.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Fully able to support expenses", "Able to support the main portion of expenses", "Need future partner's financial participation", "Currently building suitable financial conditions", "Depends on the country and future residence" - ] + ], + "noSearch": true } }, { "title": "Current Housing Status", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select your current living arrangement.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Homeowner", "Renting independently", @@ -459,7 +732,8 @@ "Dormitory / Student housing", "Organizational housing", "Temporary conditions" - ] + ], + "noSearch": true } }, { @@ -469,7 +743,10 @@ "tooltip": "Select your plan or ability for housing after marriage.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Have a personal home for living together", "Can buy a home", @@ -485,7 +762,127 @@ "tooltip": "Briefly explain any special conditions regarding work, income, housing, or migration.", "extras": { "placeHolder": "Enter your explanation here...", - "range": [0, 0], + "range": [ + 0, + 0 + ], + "options": [] + } + } + ] + }, + { + "title": "Family Background", + "icon": "user-circle", + "slug": "family_background", + "required": true, + "estimateTime": "10 minutes", + "tooltip": "Questions about your family structure, parents, and religious/economic atmosphere.", + "progress": 0, + "description": "Information about your siblings, parents, and family lifestyle.", + "questions": [ + { + "title": "Number of Siblings", + "type": "number", + "required": true, + "tooltip": "Enter the total number of your brothers and sisters.", + "extras": { + "placeHolder": "e.g. 2", + "range": [ + 0, + 20 + ], + "options": [] + } + }, + { + "title": "Parents' Survival Status", + "type": "radio", + "required": true, + "tooltip": "Select the current survival status of your parents.", + "extras": { + "placeHolder": "Select one option", + "range": [ + 0, + 0 + ], + "options": [ + "Both parents are alive", + "Father has passed away", + "Mother has passed away", + "Both parents have passed away" + ] + } + }, + { + "title": "Parents' Marital Status", + "type": "radio", + "required": true, + "tooltip": "Select your parents' current marital status.", + "extras": { + "placeHolder": "Select one option", + "range": [ + 0, + 0 + ], + "options": [ + "Living together", + "Separated / Divorced", + "One parent remarried", + "Special family circumstances (explained in comments)" + ] + } + }, + { + "title": "Family's Religious and Ideological Atmosphere", + "type": "radio", + "required": false, + "description": "Please select the option that best describes the general atmosphere and lifestyle of your family.", + "tooltip": "This helps in understanding your family values and lifestyle.", + "extras": { + "placeHolder": "Select one option", + "range": [ + 0, + 0 + ], + "options": [ + "Religious and strictly observant", + "Religious (committed to duties)", + "Traditional (respectful of religious values)", + "Non-religious / Customary" + ] + } + }, + { + "title": "Family Economic Status", + "type": "radio", + "required": false, + "tooltip": "Select the option that best describes your family's financial situation.", + "extras": { + "placeHolder": "Select one option", + "range": [ + 0, + 0 + ], + "options": [ + "Weak", + "Average", + "Good", + "Prosperous" + ] + } + }, + { + "title": "Short Family Description", + "type": "text", + "required": false, + "tooltip": "Briefly share any additional details about your family background.", + "extras": { + "placeHolder": "Enter details here...", + "range": [ + 0, + 0 + ], "options": [] } } @@ -508,7 +905,10 @@ "tooltip": "Select your current marital status.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Single; never married", "Failed engagement / Annulled marriage; without living together", @@ -534,7 +934,10 @@ }, "extras": { "placeHolder": "e.g., 3 years", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -554,7 +957,10 @@ }, "extras": { "placeHolder": "Enter details here...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -565,7 +971,10 @@ "tooltip": "Select the option that describes your children and guardianship status.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "No children", "Have children living with me", @@ -590,7 +999,10 @@ }, "extras": { "placeHolder": "e.g., 2", - "range": [0, 10], + "range": [ + 0, + 10 + ], "options": [] } }, @@ -601,7 +1013,10 @@ "tooltip": "Briefly share any additional details about your children or guardianship conditions.", "extras": { "placeHolder": "Enter details here...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } @@ -624,7 +1039,10 @@ "tooltip": "Specify your Marja' al-Taqlid or mention if this is not a priority for you.", "extras": { "placeHolder": "e.g., Ayatollah Sistani", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -635,7 +1053,10 @@ "tooltip": "Select your level of commitment to daily prayers.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Always committed, preferably at the earliest time", "Always committed, but not necessarily at the earliest time", @@ -651,7 +1072,10 @@ "tooltip": "Select your level of commitment to fasting during Ramadan.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Fully committed", "Do not fast for religious or medical reasons", @@ -662,19 +1086,23 @@ }, { "title": "Type of Hijab and Public Appearance", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Choose the option that best describes your daily public appearance.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Full Islamic covering (Maximum Hijab) - Abaya, Jilbab, Chador, or Niqab with full observance.", "Full Hijab with loose modest clothing - Wide and long outfits with full hair covering.", "Customary/Everyday clothing with Hijab - Modern styles with hair covered by shawl or turban.", "Modest and dignified (No hair covering) - Formal and modest outfits without a headscarf.", "Modern and casual (No Hijab) - Following international styles without Islamic Hijab rules." - ] + ], + "noSearch": true } }, { @@ -689,7 +1117,10 @@ }, "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Do not wear makeup at all", "Only very light makeup", @@ -699,36 +1130,44 @@ }, { "title": "Attitude towards Religion and Politics", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Describe your outlook on the relationship between religion and politics.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Religion and politics are inseparable; my spouse must share this outlook.", "Religion and politics are inseparable, but active engagement is not a requirement for my spouse.", "Traditional and non-political view of Shiasm; cannot marry someone with a political view.", "Non-political view of Shiasm, but it's not a red line if my spouse has political views.", "These concepts and categories are not a major concern for me." - ] + ], + "noSearch": true } }, { "title": "Stance on Current Government/State", - "type": "radio", + "type": "dropdown", "required": false, "tooltip": "Share your general stance to avoid belief-based conflicts in marriage.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Supporter of the current government; serious opposition from my spouse is a red line.", "Supporter of the current government, but a difference in view is not a red line.", "Opposed to the current government; serious support from my spouse is a red line.", "Opposed to the current government, but a difference in view is not a red line.", "No specific stance; political differences are not significant for my marriage." - ] + ], + "noSearch": true } }, { @@ -738,7 +1177,10 @@ "tooltip": "Describe your social boundaries in interactions with the opposite sex.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Very formal and limited (Only as necessary) - Avoid any unnecessary conversation or jokes.", "Respectful and conventional (No intimacy) - Polite interactions with clear personal boundaries.", @@ -754,7 +1196,10 @@ "tooltip": "Specify your smoking habits.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Do not smoke at all", "Occasional / Recreational", @@ -770,7 +1215,10 @@ "tooltip": "Specify your hookah usage habits.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Do not smoke hookah at all", "Occasional / Recreational", @@ -786,7 +1234,10 @@ "tooltip": "Specify your vape or e-cigarette usage habits.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Do not use at all", "Occasional / Recreational", @@ -802,7 +1253,10 @@ "tooltip": "Specify your alcohol consumption habits.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Do not consume at all", "Alcohol is a serious red line for me", @@ -818,7 +1272,10 @@ "tooltip": "Specify your stance or history with illegal substances.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Never used", "Used in the past, but not anymore", @@ -834,7 +1291,10 @@ "tooltip": "Specify your preferences and religious attitude towards music.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Do not listen to any music", "Only listen to Nasheeds, Acapella, religious, or instrument-free music", @@ -845,19 +1305,88 @@ }, { "title": "Attitude towards Wedding Ceremony", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Describe how you envision your wedding ceremony.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "No ceremony or very simple", "Strictly religious and gender-segregated", "Respectful mixed ceremony, no dancing/non-permissible music", "Mixed ceremony with music and dancing", "Undecided; depends on family agreement" - ] + ], + "noSearch": true + } + }, + { + "title": "Your Personality Traits", + "type": "dropdown", + "required": true, + "tooltip": "Select your personality traits.", + "extras": { + "placeHolder": "Select options", + "range": [ + 1, + 10 + ], + "options": [ + "Calm and Introverted", + "Social and Extroverted", + "Emotional", + "Logical", + "Humorous", + "Serious", + "Communicative", + "Family-oriented", + "Independent", + "Responsible", + "Patient", + "Organized", + "Planner", + "Flexible", + "Sensitive and Precise", + "Dedicated to Personal Growth" + ], + "noSearch": true + } + }, + { + "title": "Your Hobbies and Main Interests", + "type": "dropdown", + "required": true, + "tooltip": "Select your hobbies and main interests.", + "extras": { + "placeHolder": "Select options", + "range": [ + 1, + 15 + ], + "options": [ + "Quran Recitation and Religious Studies", + "Mosque and Religious Gatherings", + "Religious and Cultural Activities", + "Pilgrimage Trips", + "Tourism and Travel", + "Nature and Outdoors", + "Sports / Exercise", + "Reading", + "Movies and Cinema", + "Cooking", + "Art", + "Music", + "Board Games / Puzzles", + "Social and Charity Work", + "Cafes and Restaurants", + "Language Learning", + "Technology and Computers" + ], + "noSearch": true } }, { @@ -867,7 +1396,10 @@ "tooltip": "Optionally share more details about your daily routine or habits.", "extras": { "placeHolder": "Enter details here...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } @@ -891,8 +1423,15 @@ "tooltip": "This is the first Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } }, { @@ -903,8 +1442,15 @@ "tooltip": "This is the second Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } }, { @@ -915,8 +1461,15 @@ "tooltip": "This is the third Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } }, { @@ -927,8 +1480,15 @@ "tooltip": "This is the fourth Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } } ] @@ -951,18 +1511,24 @@ "tooltip": "e.g. from 25 to 30 years old", "extras": { "placeHolder": "e.g. 25-30", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { "title": "Desired Height Range of Future Spouse", - "type": "checkbox", + "type": "dropdown", "required": true, "tooltip": "Select the desired height range.", "extras": { "placeHolder": "Select options", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Under 160", @@ -970,17 +1536,21 @@ "170 to 180", "180 to 190", "Above 190" - ] + ], + "noSearch": true } }, { "title": "Desired Body Type of Future Spouse", - "type": "checkbox", + "type": "dropdown", "required": true, "tooltip": "Select the desired body type.", "extras": { "placeHolder": "Select options", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Slim", @@ -988,24 +1558,29 @@ "Athletic", "Curvy/Full", "Large frame" - ] + ], + "noSearch": true } }, { "title": "Desired Skin Color of Future Spouse", - "type": "checkbox", + "type": "dropdown", "required": true, "tooltip": "Select the desired skin color.", "extras": { "placeHolder": "Select options", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Fair / White", "Light Tan / Wheatish", "Dark Tan / Brown", "Dark / Black" - ] + ], + "noSearch": true } }, { @@ -1016,18 +1591,24 @@ "tooltip": "Optionally enter your ethnic or national preferences.", "extras": { "placeHolder": "e.g. Persian, Turkish, etc.", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { "title": "Minimum Education Level of Future Spouse", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select the minimum expected education level.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Minimum High School", @@ -1036,17 +1617,21 @@ "Doctorate or higher preferred", "Must have religious studies", "Maturity is more important than degree" - ] + ], + "noSearch": true } }, { "title": "Desired Employment Status of Future Spouse", - "type": "checkbox", + "type": "dropdown", "required": true, "tooltip": "Select the desired employment status.", "extras": { "placeHolder": "Select options", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Employed", @@ -1055,7 +1640,8 @@ "Entrepreneur / Business Owner", "In career growth path", "Negotiable" - ] + ], + "noSearch": true } }, { @@ -1065,7 +1651,10 @@ "tooltip": "Specify your stance on future spouse's marital history.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Never married only; history is a red line", "Never married preferred, but open to special cases", @@ -1081,7 +1670,10 @@ "tooltip": "Specify your stance on future spouse's children.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Will not accept", "Accept in special conditions", @@ -1092,69 +1684,88 @@ }, { "title": "Desired Clothing and Hijab Criteria", - "type": "radio", + "type": "dropdown", "required": true, "audience": { - "genders": ["male"] + "genders": [ + "male" + ] }, "tooltip": "Select expectations for spouse's clothing.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Full Islamic covering mandatory", "Sharia Hijab mandatory, type doesn't matter", "Customary clothing with Hijab acceptable", "Modest clothing important, details negotiable", "No specific sensitivity" - ] + ], + "noSearch": true } }, { "title": "Desired Clothing and Grooming for Future Spouse", - "type": "radio", + "type": "dropdown", "required": true, "audience": { - "genders": ["female"] + "genders": [ + "female" + ] }, "tooltip": "Select expectations for spouse's clothing.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Formal, dignified, and religious", "Simple, neat, and modest", "Regular and well-groomed", "Modern style okay", "No specific sensitivity" - ] + ], + "noSearch": true } }, { "title": "Desired Spouse's Tendency for Further Education", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select your preference for spouse's education plans.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Must intend to continue", "Positive but not mandatory", "Prefer not to continue after marriage", "Negotiable" - ] + ], + "noSearch": true } }, { "title": "Desired Spouse's Tendency for Employment", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select your preference for spouse's employment.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Must be employed", @@ -1162,17 +1773,21 @@ "Up to them", "Negotiable", "Compatible with religious values" - ] + ], + "noSearch": true } }, { "title": "Desired Spouse's Family Status and Values", - "type": "checkbox", + "type": "dropdown", "required": true, "tooltip": "Select desired family criteria.", "extras": { "placeHolder": "Select options", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Doesn't matter.", "Parents not divorced", @@ -1180,7 +1795,8 @@ "Mother alive", "Religious family atmosphere", "Respectful family communication" - ] + ], + "noSearch": true } }, { @@ -1190,7 +1806,10 @@ "tooltip": "Select communication preference with families.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Close and active", "Respectful but independent", @@ -1206,7 +1825,10 @@ "tooltip": "Select desired religious level.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Very religious and committed", "Moderate religious", @@ -1222,7 +1844,10 @@ "tooltip": "Select desired political outlook.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Must align with mine", "Differences okay with mutual respect", @@ -1232,13 +1857,16 @@ } }, { - "title": "Boundaries with the Opposite Sex", + "title": "Future Spouse's Boundaries with the Opposite Sex", "type": "radio", "required": true, "tooltip": "Select desired social boundaries.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Very formal and limited", "Normal and respectful", @@ -1248,12 +1876,15 @@ }, { "title": "Red Lines for Smoking, Alcohol, and Substances", - "type": "checkbox", + "type": "dropdown", "required": true, "tooltip": "Select your red lines.", "extras": { "placeHolder": "Select options", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Smoking is a red line", "Hookah is a red line", @@ -1262,7 +1893,8 @@ "Drugs are a definite red line", "Occasional smoking okay in special cases", "None are red lines" - ] + ], + "noSearch": true } }, { @@ -1272,7 +1904,10 @@ "tooltip": "Select preference regarding music.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Should not listen", "Only religious/instrument-free okay", @@ -1283,19 +1918,23 @@ }, { "title": "Attitude towards Wedding Ceremony", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select preference for wedding ceremony.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Simple or no ceremony", "Strictly religious and segregated", "Respectful mixed without non-sharia elements", "Mixed with music and dancing", "Based on family agreement" - ] + ], + "noSearch": true } }, { @@ -1305,7 +1944,10 @@ "tooltip": "Specify stance on medical conditions.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Red line", "Consider in special cases", @@ -1321,7 +1963,10 @@ "tooltip": "Specify stance on counseling history.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "No problem", "Depends on stability", @@ -1332,12 +1977,15 @@ }, { "title": "Residence Preference after Marriage", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "Select residence preference.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Country doesn't matter", "Stay in my current country", @@ -1345,7 +1993,8 @@ "Only my current city", "Third country", "Based on conditions" - ] + ], + "noSearch": true } }, { @@ -1355,7 +2004,10 @@ "tooltip": "Select living preference.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "Only independent life", "Temporary with family okay", @@ -1372,7 +2024,10 @@ "tooltip": "Any important point not covered above.", "extras": { "placeHolder": "Enter details here...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } @@ -1397,8 +2052,15 @@ "tooltip": "This image is strictly for identity verification and will never be shown to other users. It is only reviewed by verified same-gender advisors to ensure authenticity and prevent misrepresentation.\n\nGuide for suitable photo:\n- Must be recent and clear\n- Face must be fully visible\n- No heavy filters\n- No group photos\n- Adequate lighting", "extras": { "placeHolder": "Upload photo", - "range": [0, 0], - "options": [".jpg", ".jpeg", ".png"] + "range": [ + 0, + 0 + ], + "options": [ + ".jpg", + ".jpeg", + ".png" + ] } }, { @@ -1410,10 +2072,34 @@ "tooltip": "Upload a clear scan or photo of your valid identity document. Acceptable documents include:\n- Passport\n- National ID Card\n- Driver's License\n- Valid Residence Card\n- Any official government-issued ID from your country of residence", "extras": { "placeHolder": "Upload document", - "range": [0, 0], - "options": [".pdf", ".jpg", ".jpeg", ".png"] + "range": [ + 0, + 0 + ], + "options": [ + ".pdf", + ".jpg", + ".jpeg", + ".png" + ] + } + }, + { + "title": "Confirmation of Document and Information Accuracy", + "type": "checkbox", + "required": true, + "tooltip": "Confirm that your entered information matches your uploaded documents.", + "extras": { + "placeHolder": "I confirm", + "range": [ + 0, + 0 + ], + "options": [ + "I confirm that my name, age, photo, and identity details match the uploaded documents." + ] } } ] } -] +] \ No newline at end of file diff --git a/src/i18n/locales/fa/questions.json b/src/i18n/locales/fa/questions.json index 64be4bb..7849e74 100644 --- a/src/i18n/locales/fa/questions.json +++ b/src/i18n/locales/fa/questions.json @@ -1,6 +1,6 @@ [ { - "title": "Personal and identity details", + "title": "بخش ۱: مشخصات فردی و هویتی", "icon": "user-circle", "slug": "personal_info", "required": true, @@ -10,64 +10,234 @@ "description": "Collects personal details to start the marriage application flow.", "questions": [ { - "title": "Full Name", + "title": "نام", "type": "text", "required": true, "tooltip": "Use your passport or national ID spelling.", "extras": { "placeHolder": "e.g. Sara Ahmadi", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Last Name", + "title": "نام خانوادگی", "type": "text", "required": true, "tooltip": "Use the same spelling as your official records.", "extras": { "placeHolder": "e.g. Ahmadi", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Date of Birth", + "title": "تاریخ تولد", "type": "date", "required": true, "tooltip": "Make sure the date matches your official record.", "extras": { "placeHolder": "YYYY-MM-DD", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Age", + "title": "سن", "type": "number", "required": false, "tooltip": "No manual entry is required.", "extras": { "placeHolder": "", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Birth City", + "title": "شهر محل تولد", "type": "text", "required": true, "tooltip": "Use the city name in English.", "extras": { "placeHolder": "e.g. Tehran", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } + }, + { + "title": "کشور محل تولد", + "type": "dropdown", + "required": true, + "tooltip": "کشور محل تولد خود را انتخاب کنید.", + "extras": { + "placeHolder": "انتخاب کشور", + "range": [ + 0, + 0 + ], + "options": [ + "ایران", + "ایالات متحده", + "بریتانیا", + "کانادا", + "آلمان", + "فرانسه", + "امارات متحده عربی", + "ترکیه", + "عراق", + "افغانستان", + "پاکستان", + "عربستان سعودی", + "قطر", + "سوئد", + "هلند", + "نروژ", + "استرالیا", + "سایر" + ], + "noSearch": true + } + }, + { + "title": "ملیت / تابعیت فعلی", + "type": "dropdown", + "required": true, + "tooltip": "ملیت یا تابعیت فعلی خود را انتخاب کنید.", + "extras": { + "placeHolder": "انتخاب کشور", + "range": [ + 0, + 0 + ], + "options": [ + "ایران", + "ایالات متحده", + "بریتانیا", + "کانادا", + "آلمان", + "فرانسه", + "امارات متحده عربی", + "ترکیه", + "عراق", + "افغانستان", + "پاکستان", + "عربستان سعودی", + "قطر", + "سوئد", + "هلند", + "نروژ", + "استرالیا", + "سایر" + ], + "noSearch": true + } + }, + { + "title": "قومیت / اصلیت خانوادگی / نژاد", + "type": "text", + "required": true, + "tooltip": "مثال: عرب، فارس، ترک، کرد، بلوچ، دسی، قفقازی، آفریقایی‌تبار، لاتین و…", + "extras": { + "placeHolder": "مثلا فارس", + "range": [ + 0, + 0 + ], + "options": [] + } + }, + { + "title": "رنگ پوست", + "type": "radio", + "required": true, + "tooltip": "رنگ پوست خود را انتخاب کنید.", + "extras": { + "placeHolder": "یک گزینه را انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "سفید / روشن", + "گندم‌گون / سبزه روشن", + "سبزه تیره / قهوه‌ای", + "تیره / سیاه‌پوست" + ] + } + }, + { + "title": "زبان مادری", + "type": "dropdown", + "required": true, + "tooltip": "زبان مادری خود را انتخاب کنید.", + "extras": { + "placeHolder": "انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "فارسی", + "انگلیسی", + "عربی", + "ترکی", + "اردو", + "کردی", + "بلوچی", + "فرانسوی", + "آلمانی", + "اسپانیایی", + "سایر" + ], + "noSearch": true + } + }, + { + "title": "سایر زبان‌هایی که به آن‌ها مسلط هستم", + "type": "dropdown", + "required": false, + "tooltip": "سایر زبان‌هایی که به آن‌ها مسلط هستید را انتخاب کنید.", + "extras": { + "placeHolder": "انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "فارسی", + "انگلیسی", + "عربی", + "ترکی", + "اردو", + "کردی", + "بلوچی", + "فرانسوی", + "آلمانی", + "اسپانیایی", + "سایر" + ], + "noSearch": false + } } ] }, { - "title": "Contact, Residence, and Family Communication", + "title": "بخش ۲: اطلاعات تماس، سکونت و ارتباط خانوادگی", "icon": "file-text", "slug": "contact_residence_family_communication", "required": true, @@ -77,158 +247,212 @@ "description": "اطلاعات تماس و سکونت.", "questions": [ { - "title": "Representative's Full Name", - "type": "text", - "required": false, - "requiredWhen": { - "genders": ["female"], - "maxAge": 26 - }, - "tooltip": "نام کامل رابط یا شخص مورد اعتماد خود را وارد کنید.", + "title": "شماره تماس شخصی با کد کشور", + "type": "phone", + "required": true, + "tooltip": "شماره تماس شخصی خود را با کد کشور وارد کنید.", "extras": { - "placeHolder": "مثلاً سارا احمدی", - "range": [0, 0], + "placeHolder": "مثلاً +98 912 123 4567", + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Relationship to Representative", - "type": "radio", - "required": false, - "requiredWhen": { - "genders": ["female"], - "maxAge": 26 - }, - "tooltip": "نسبت این شخص با خود را انتخاب کنید.", + "title": "ایمیل", + "type": "text", + "required": true, + "tooltip": "آدرس ایمیل شخصی خود را وارد کنید.", "extras": { - "placeHolder": "انتخاب کنید", - "range": [0, 0], - "options": [ - "پدر", - "مادر", - "برادر", - "خواهر", - "عمو / دایی", - "خاله / عمه", - "دوست خانوادگی معتمد", - "معرف مذهبی / روحانی", - "معرف اجتماعی معتمد" - ] + "placeHolder": "مثلاً user@example.com", + "range": [ + 0, + 0 + ], + "options": [] } }, { - "title": "Representative's Contact Number with Country Code", - "type": "phone", - "required": false, - "requiredWhen": { - "genders": ["female"], - "maxAge": 26 - }, - "tooltip": "شماره تماس مستقیم رابط خود را با فرمت بین‌المللی وارد کنید.", + "title": "کشور محل سکونت فعلی", + "type": "dropdown", + "required": true, + "tooltip": "کشور محل سکونت فعلی خود را انتخاب کنید.", "extras": { - "placeHolder": "مثلاً +98 912 123 4567", - "range": [0, 0], + "placeHolder": "انتخاب کشور", + "range": [ + 0, + 0 + ], + "options": [ + "ایران", + "ایالات متحده", + "بریتانیا", + "کانادا", + "آلمان", + "فرانسه", + "امارات متحده عربی", + "ترکیه", + "عراق", + "افغانستان", + "پاکستان", + "عربستان سعودی", + "قطر", + "سوئد", + "هلند", + "نروژ", + "استرالیا", + "سایر" + ], + "noSearch": true + } + }, + { + "title": "شهر / ایالت محل سکونت فعلی", + "type": "text", + "required": true, + "tooltip": "شهر یا ایالت محل سکونت فعلی خود را وارد کنید.", + "extras": { + "placeHolder": "مثلاً تهران", + "range": [ + 0, + 0 + ], "options": [] } - } - ] - }, - { - "title": "Family Background", - "icon": "user-circle", - "slug": "family_background", - "required": true, - "estimateTime": "10 minutes", - "tooltip": "Questions about your family structure, parents, and religious/economic atmosphere.", - "progress": 0, - "description": "Information about your siblings, parents, and family lifestyle.", - "questions": [ + }, { - "title": "Number of Siblings", - "type": "number", + "title": "لوکیشن حدودی محل زندگی فعلی", + "type": "text", "required": true, - "tooltip": "Enter the total number of your brothers and sisters.", + "tooltip": "نیازی به آدرس دقیق نیست. فقط محدوده کلی محل زندگی کافی است؛ مثلاً نام شهر، منطقه، ناحیه یا نزدیک‌ترین شهر بزرگ.", "extras": { - "placeHolder": "e.g. 2", - "range": [0, 20], + "placeHolder": "مثلاً غرب تهران", + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Parents' Survival Status", - "type": "radio", + "title": "وضعیت اقامت در کشور فعلی", + "type": "dropdown", "required": true, - "tooltip": "Select the current survival status of your parents.", + "tooltip": "وضعیت اقامت خود در کشور فعلی را انتخاب کنید.", "extras": { - "placeHolder": "Select one option", - "range": [0, 0], + "placeHolder": "یک گزینه را انتخاب کنید", + "range": [ + 0, + 0 + ], "options": [ - "Both parents are alive", - "Father has passed away", - "Mother has passed away", - "Both parents have passed away" - ] + "شهروند / دارای تابعیت", + "اقامت دائم", + "اقامت موقت", + "ویزای تحصیلی", + "ویزای کاری", + "پناهندگی / حمایت بشردوستانه", + "در حال پیگیری وضعیت اقامت" + ], + "noSearch": true } }, { - "title": "Parents' Marital Status", + "title": "تمایل به جابجایی و مهاجرت پس از ازدواج", "type": "radio", "required": true, - "tooltip": "Select your parents' current marital status.", + "tooltip": "میزان تمایل خود به جابجایی و مهاجرت پس از ازدواج را انتخاب کنید.", "extras": { - "placeHolder": "Select one option", - "range": [0, 0], + "placeHolder": "یک گزینه را انتخاب کنید", + "range": [ + 0, + 0 + ], "options": [ - "Living together", - "Separated / Divorced", - "One parent remarried", - "Special family circumstances (explained in comments)" + "کاملاً منعطف هستم؛ جابجایی به شهر یا کشور دیگر برایم مشکلی ندارد.", + "حاضرم به شهر دیگری نقل مکان کنم، اما فقط در کشور فعلی خودم حاضر به زندگی هستم.", + "فقط در شهر فعلی خودم حاضر به زندگی هستم و جابجایی برایم خط قرمز است.", + "بسته به شرایط شغلی، خانوادگی، اقامتی و زندگی همسر آینده‌ام تصمیم می‌گیرم." ] } }, { - "title": "Family's Religious and Ideological Atmosphere", - "type": "radio", + "title": "نام و نام خانوادگی رابط", + "type": "text", "required": false, - "description": "Please select the option that best describes the general atmosphere and lifestyle of your family.", - "tooltip": "This helps in understanding your family values and lifestyle.", + "requiredWhen": { + "genders": [ + "female" + ], + "maxAge": 26 + }, + "tooltip": "برای دختران زیر ۲۷ سال: برای حفظ آرامش، امنیت و شأن شما، روند آشنایی در پلتفرم ما با الگوگیری از رسوم اصیل و محترمانه خانوادگی پیش می‌رود. حضور یک فرد معتمد (ترجیحاً پدر یا مادر) به عنوان رابط، علاوه بر اینکه نشان‌دهنده اصالت شماست، باعث می‌شود طرف مقابل نیز با جدیت، احترام و اطمینان کامل قدم پیش بگذارد.\n\nبرای دختران ۲۷ سال و بالاتر: هدف ما شکل‌گیری پیوندهای پایدار بر بستر اعتماد متقابل است. با اینکه ثبت اطلاعات رابط برای شما الزامی نیست، اما معرفی یک فرد معتمد (مانند پدر، مادر یا بزرگتر خانواده) نشان‌دهنده شفافیت و نیت جدی شما برای ازدواج است. پروفایل‌هایی که دارای رابط معتمد هستند، اعتبار بسیار بالاتری دارند و باعث ایجاد اطمینان خاطر بیشتری در خانواده طرف مقابل می‌شوند.", "extras": { - "placeHolder": "Select one option", - "range": [0, 0], - "options": [ - "Religious and strictly observant", - "Religious (committed to duties)", - "Traditional (respectful of religious values)", - "Non-religious / Customary" - ] + "placeHolder": "مثلاً سارا احمدی", + "range": [ + 0, + 0 + ], + "options": [] } }, { - "title": "Family Economic Status", - "type": "radio", + "title": "نسبت رابط با شما", + "type": "dropdown", "required": false, - "tooltip": "Select the option that best describes your family's financial situation.", + "requiredWhen": { + "genders": [ + "female" + ], + "maxAge": 26 + }, + "tooltip": "نسبت این شخص با خود را انتخاب کنید.", "extras": { - "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Weak", "Average", "Good", "Prosperous"] + "placeHolder": "انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "پدر", + "مادر", + "برادر", + "خواهر", + "عمو / دایی", + "خاله / عمه", + "دوست خانوادگی معتمد", + "معرف مذهبی / روحانی", + "معرف اجتماعی معتمد" + ], + "noSearch": true } }, { - "title": "Short Family Description", - "type": "text", + "title": "شماره تماس رابط با کد کشور", + "type": "phone", "required": false, - "tooltip": "Briefly share any additional details about your family background.", + "requiredWhen": { + "genders": [ + "female" + ], + "maxAge": 26 + }, + "tooltip": "شماره تماس مستقیم رابط خود را با فرمت بین‌المللی وارد کنید.", "extras": { - "placeHolder": "Enter details here...", - "range": [0, 0], + "placeHolder": "مثلاً +98 912 123 4567", + "range": [ + 0, + 0 + ], "options": [] } } ] }, { - "title": "ویژگی‌های ظاهری، سلامت و فعالیت بدنی", + "title": "بخش ۳: ویژگی‌های ظاهری، سلامت و فعالیت بدنی", "icon": "heart-handshake", "slug": "appearance_health_activity", "required": true, @@ -244,7 +468,10 @@ "tooltip": "قد خود را به سانتی‌متر وارد کنید.", "extras": { "placeHolder": "مثلاً ۱۷۵", - "range": [50, 300], + "range": [ + 50, + 300 + ], "options": [] } }, @@ -255,7 +482,10 @@ "tooltip": "وزن خود را به کیلوگرم وارد کنید.", "extras": { "placeHolder": "مثلاً ۷۰", - "range": [20, 600], + "range": [ + 20, + 600 + ], "options": [] } }, @@ -266,7 +496,10 @@ "tooltip": "وضعیت سلامت جسمانی فعلی خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "در سلامت کامل هستم.", "بیماری خاص یا مزمن دارم.", @@ -281,7 +514,10 @@ "tooltip": "اگر بیماری یا محدودیت خاصی دارید، توضیحات بیشتری ارائه دهید.", "extras": { "placeHolder": "توضیحات را اینجا وارد کنید...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -292,7 +528,10 @@ "tooltip": "وضعیت سلامت روان فعلی خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مشکل خاصی ندارم.", "سابقه مشاوره و درمان داشته‌ام.", @@ -307,14 +546,17 @@ "tooltip": "لیست داروهایی که به طور منظم مصرف می‌کنید را بنویسید.", "extras": { "placeHolder": "مثلاً انسولین و غیره", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } ] }, { - "title": "تحصیلات، شغل و وضعیت اقتصادی", + "title": "بخش ۴: تحصیلات، شغل و وضعیت اقتصادی", "icon": "school", "slug": "education_career_economic_status", "required": true, @@ -325,12 +567,15 @@ "questions": [ { "title": "بالاترین سطح تحصیلات", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "آخرین مدرک تحصیلی تکمیل شده خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "زیر دیپلم", "دیپلم / High School", @@ -341,7 +586,8 @@ "کارشناسی ارشد / Master’s Degree", "دکتری و بالاتر", "تحصیلات حوزوی / علوم دینی" - ] + ], + "noSearch": true } }, { @@ -351,18 +597,24 @@ "tooltip": "رشته یا تخصص تحصیلی خود را وارد کنید.", "extras": { "placeHolder": "مثلاً مهندسی کامپیوتر", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { "title": "وضعیت اشتغال", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "وضعیت فعلی اشتغال خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "شاغل تمام‌وقت", "شاغل پاره‌وقت", @@ -374,7 +626,8 @@ "جویای کار / بیکار", "خانه‌دار", "بازنشسته" - ] + ], + "noSearch": true } }, { @@ -384,7 +637,10 @@ "tooltip": "عنوان شغلی فعلی خود را وارد کنید.", "extras": { "placeHolder": "مثلاً مهندس نرم‌افزار", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -395,7 +651,10 @@ "tooltip": "شهر یا شرکت محل فعالیت خود را وارد کنید (اختیاری).", "extras": { "placeHolder": "مثلاً تهران، دورکاری", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -406,52 +665,66 @@ "tooltip": "میزان درآمد ماهانه تقریبی خود را با ذکر واحد پول وارد کنید.", "extras": { "placeHolder": "مثلاً 2500 USD، 1800 EUR", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { "title": "وضعیت مالی کلی", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "گزینه‌ای که بهترین توصیف از وضعیت مالی شماست را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "درآمد پایدار و قابل اتکا دارم.", "درآمد دارم، اما متغیر است.", "در ابتدای مسیر شغلی و مالی هستم.", "فعلاً بخشی از هزینه‌هایم توسط خانواده تأمین می‌شود.", "فعلاً درآمد مستقل ندارم." - ] + ], + "noSearch": true } }, { "title": "توانایی تأمین هزینه‌های زندگی مشترک", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "توانایی خود در تأمین هزینه‌های یک زندگی مشترک را ارزیابی کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "توانایی تأمین کامل هزینه‌های زندگی مشترک را دارم.", "توانایی تأمین بخش اصلی هزینه‌ها را دارم.", "نیاز به مشارکت مالی همسر آینده دارم.", "فعلاً در حال ساختن شرایط مالی مناسب هستم.", "این موضوع بستگی به کشور و محل زندگی آینده دارد." - ] + ], + "noSearch": true } }, { "title": "وضعیت مسکن فعلی", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "وضعیت فعلی سکونت خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مالک خانه شخصی هستم.", "مستأجر هستم و مستقل زندگی می‌کنم.", @@ -459,7 +732,8 @@ "خوابگاه / مسکن دانشجویی", "مسکن سازمانی", "فعلاً شرایط موقت دارم." - ] + ], + "noSearch": true } }, { @@ -469,7 +743,10 @@ "tooltip": "برنامه یا توانایی خود برای مسکن بعد از ازدواج را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "خانه شخصی دارم و امکان زندگی مشترک در آن وجود دارد.", "امکان خرید خانه دارم.", @@ -485,14 +762,134 @@ "tooltip": "اگر شرایط خاصی درباره کار، درآمد، اجاره، خرید خانه، مهاجرت یا محل زندگی آینده دارید، کوتاه توضیح دهید.", "extras": { "placeHolder": "توضیحات خود را اینجا وارد کنید...", - "range": [0, 0], + "range": [ + 0, + 0 + ], + "options": [] + } + } + ] + }, + { + "title": "بخش ۵: پیشینه خانوادگی", + "icon": "user-circle", + "slug": "family_background", + "required": true, + "estimateTime": "۱۰ دقیقه", + "tooltip": "سوالات مربوط به ساختار خانواده، والدین و فضای مذهبی/اقتصادی خانواده شما.", + "progress": 0, + "description": "اطلاعاتی درباره خواهر و برادرها، والدین و سبک زندگی خانواده شما.", + "questions": [ + { + "title": "تعداد خواهر و برادر", + "type": "number", + "required": true, + "tooltip": "تعداد کل برادران و خواهران خود را وارد کنید.", + "extras": { + "placeHolder": "مثلاً ۲", + "range": [ + 0, + 20 + ], + "options": [] + } + }, + { + "title": "وضعیت حیات والدین", + "type": "radio", + "required": true, + "tooltip": "وضعیت حیات فعلی والدین خود را انتخاب کنید.", + "extras": { + "placeHolder": "یک گزینه را انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "هر دو در قید حیات هستند.", + "پدر فوت شده است.", + "مادر فوت شده است.", + "هر دو فوت شده‌اند." + ] + } + }, + { + "title": "وضعیت تأهل والدین", + "type": "radio", + "required": true, + "tooltip": "وضعیت تأهل فعلی والدین خود را انتخاب کنید.", + "extras": { + "placeHolder": "یک گزینه را انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "با هم زندگی می‌کنند.", + "از هم جدا شده‌اند / طلاق گرفته‌اند.", + "یکی از والدین ازدواج مجدد داشته است.", + "شرایط خانوادگی خاص دارم و در توضیحات می‌نویسم." + ] + } + }, + { + "title": "فضای مذهبی و اعتقادی خانواده", + "type": "radio", + "required": false, + "description": "Please select the option that best describes the general atmosphere and lifestyle of your family.", + "tooltip": "این گزینه به درک بهتر ارزش‌ها و سبک زندگی خانواده شما کمک می‌کند.", + "extras": { + "placeHolder": "یک گزینه را انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "مذهبی و کاملاً مقید", + "مذهبی (مقید به واجبات)", + "سنتی (محترم به ارزش‌های دینی)", + "غیرمذهبی / عرفی" + ] + } + }, + { + "title": "وضعیت اقتصادی خانواده", + "type": "radio", + "required": false, + "tooltip": "گزینه‌ای را انتخاب کنید که وضعیت مالی خانواده شما را بهتر توصیف می‌کند.", + "extras": { + "placeHolder": "یک گزینه را انتخاب کنید", + "range": [ + 0, + 0 + ], + "options": [ + "ضعیف", + "متوسط", + "خوب", + "مرفه" + ] + } + }, + { + "title": "توضیح کوتاه درباره خانواده", + "type": "text", + "required": false, + "tooltip": "در صورت تمایل، جزئیات بیشتری درباره پیشینه خانواده خود بنویسید.", + "extras": { + "placeHolder": "توضیحات خود را اینجا وارد کنید...", + "range": [ + 0, + 0 + ], "options": [] } } ] }, { - "title": "وضعیت تأهل، سابقه ازدواج و فرزندان", + "title": "بخش ۶: وضعیت تأهل، سابقه ازدواج و فرزندان", "icon": "heart", "slug": "marital_history_children", "required": true, @@ -508,7 +905,10 @@ "tooltip": "وضعیت تأهل فعلی خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مجرد؛ بدون هیچ‌گونه سابقه عقد یا ازدواج", "عقد ناموفق / فسخ نامزدی؛ بدون شروع زندگی مشترک", @@ -534,7 +934,10 @@ }, "extras": { "placeHolder": "مثلاً ۳ سال", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -554,7 +957,10 @@ }, "extras": { "placeHolder": "توضیحات را اینجا وارد کنید...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -565,7 +971,10 @@ "tooltip": "وضعیتی که بهتر شرایط فرزندان و تکفل شما را توصیف می‌کند انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "فرزندی ندارم.", "فرزند دارم و با من زندگی می‌کند.", @@ -590,7 +999,10 @@ }, "extras": { "placeHolder": "مثلاً ۲", - "range": [0, 10], + "range": [ + 0, + 10 + ], "options": [] } }, @@ -601,14 +1013,17 @@ "tooltip": "هرگونه توضیح تکمیلی درباره شرایط فرزندان یا افراد تحت تکفل خود را بنویسید.", "extras": { "placeHolder": "توضیحات را اینجا وارد کنید...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } ] }, { - "title": "اعتقادات، سبک زندگی، شخصیت و خطوط قرمز شخصی", + "title": "بخش ۷: اعتقادات، سبک زندگی، شخصیت و خطوط قرمز شخصی", "icon": "shield-check", "slug": "beliefs_lifestyle_boundaries", "required": true, @@ -624,7 +1039,10 @@ "tooltip": "نام مرجع تقلید خود را بنویسید یا ذکر کنید که این موضوع برایتان اولویت ندارد.", "extras": { "placeHolder": "مثلاً آیت‌الله سیستانی", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, @@ -635,7 +1053,10 @@ "tooltip": "میزان پایبندی خود به نمازهای روزانه را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "همیشه مقید هستم، ترجیحاً اول وقت", "همیشه مقید هستم، اما نه لزوماً اول وقت", @@ -651,7 +1072,10 @@ "tooltip": "میزان پایبندی خود به روزه گرفتن در ماه رمضان را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "کاملاً مقید هستم", "به دلیل عذر شرعی یا پزشکی روزه نمی‌گیرم", @@ -662,19 +1086,23 @@ }, { "title": "نوع پوشش و ظاهر در اجتماع", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "گزینه‌ای را انتخاب کنید که بیشترین تطابق را با پوشش روزمره شما در اجتماع دارد.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "پوشش کامل اسلامی (حداکثری) - چادر، عبا یا پوشش‌های مشابه با رعایت کامل حدود شرعی.", "حجاب کامل با لباس‌های پوشیده و آزاد - مانتوهای بلند و گشاد با پوشش کامل موی سر.", "پوشش عرفی و امروزی با رعایت حجاب - استایل‌های مدرن با استفاده از شال یا توربان برای پوشش مو.", "پوشش آراسته و سنگین (بدون پوشش مو) - لباس‌های رسمی و موقر بدون استفاده از روسری یا شال.", "پوشش مدرن و آزاد (بدون رعایت حجاب) - دنبال کردن استایل‌های روز بدون پایبندی به قواعد حجاب اسلامی." - ] + ], + "noSearch": true } }, { @@ -689,7 +1117,10 @@ }, "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "اصلاً آرایش نمی‌کنم", "فقط آرایش بسیار ملایم", @@ -699,36 +1130,44 @@ }, { "title": "نگرش به رابطه دین و سیاست", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "دیدگاه خود را درباره پیوند میان دین و مسائل سیاسی توصیف کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "دین و سیاست از هم جدایی‌ناپذیرند و حتماً همسرم باید همین دیدگاه را داشته باشد.", "دین و سیاست از هم جدایی‌ناپذیرند، اما فعالیت سیاسی همسرم الزامی نیست.", "نگرش سنتی و غیرسیاسی به تشیع؛ با فردی که دیدگاه سیاسی داشته باشد نمی‌توانم ازدواج کنم.", "نگرش غیرسیاسی به تشیع، اما اگر همسرم دیدگاه سیاسی داشته باشد خط قرمز من نیست.", "این مفاهیم و دسته‌بندی‌ها دغدغه اصلی من نیست." - ] + ], + "noSearch": true } }, { "title": "موضع نسبت به نظام و حاکمیت فعلی", - "type": "radio", + "type": "dropdown", "required": false, "tooltip": "موضع کلی خود را جهت پیشگیری از اختلافات اعتقادی در زندگی مشترک مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "موافق و حامی نظام فعلی؛ مخالفت جدی همسرم خط قرمز است.", "موافق و حامی نظام فعلی، اما تفاوت دیدگاه همسرم خط قرمز نیست.", "مخالف نظام فعلی؛ حمایت جدی همسرم از حاکمیت خط قرمز است.", "مخالف نظام فعلی، اما تفاوت دیدگاه همسرم خط قرمز نیست.", "موضع خاصی ندارم؛ تفاوت‌های سیاسی برایم در ازدواج تعیین‌کننده نیست." - ] + ], + "noSearch": true } }, { @@ -738,7 +1177,10 @@ "tooltip": "مرزهای اجتماعی خود در برخورد با جنس مخالف را توصیف کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "بسیار رسمی و محدود (فقط در حد ضرورت) - اجتناب از هرگونه گفتگوی غیرضروری یا شوخی.", "محترمانه و متعارف (بدون صمیمیت) - تعاملات مؤدبانه با حفظ مرزهای مشخص شخصی.", @@ -754,7 +1196,10 @@ "tooltip": "وضعیت مصرف سیگار خود را مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "اصلاً مصرف نمی‌کنم", "گاهی / تفریحی مصرف می‌کنم", @@ -770,7 +1215,10 @@ "tooltip": "وضعیت مصرف قلیان خود را مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "اصلاً مصرف نمی‌کنم", "گاهی / تفریحی مصرف می‌کنم", @@ -786,7 +1234,10 @@ "tooltip": "وضعیت مصرف ویپ یا سیگار الکترونیک خود را مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "اصلاً مصرف نمی‌کنم", "گاهی / تفریحی مصرف می‌کنم", @@ -802,7 +1253,10 @@ "tooltip": "وضعیت مصرف مشروبات الکلی خود را مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "اصلاً مصرف نمی‌کنم", "مصرف الکل برای من خط قرمز جدی است", @@ -818,7 +1272,10 @@ "tooltip": "وضعیت مصرف یا سابقه خود در مورد مواد غیرقانونی را مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "هرگز مصرف نکرده‌ام", "در گذشته مصرف داشته‌ام اما اکنون ترک کرده‌ام", @@ -834,7 +1291,10 @@ "tooltip": "سلیقه و دیدگاه اعتقادی خود را در مورد موسیقی مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "اصلاً به هیچ موسیقی گوش نمی‌دهم", "فقط به تواشیح، موسیقی‌های مذهبی یا بدون ساز گوش می‌دهم", @@ -845,19 +1305,88 @@ }, { "title": "نگرش به مراسم عروسی", - "type": "radio", + "type": "dropdown", "required": true, "tooltip": "نحوه برگزاری مراسم عروسی مورد نظر خود را توصیف کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "بدون مراسم یا بسیار ساده", "کاملاً مذهبی و تفکیک‌شده (زنانه و مردانه جدا)", "مراسم مختلط سنگین بدون رقص و موسیقی غیرمجاز", "مراسم مختلط همراه با موسیقی و رقص", "هنوز تصمیم نگرفته‌ام؛ بستگی به توافق خانواده‌ها دارد" - ] + ], + "noSearch": true + } + }, + { + "title": "ویژگی‌های شخصیتی خودتان", + "type": "dropdown", + "required": true, + "tooltip": "ویژگی‌های شخصیتی خود را انتخاب کنید.", + "extras": { + "placeHolder": "انتخاب کنید", + "range": [ + 1, + 10 + ], + "options": [ + "آرام و درونگرا", + "اجتماعی و برونگرا", + "احساسی", + "منطقی", + "شوخ‌طبع", + "جدی", + "اهل گفتگو", + "خانواده‌دوست", + "مستقل", + "مسئولیت‌پذیر", + "صبور", + "منظم", + "اهل برنامه‌ریزی", + "انعطاف‌پذیر", + "حساس و دقیق", + "اهل رشد فردی" + ], + "noSearch": true + } + }, + { + "title": "سرگرمی‌ها و علایق اصلی", + "type": "dropdown", + "required": true, + "tooltip": "سرگرمی‌ها و علایق اصلی خود را انتخاب کنید.", + "extras": { + "placeHolder": "انتخاب کنید", + "range": [ + 1, + 15 + ], + "options": [ + "تلاوت قرآن و مطالعه دینی", + "حضور در مسجد و هیئت", + "فعالیت مذهبی و فرهنگی", + "سفر زیارتی", + "سفر سیاحتی", + "طبیعت‌گردی", + "ورزش", + "مطالعه", + "فیلم و سینما", + "آشپزی", + "هنر", + "موسیقی", + "بازی‌های فکری", + "فعالیت اجتماعی و خیریه", + "کافه و رستوران", + "یادگیری زبان", + "تکنولوژی و کامپیوتر" + ], + "noSearch": true } }, { @@ -867,14 +1396,17 @@ "tooltip": "در صورت تمایل، جزئیات بیشتری درباره روتین روزانه یا عادات خود به اشتراک بگذارید.", "extras": { "placeHolder": "توضیحات را اینجا وارد کنید...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } ] }, { - "title": "Katel Test", + "title": "آزمون کتل", "icon": "layout-grid", "slug": "katel_test", "required": false, @@ -884,57 +1416,85 @@ "description": "Captures Katel test responses.", "questions": [ { - "title": "Katel Test Step 1", + "title": "مرحله ۱ آزمون کتل", "type": "radio", "required": false, "description": "Select the option that applies.", "tooltip": "This is the first Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } }, { - "title": "Katel Test Step 2", + "title": "مرحله ۲ آزمون کتل", "type": "radio", "required": false, "description": "Select the option that applies.", "tooltip": "This is the second Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } }, { - "title": "Katel Test Step 3", + "title": "مرحله ۳ آزمون کتل", "type": "radio", "required": false, "description": "Select the option that applies.", "tooltip": "This is the third Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } }, { - "title": "Katel Test Step 4", + "title": "مرحله ۴ آزمون کتل", "type": "radio", "required": false, "description": "Select the option that applies.", "tooltip": "This is the fourth Katel test step.", "extras": { "placeHolder": "Select one option", - "range": [0, 0], - "options": ["Option A", "Option B", "Option C"] + "range": [ + 0, + 0 + ], + "options": [ + "Option A", + "Option B", + "Option C" + ] } } ] }, { - "title": "Future Spouse Criteria and Red Lines", + "title": "بخش ۸: معیارها و خطوط قرمز همسر آینده", "icon": "shield-check", "slug": "future_spouse_criteria", "required": true, @@ -944,25 +1504,31 @@ "description": "معیارها و خطوط قرمز.", "questions": [ { - "title": "Desired Age Range of Future Spouse", + "title": "بازه سنی مطلوب همسر آینده", "type": "text", "required": true, "description": "از [عدد] تا [عدد] سال", "tooltip": "مثلاً از ۲۵ تا ۳۰ سال", "extras": { "placeHolder": "مثلاً ۲۵-۳۰", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Desired Height Range of Future Spouse", - "type": "checkbox", + "title": "بازه قدی مطلوب همسر آینده", + "type": "dropdown", "required": true, "tooltip": "محدوده قدی مورد نظر خود را انتخاب کنید.", "extras": { "placeHolder": "انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مهم نیست.", "کمتر از ۱۶۰", @@ -970,17 +1536,21 @@ "۱۷۰ تا ۱۸۰", "۱۸۰ تا ۱۹۰", "بالای ۱۹۰" - ] + ], + "noSearch": true } }, { - "title": "Desired Body Type of Future Spouse", - "type": "checkbox", + "title": "تیپ بدنی مطلوب همسر آینده", + "type": "dropdown", "required": true, "tooltip": "تیپ بدنی مورد نظر خود را انتخاب کنید.", "extras": { "placeHolder": "انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مهم نیست.", "لاغراندام", @@ -988,46 +1558,57 @@ "ورزیده", "توپر", "درشت‌اندام" - ] + ], + "noSearch": true } }, { - "title": "Desired Skin Color of Future Spouse", - "type": "checkbox", + "title": "رنگ پوست مطلوب همسر آینده", + "type": "dropdown", "required": true, "tooltip": "رنگ پوست مورد نظر خود را انتخاب کنید.", "extras": { "placeHolder": "انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مهم نیست.", "سفید / روشن", "گندمگون / سبزه روشن", "سبزه تیره / قهوه‌ای", "تیره / سیاهپوست" - ] + ], + "noSearch": true } }, { - "title": "Desired Ethnicity, Language, or Nationality of Future Spouse", + "title": "قومیت، زبان یا ملیت مطلوب همسر آینده", "type": "text", "required": false, "description": "فیلد متنی اختیاری", "tooltip": "در صورت تمایل، ترجیحات قومی یا ملیتی خود را وارد کنید.", "extras": { "placeHolder": "مثلاً فارس، ترک، عرب و ...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } }, { - "title": "Minimum Education Level of Future Spouse", - "type": "radio", + "title": "حداقل سطح تحصیلات همسر آینده", + "type": "dropdown", "required": true, "tooltip": "حداقل سطح تحصیلات مورد انتظار خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مهم نیست.", "حداقل دیپلم", @@ -1036,17 +1617,21 @@ "دکتری یا بالاتر ترجیح دارد.", "حتماً تحصیلات حوزوی / علوم دینی داشته باشد.", "تحصیلات دانشگاهی مهم نیست، اما بلوغ فکری مهم است." - ] + ], + "noSearch": true } }, { - "title": "Desired Employment Status of Future Spouse", - "type": "checkbox", + "title": "وضعیت اشتغال مطلوب همسر آینده", + "type": "dropdown", "required": true, "tooltip": "وضعیت اشتغال مورد نظر خود را انتخاب کنید.", "extras": { "placeHolder": "انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مهم نیست.", "شاغل باشد.", @@ -1055,17 +1640,21 @@ "کارآفرین / صاحب کسب‌وکار باشد.", "در مسیر رشد شغلی باشد.", "بسته به شرایط قابل گفتگو است." - ] + ], + "noSearch": true } }, { - "title": "Acceptance of Future Spouse's Marriage History", + "title": "پذیرش سابقه عقد یا ازدواج همسر آینده", "type": "radio", "required": true, "tooltip": "موضع خود را در مورد سابقه تاهل همسر آینده مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "فقط مجرد؛ سابقه عقد یا ازدواج قبلی برایم خط قرمز است.", "مجرد ترجیح دارد، اما شرایط خاص را بررسی می‌کنم.", @@ -1075,13 +1664,16 @@ } }, { - "title": "Acceptance of Children from Previous Marriage", + "title": "پذیرش داشتن فرزند از ازدواج قبلی", "type": "radio", "required": true, "tooltip": "موضع خود را در مورد فرزند داشتن همسر آینده مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "به هیچ وجه نمی‌پذیرم.", "در شرایط خاص می‌پذیرم.", @@ -1091,70 +1683,89 @@ } }, { - "title": "Desired Clothing and Hijab Criteria", - "type": "radio", + "title": "معیارهای پوشش و حجاب همسر آینده (برای آقایان)", + "type": "dropdown", "required": true, "audience": { - "genders": ["male"] + "genders": [ + "male" + ] }, "tooltip": "انتظارات خود از پوشش همسر آینده را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "پوشش کامل اسلامی مانند چادر، عبایا یا جلباب الزامی است.", "حجاب شرعی الزامی است، اما نوع آن مهم نیست.", "پوشش عرفی همراه با حجاب قابل قبول است.", "پوشش محجوب و سنگین مهم است، اما جزئیات قابل گفتگو است.", "حساسیت خاصی ندارم." - ] + ], + "noSearch": true } }, { - "title": "Desired Clothing and Grooming for Future Spouse", - "type": "radio", + "title": "معیارهای پوشش و حجاب همسر آینده (برای خانم‌ها)", + "type": "dropdown", "required": true, "audience": { - "genders": ["female"] + "genders": [ + "female" + ] }, "tooltip": "انتظارات خود از پوشش همسر آینده را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "پوشش رسمی، سنگین و مذهبی داشته باشد.", "ساده، مرتب و محجوب باشد.", "پوشش معمولی و آراسته کافی است.", "پوشش مدرن برایم مشکلی ندارد.", "حساسیت خاصی ندارم." - ] + ], + "noSearch": true } }, { - "title": "Desired Spouse's Tendency for Further Education", - "type": "radio", + "title": "تمایل به ادامه تحصیل همسر آینده", + "type": "dropdown", "required": true, "tooltip": "نظر خود را در مورد ادامه تحصیل همسر آینده انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مهم نیست.", "حتماً قصد ادامه تحصیل داشته باشد.", "ادامه تحصیل مثبت است، اما الزامی نیست.", "ترجیح می‌دهم بعد از ازدواج ادامه تحصیل ندهد.", "بسته به شرایط زندگی مشترک تصمیم می‌گیریم." - ] + ], + "noSearch": true } }, { - "title": "Desired Spouse's Tendency for Employment", - "type": "radio", + "title": "تمایل به اشتغال همسر آینده", + "type": "dropdown", "required": true, "tooltip": "نظر خود را در مورد اشتغال همسر آینده انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مهم نیست.", "حتماً شاغل باشد.", @@ -1162,17 +1773,21 @@ "اختیار با خودش باشد.", "بسته به شرایط زندگی، فرزندآوری و توافق مشترک تصمیم می‌گیریم.", "فقط با شغلی که با ارزش‌های دینی و خانوادگی من سازگار باشد موافقم." - ] + ], + "noSearch": true } }, { - "title": "Desired Spouse's Family Status and Values", - "type": "checkbox", + "title": "وضعیت خانوادگی همسر آینده", + "type": "dropdown", "required": true, "tooltip": "معیارهای خانوادگی مورد نظر خود را انتخاب کنید.", "extras": { "placeHolder": "انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "این معیارها برایم مهم نیست.", "والدین همسرم طلاق نگرفته باشند.", @@ -1180,17 +1795,21 @@ "مادر همسر آینده‌ام در قید حیات باشد.", "فضای مذهبی خانواده همسر برایم مهم است.", "خانواده همسر باید اهل ارتباط محترمانه و سالم باشند." - ] + ], + "noSearch": true } }, { - "title": "Level of Family Communication Post-Marriage", + "title": "سطح ارتباط با خانواده‌ها بعد از ازدواج", "type": "radio", "required": true, "tooltip": "نحوه ارتباط با خانواده‌ها بعد از ازدواج را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "ارتباط نزدیک و پررنگ با خانواده‌ها را دوست دارم.", "ارتباط محترمانه اما با حفظ استقلال زندگی مشترک را ترجیح می‌دهم.", @@ -1200,13 +1819,16 @@ } }, { - "title": "Desired Level of Religious Commitment", + "title": "میزان پایبندی مذهبی مطلوب همسر آینده", "type": "radio", "required": true, "tooltip": "سطح مذهبی مورد نظر همسر آینده را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "بسیار مذهبی و مقید", "مذهبی معتدل", @@ -1216,13 +1838,16 @@ } }, { - "title": "Desired Political Outlook", + "title": "نگرش سیاسی مطلوب همسر آینده", "type": "radio", "required": true, "tooltip": "نگرش سیاسی مورد نظر خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "حتماً همسو با دیدگاه من باشد.", "تفاوت دیدگاه سیاسی مهم نیست، به شرط احترام متقابل.", @@ -1232,13 +1857,16 @@ } }, { - "title": "Boundaries with the Opposite Sex", + "title": "حدود روابط همسر آینده با جنس مخالف", "type": "radio", "required": true, "tooltip": "حدود روابط اجتماعی همسر آینده را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "بسیار رسمی و محدود باشد.", "معمولی و محترمانه باشد.", @@ -1247,13 +1875,16 @@ } }, { - "title": "Red Lines for Smoking, Alcohol, and Substances", - "type": "checkbox", + "title": "خط قرمزهای مربوط به دخانیات، الکل و مواد در همسر آینده", + "type": "dropdown", "required": true, "tooltip": "خط قرمزهای خود را انتخاب کنید.", "extras": { "placeHolder": "انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "سیگار برایم خط قرمز است.", "قلیان برایم خط قرمز است.", @@ -1262,17 +1893,21 @@ "مواد مخدر برایم خط قرمز قطعی است.", "مصرف تفریحی دخانیات را در شرایط خاص می‌پذیرم.", "هیچ‌کدام برایم خط قرمز نیست." - ] + ], + "noSearch": true } }, { - "title": "Attitude towards Music", + "title": "نگرش به موسیقی", "type": "radio", "required": true, "tooltip": "نگرش مورد نظر خود را در مورد موسیقی انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "نباید به موسیقی گوش بدهد.", "فقط موسیقی مذهبی / بدون ساز / نشید قابل قبول است.", @@ -1282,30 +1917,37 @@ } }, { - "title": "Attitude towards Wedding Ceremony", - "type": "radio", + "title": "نگرش به مراسم عروسی", + "type": "dropdown", "required": true, "tooltip": "نحوه برگزاری مراسم عروسی مورد نظر خود را انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "مراسم ساده یا بدون مراسم را ترجیح دهد.", "فقط مراسم کاملاً شرعی و تفکیک‌شده قابل قبول است.", "مراسم مختلط محترمانه و بدون رقص و موسیقی غیرشرعی قابل قبول است.", "مراسم مختلط با موسیقی و رقص قابل قبول است.", "بسته به توافق خانواده‌ها قابل تصمیم‌گیری است." - ] + ], + "noSearch": true } }, { - "title": "Acceptance of Chronic Illness or Disability", + "title": "پذیرش بیماری خاص، معلولیت یا شرایط درمانی در همسر آینده", "type": "radio", "required": true, "tooltip": "موضع خود را در مورد بیماری یا معلولیت همسر آینده مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "برایم خط قرمز است.", "در شرایط خاص و با توضیح کامل بررسی می‌کنم.", @@ -1315,13 +1957,16 @@ } }, { - "title": "Acceptance of Psychological Counseling History", + "title": "پذیرش سابقه مشاوره یا درمان روان‌شناختی همسر آینده", "type": "radio", "required": true, "tooltip": "موضع خود را در مورد سابقه مشاوره همسر آینده مشخص کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "برایم مشکلی ندارد.", "بستگی به شرایط فعلی و میزان ثبات دارد.", @@ -1331,13 +1976,16 @@ } }, { - "title": "Residence Preference after Marriage", - "type": "radio", + "title": "ترجیح درباره محل زندگی بعد از ازدواج", + "type": "dropdown", "required": true, "tooltip": "محل زندگی مورد نظر خود را بعد از ازدواج انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "کشور محل زندگی طرف مقابل برایم مهم نیست.", "ترجیح می‌دهم در کشور فعلی خودم بمانم.", @@ -1345,17 +1993,21 @@ "فقط در شهر فعلی خودم حاضر به زندگی هستم.", "آماده مهاجرت به کشور ثالث هستم.", "بسته به کار، اقامت، خانواده و شرایط مالی تصمیم می‌گیریم." - ] + ], + "noSearch": true } }, { - "title": "Preference for Living with Family", + "title": "زندگی با خانواده بعد از ازدواج", "type": "radio", "required": true, "tooltip": "نظر خود را در مورد زندگی با خانواده بعد از ازدواج انتخاب کنید.", "extras": { "placeHolder": "یک گزینه را انتخاب کنید", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [ "فقط زندگی مستقل را می‌پذیرم.", "زندگی موقت با خانواده در ابتدای ازدواج قابل قبول است.", @@ -1365,21 +2017,24 @@ } }, { - "title": "Additional Comments and Red Lines", + "title": "توضیحات تکمیلی و سایر خطوط قرمز", "type": "text", "required": true, "description": "فیلد متنی بزرگ", "tooltip": "هر نکته مهمی که در گزینه‌های بالا نبود، اینجا بنویسید.", "extras": { "placeHolder": "توضیحات تکمیلی را اینجا وارد کنید...", - "range": [0, 0], + "range": [ + 0, + 0 + ], "options": [] } } ] }, { - "title": "Identity Verification and Documents", + "title": "بخش ۹: بارگذاری مدارک، احراز هویت و تصاویر", "icon": "shield-check", "slug": "identity_verification", "required": true, @@ -1389,7 +2044,7 @@ "description": "بارگذاری مدارک شناسایی.", "questions": [ { - "title": "Profile Picture", + "title": "تصویر چهره؛ عکس جدید و واضح", "type": "photo", "required": true, "private": true, @@ -1397,12 +2052,19 @@ "tooltip": "این تصویر به هیچ عنوان به طرف مقابل یا سایر کاربران نمایش داده نمی‌شود. عکس شما فقط توسط کارشناسان تأییدشده و هم‌جنس برای احراز هویت، بررسی تطابق ظاهری و جلوگیری از اختلافات ظاهری شدید بررسی می‌شود.\n\nراهنمای عکس مناسب:\n- عکس جدید و واضح باشد.\n- چهره کاملاً مشخص باشد.\n- فیلتر سنگین نداشته باشد.\n- عکس گروهی نباشد.\n- نور کافی داشته باشد.", "extras": { "placeHolder": "بارگذاری تصویر", - "range": [0, 0], - "options": [".jpg", ".jpeg", ".png"] + "range": [ + 0, + 0 + ], + "options": [ + ".jpg", + ".jpeg", + ".png" + ] } }, { - "title": "Valid Identification Document", + "title": "تصویر کارت شناسایی معتبر", "type": "file", "required": true, "private": true, @@ -1410,10 +2072,34 @@ "tooltip": "تصویر واضح از مدرک شناسایی معتبر خود را بارگذاری کنید. مدارک قابل قبول:\n- پاسپورت\n- کارت ملی\n- گواهینامه\n- کارت اقامت معتبر\n- مدرک شناسایی رسمی کشور محل سکونت", "extras": { "placeHolder": "بارگذاری مدرک", - "range": [0, 0], - "options": [".pdf", ".jpg", ".jpeg", ".png"] + "range": [ + 0, + 0 + ], + "options": [ + ".pdf", + ".jpg", + ".jpeg", + ".png" + ] + } + }, + { + "title": "تأیید تطابق مدارک و اطلاعات", + "type": "checkbox", + "required": true, + "tooltip": "تأیید مطابقت اطلاعات وارد شده با مدارک شناسایی.", + "extras": { + "placeHolder": "تأیید می‌کنم", + "range": [ + 0, + 0 + ], + "options": [ + "تأیید می‌کنم که نام، سن، تصویر و اطلاعات هویتی من با مدارک بارگذاری‌شده مطابقت دارد." + ] } } ] } -] +] \ No newline at end of file diff --git a/سوالات مریج.md b/سوالات مریج.md new file mode 100644 index 0000000..26ed26c --- /dev/null +++ b/سوالات مریج.md @@ -0,0 +1,770 @@ +🔒 **محرمانه:** فقط برای کارشناسان پلتفرم و سیستم مچینگ قابل مشاهده است. + 👁️ **قابل نمایش محدود:** فقط پس از تأیید، در مراحل رسمی آشنایی، و به‌صورت محدود به طرف مقابل نمایش داده می‌شود. + \* **فیلد اجباری:** تکمیل این مورد برای ادامه ثبت‌نام لازم است. + +حبیب مریج تلاش می‌کند ازدواج را با حفظ شأن، حریم خصوصی، چارچوب خانوادگی و روش سنتی، اما با کمک ابزارهای مدرن، پیش ببرد. + +--- + +# **بخش ۱: مشخصات فردی و هویتی** + +🔒 **نام**\* + \[فیلد متنی\] + +🔒 **نام خانوادگی**\* + \[فیلد متنی\] + +🔒 **جنسیت**\* + \[قبلاً در مرحله ثبت‌نام دریافت شده است\] + +👁️ **تاریخ تولد**\* + \[انتخابگر تقویم میلادی — YYYY/MM/DD\] + +👁️ **سن** + \[محاسبه خودکار توسط سیستم\] + +👁️ **کشور محل تولد**\* + \[لیست کشویی کشورها\] + +👁️ **شهر محل تولد**\* + \[فیلد متنی\] + +👁️ **ملیت / تابعیت فعلی**\* + \[لیست کشویی کشورها\] + +👁️ **قومیت / اصلیت خانوادگی / نژاد**\* + \[فیلد متنی\] + راهنما: مثال: عرب، فارس، ترک، کرد، بلوچ، دسی، قفقازی، آفریقایی‌تبار، لاتین و… + +👁️ **رنگ پوست**\* + \[تک‌انتخابی\] + +* سفید / روشن +* گندم‌گون / سبزه روشن +* سبزه تیره / قهوه‌ای +* تیره / سیاه‌پوست + +👁️ **زبان مادری**\* + \[چندانتخابی\] + +👁️ **سایر زبان‌هایی که به آن‌ها مسلط هستم** + \[چندانتخابی\] + +--- + +# **بخش ۲: اطلاعات تماس، سکونت و ارتباط خانوادگی** + +🔒 **شماره تماس شخصی با کد کشور**\* + \[فیلد متنی\] + +🔒 **ایمیل**\* + \[فیلد متنی\] + +👁️ **کشور محل سکونت فعلی**\* + \[لیست کشویی کشورها\] + +👁️ **شهر / ایالت محل سکونت فعلی**\* + \[فیلد متنی\] + +👁️ **لوکیشن حدودی محل زندگی فعلی**\* + \[فیلد متنی یا انتخاب منطقه\] + راهنما: نیازی به آدرس دقیق نیست. فقط محدوده کلی محل زندگی کافی است؛ مثلاً نام شهر، منطقه، ناحیه یا نزدیک‌ترین شهر بزرگ. + +👁️ **وضعیت اقامت در کشور فعلی**\* + \[تک‌انتخابی\] + +* شهروند / دارای تابعیت +* اقامت دائم +* اقامت موقت +* ویزای تحصیلی +* ویزای کاری +* پناهندگی / حمایت بشردوستانه +* در حال پیگیری وضعیت اقامت + +🔒 **تمایل به جابجایی و مهاجرت پس از ازدواج**\* + \[تک‌انتخابی\] + +* کاملاً منعطف هستم؛ جابجایی به شهر یا کشور دیگر برایم مشکلی ندارد. +* حاضرم به شهر دیگری نقل مکان کنم، اما فقط در کشور فعلی خودم حاضر به زندگی هستم. +* فقط در شهر فعلی خودم حاضر به زندگی هستم و جابجایی برایم خط قرمز است. +* بسته به شرایط شغلی، خانوادگی، اقامتی و زندگی همسر آینده‌ام تصمیم می‌گیرم. + +--- + +## **اطلاعات سرپرست / ولی / رابط قابل اعتماد (فقط دختران):** + +⚠️ **قانون اجباری:** + برای **دختران زیر ۲۷ سال** ثبت شماره یک رابط قابل اعتماد **اجباری** است. + برای دختران **۲۷ سال و بالاتر** اجباری نیست، اما قویاً توصیه می‌شود. + +متن مهم که بالاش باید بیاد: +برای زیر ۲۷: +«برای حفظ آرامش، امنیت و شأن شما، روند آشنایی در پلتفرم ما با الگوگیری از رسوم اصیل و محترمانه خانوادگی پیش می‌رود. حضور یک فرد معتمد (ترجیحاً پدر یا مادر) به عنوان رابط، علاوه بر اینکه نشان‌دهنده اصالت شماست، باعث می‌شود طرف مقابل نیز با جدیت، احترام و اطمینان کامل قدم پیش بگذارد.» +برای بالای ۲۷: +«هدف ما شکل‌گیری پیوندهای پایدار بر بستر اعتماد متقابل است. با اینکه ثبت اطلاعات رابط برای شما الزامی نیست، اما معرفی یک فرد معتمد (مانند پدر، مادر یا بزرگتر خانواده) نشان‌دهنده شفافیت و نیت جدی شما برای ازدواج است. پروفایل‌هایی که دارای رابط معتمد هستند، اعتبار بسیار بالاتری دارند و باعث ایجاد اطمینان خاطر بیشتری در خانواده طرف مقابل می‌شوند.» + +🔒 **نام و نام خانوادگی رابط** + \[فیلد متنی — شرطی\] + برای دختران زیر ۲۷ سال: اجباری + +🔒 **نسبت رابط با شما** + \[تک‌انتخابی — شرطی\] + +* پدر +* مادر +* برادر +* خواهر +* عمو / دایی +* خاله / عمه +* دوست خانوادگی معتمد +* معرف مذهبی / روحانی +* معرف اجتماعی معتمد + +🔒 **شماره تماس رابط با کد کشور** + \[فیلد متنی — شرطی\] + برای دختران زیر ۲۷ سال: اجباری + +--- + +# **بخش ۳: ویژگی‌های ظاهری، سلامت و فعالیت بدنی** + +🔒 **قد به سانتی‌متر**\* + \[فیلد عددی\] + +🔒 **وزن به کیلوگرم**\* + \[فیلد عددی\] + +👁️ **وضعیت سلامت جسمانی**\* + \[تک‌انتخابی\] + +* در سلامت کامل هستم. +* بیماری خاص یا مزمن دارم. +* نقص عضو، معلولیت یا محدودیت جسمی دارم. + +👁️ **توضیحات سلامت جسمانی** + \[فیلد متنی شرطی\] + +👁️ **وضعیت سلامت روان**\* + \[تک‌انتخابی\] + +* مشکل خاصی ندارم. +* سابقه مشاوره و درمان داشته‌ام. +* در حال حاضر تحت مشاوره و درمان هستم. + +🔒 **استفاده از داروهای دائمی** + \[فیلد متنی اختیاری\] + +--- + +# **بخش ۴: تحصیلات، شغل و وضعیت اقتصادی** + +👁️ **بالاترین سطح تحصیلات**\* + \[تک‌انتخابی\] + +* زیر دیپلم +* دیپلم / High School +* کاردانی / Associate +* گواهینامه مهارت حرفه‌ای / Certificate +* آموزش فنی یا مهارتی +* کارشناسی / Bachelor’s Degree +* کارشناسی ارشد / Master’s Degree +* دکتری و بالاتر +* تحصیلات حوزوی / علوم دینی + +👁️ **رشته تحصیلی** + \[فیلد متنی\] + +👁️ **وضعیت اشتغال**\* + \[تک‌انتخابی\] + +* شاغل تمام‌وقت +* شاغل پاره‌وقت +* خویش‌فرما / فریلنسر +* کارآفرین / صاحب کسب‌وکار +* دانشجو +* دانشجو و شاغل +* دانشجو و جویای کار +* جویای کار / بیکار +* خانه‌دار +* بازنشسته + +👁️ **عنوان شغلی** + \[فیلد متنی شرطی\] + +👁️ **محل فعالیت** + \[فیلد متنی اختیاری\] + +🔒 **میزان درآمد ماهانه**\* + \[فیلد متنی\] + مثال: 2500 USD، 1800 EUR، 3000 CAD + +🔒 **وضعیت مالی کلی**\* + \[تک‌انتخابی\] + +* درآمد پایدار و قابل اتکا دارم. +* درآمد دارم، اما متغیر است. +* در ابتدای مسیر شغلی و مالی هستم. +* فعلاً بخشی از هزینه‌هایم توسط خانواده تأمین می‌شود. +* فعلاً درآمد مستقل ندارم. + +🔒 **توانایی تأمین هزینه‌های زندگی مشترک**\* + \[تک‌انتخابی\] + +* توانایی تأمین کامل هزینه‌های زندگی مشترک را دارم. +* توانایی تأمین بخش اصلی هزینه‌ها را دارم. +* نیاز به مشارکت مالی همسر آینده دارم. +* فعلاً در حال ساختن شرایط مالی مناسب هستم. +* این موضوع بستگی به کشور و محل زندگی آینده دارد. + +🔒 **وضعیت مسکن فعلی**\* + \[تک‌انتخابی\] + +* مالک خانه شخصی هستم. +* مستأجر هستم و مستقل زندگی می‌کنم. +* همراه خانواده / والدین زندگی می‌کنم. +* خوابگاه / مسکن دانشجویی +* مسکن سازمانی +* فعلاً شرایط موقت دارم. + +🔒 **برنامه یا توانایی تأمین مسکن بعد از ازدواج**\* + \[تک‌انتخابی\] + +* خانه شخصی دارم و امکان زندگی مشترک در آن وجود دارد. +* امکان خرید خانه دارم. +* در ابتدای ازدواج احتمالاً مستأجر خواهیم بود. +* در ابتدای ازدواج ممکن است موقتاً با خانواده زندگی کنیم. + +🔒 **توضیح تکمیلی درباره وضعیت اقتصادی و مسکن** + \[فیلد متنی اختیاری\] + راهنما: اگر شرایط خاصی درباره کار، درآمد، اجاره، خرید خانه، مهاجرت یا محل زندگی آینده دارید، کوتاه توضیح دهید. + +--- + +# **بخش ۵: پیشینه خانوادگی** + +👁️ **تعداد خواهر و برادر**\* + \[فیلد عددی\] + +👁️ **وضعیت حیات والدین**\* + \[تک‌انتخابی\] + +* هر دو در قید حیات هستند. +* پدر فوت شده است. +* مادر فوت شده است. +* هر دو فوت شده‌اند. + +🔒 **وضعیت تأهل والدین**\* + \[تک‌انتخابی\] + +* با هم زندگی می‌کنند. +* از هم جدا شده‌اند / طلاق گرفته‌اند. +* یکی از والدین ازدواج مجدد داشته است. +* شرایط خانوادگی خاص دارم و در توضیحات می‌نویسم. + + +**👁️ فضای مذهبی و اعتقادی خانواده شما به چه شکلی است؟** + +* *(راهنما: لطفاً گزینه‌ای را انتخاب کنید که توصیف بهتری از فضای عمومی و سبک زندگی خانواده شما ارائه می‌دهد.)* +* 🔘 **مذهبی و کاملاً مقید** +* خانواده‌ای که اهتمام ویژه‌ای به انجام دقیق واجبات، رعایت کامل حدود شرعی (مانند محرم و نامحرم) و حفظ شعائر دینی و مکتب اهل‌بیت (علیهم‌السلام) در تمام شئونات زندگی دارند. +* 🔘 **مذهبی (مقید به واجبات)** +* خانواده‌ای که به انجام واجبات دینی (مانند نماز و روزه) و اصول اخلاق اسلامی پایبند هستند و سبک زندگی سالمی بر پایه چارچوب‌های عرفیِ جامعه مذهبی دارند. +* 🔘 **سنتی (محترم به ارزش‌های دینی)** +* خانواده‌ای که به اهل‌بیت و ارزش‌های اخلاقی ارادت دارند و به دین احترام می‌گذارند، اما ممکن است در انجام دقیقِ تمامی احکام شرعی و واجبات، تقید کاملی نداشته باشند. +* 🔘 **غیرمذهبی / عرفی** +* خانواده‌ای که با وجود احترام کلی به دین، مناسک و چارچوب‌های شرعی، نقش پررنگی در سبک زندگی، روابط و تصمیمات روزمره آن‌ها ندارد. +* +* + +👁️ **وضعیت اقتصادی خانواده** + \[تک‌انتخابی\] + +* ضعیف +* متوسط +* خوب +* مرفه + +👁️ **توضیح کوتاه درباره خانواده** + \[فیلد متنی اختیاری\] + +--- + +# **بخش ۶: وضعیت تأهل، سابقه ازدواج و فرزندان** + +🔒 **وضعیت تأهل فعلی**\* + \[تک‌انتخابی\] + +* مجرد؛ بدون هیچ‌گونه سابقه عقد یا ازدواج +* عقد ناموفق / فسخ نامزدی؛ بدون شروع زندگی مشترک +* جدا شده؛ طلاق پس از زندگی مشترک +* همسر فوت شده + +🔒 **مدت ازدواج یا عقد قبلی** + \[فیلد متنی شرطی\] + +🔒 **علت جدایی، در صورت وجود** + \[فیلد متنی اختیاری\] + +👁️ **وضعیت فرزند و تکفل**\* + \[چندانتخابی در صورت نیاز\] + +* فرزندی ندارم. +* فرزند دارم و با من زندگی می‌کند. +* فرزند دارم اما با من زندگی نمی‌کند. +* شخص دیگری غیر از فرزند تحت تکفل من است. + +👁️ **تعداد فرزندان** + \[فیلد عددی شرطی\] + +👁️ **توضیح کوتاه درباره شرایط فرزند یا تکفل** + \[فیلد متنی شرطی\] + +--- + +# **بخش ۷: اعتقادات، سبک زندگی، شخصیت و خطوط قرمز شخصی** + +👁️ **مرجع تقلید**\* + \[فیلد متنی یا چک‌باکس\] + +* این موضوع برایم اولویت ندارد. + +🔒 **میزان تقید به نمازهای واجب**\* + \[تک‌انتخابی\] + +* همیشه مقید هستم، ترجیحاً اول وقت. +* همیشه مقید هستم، اما نه لزوماً اول وقت. +* گاهی اوقات می‌خوانم. +* نمی‌خوانم. + +🔒 **میزان تقید به روزه ماه رمضان**\* + \[تک‌انتخابی\] + +* کاملاً مقید هستم. +* به دلیل عذر شرعی یا پزشکی روزه نمی‌گیرم. +* گاهی بدون عذر شرعی روزه نمی‌گیرم. +* مقید نیستم. +* + +👁️ **نوع پوشش و ظاهر**\* + \[تک‌انتخابی\] + +*(راهنما: لطفاً گزینه‌ای را انتخاب کنید که بیشترین تطابق را با پوشش روزمره شما در اجتماع دارد.)* + +* 🔘 **پوشش کامل اسلامی (حجاب حداکثری)** +* استفاده از لباس‌هایی مانند عبایا، جلباب، چادر یا نقاب با رعایت دقیق و کامل تمامی حدود شرعی. +* 🔘 **حجاب کامل با لباس‌های آزاد و پوشیده** +* استفاده از لباس‌های گشاد و بلند (مانند تونیک، مانتو یا شلوار قمیص) به همراه رعایت کامل حجاب موی سر. +* 🔘 **پوشش عرفی/روزمره به همراه حجاب** +* استفاده از لباس‌های معمول و مدرن (مانند شلوار جین یا استایل‌های کژوال) به همراه پوشاندن موی سر با شال، روسری یا توربان. +* 🔘 **پوشش محجوب و باوقار (بدون حجاب سر)** +* استفاده از لباس‌های کاملاً پوشیده، سنگین و رسمی، اما بدون استفاده از شال، روسری و پوشش موی سر. +* 🔘 **پوشش آزاد و مدرن (بدون رعایت حجاب)** +* پوشش کاملاً آزاد و مطابق با استایل‌های روز جامعه بین‌الملل، بدون رعایت قواعد شرعی حجاب اسلامی. + +👁️ **آرایش در محیط عمومی، مخصوص خانم‌ها** + \[تک‌انتخابی\] + +* اصلاً آرایش نمی‌کنم. +* فقط آرایش بسیار ملایم دارم. +* آرایش کامل می‌کنم. + + ### 🔒 **نگرش شما به رابطه دین و سیاست (و خط قرمزهای همسر آینده)** + + ### \[تک‌انتخابی\] + +*(راهنما: لطفاً گزینه‌ای را انتخاب کنید که نگاه شما به مذهب و انتظار شما از همسر آینده‌تان را بهتر توصیف می‌کند.)* + +* 🔘 دین را از سیاست جدا نمی‌دانم و همسرم نیز حتماً باید دغدغه و نگاه سیاسی-اجتماعی در دین داشته باشد. +* 🔘 دین را از سیاست جدا نمی‌دانم، اما داشتن دغدغه یا فعالیت سیاسی برای همسرم الزامی نیست و برایم خط قرمز محسوب نمی‌شود. +* 🔘 نگاهم به تشیع کاملاً سنتی و غیرسیاسی است و به هیچ وجه با فردی که نگاه سیاسی به دین دارد نمی‌توانم ازدواج کنم. +* 🔘 نگاهم به تشیع غیرسیاسی است، اما اگر همسر آینده‌ام نگاه سیاسی داشته باشد برایم خط قرمز نیست و با آن کنار می‌آیم. +* 🔘 اساساً این مفاهیم و دسته‌بندی‌ها (تشیع سیاسی یا غیرسیاسی) برایم مطرح نیست یا چندان درگیر این مسائل نیستم. + +### 🔒 **موضع شما نسبت به حاکمیت/دولت فعلی کشور محل سکونتتان** + +*(راهنما: این بخش برای جلوگیری از تنش‌های جدیِ اعتقادی در زندگی مشترک طراحی شده است.)* + +* 🔘 حامی حاکمیت/دولت فعلی کشورم هستم و مخالفت جدی طرف مقابل با حاکمیت، برایم خط قرمز است. +* 🔘 حامی حاکمیت/دولت فعلی کشورم هستم، اما تفاوت دیدگاه یا مخالفت همسرم در این زمینه برایم خط قرمز نیست. +* 🔘 مخالف حاکمیت/دولت فعلی کشورم هستم و حمایت جدی طرف مقابل از حاکمیت، برایم خط قرمز است. +* 🔘 مخالف حاکمیت/دولت فعلی کشورم هستم، اما تفاوت دیدگاه یا حمایت همسرم از دولت برایم خط قرمز نیست. +* 🔘 موضع‌گیری خاصی (حمایت یا مخالفت جدی) ندارم و تفاوت دیدگاه‌های سیاسی برایم اهمیت چندانی در زندگی مشترک ندارد. + +### **👁️ حدود روابط شما با جنس مخالف (در محیط کار، فامیل و اجتماع) چگونه است؟** + +* *(راهنما: لطفاً گزینه‌ای را انتخاب کنید که رفتار روزمره شما را در مواجهه با نامحرم بهتر توصیف می‌کند.)* +* 🔘 **بسیار رسمی و محدود (فقط در حد ضرورت)** +* ارتباطاتم با نامحرم بسیار کوتاه و کاملاً رسمی است و از هرگونه گفتگوی غیرضروری، معاشرت مازاد یا شوخی پرهیز می‌کنم. +* 🔘 **محترمانه و متعارف (بدون صمیمیت)** +* ارتباطاتم در اجتماع و فامیل محترمانه و با خوش‌رویی است، اما حریم و مرز جدی برای پرهیز از شوخی، راحتی بیش‌ازحد یا گفتگوهای شخصی دارم. +* 🔘 **اجتماعی و راحت‌تر (در چارچوب شرع)** +* حضور فعال و راحتی در اجتماع و فامیل دارم؛ معاشرت، گفتگوی صمیمانه و شوخی‌های عرفی را تا زمانی که از خطوط قرمز شرعی و اخلاقی خارج نشود، بلامانع می‌دانم. +* 🔘 **بدون مرزبندی خاص** +* در ارتباط با جنس مخالف کاملاً راحت هستم و مرزبندی‌های سنتی یا حساسیت‌های مذهبی در معاشرت‌ها، شوخی‌ها و دوستی‌های اجتماعی ندارم. + +--- + +## **مصرف دخانیات، الکل و مواد** + +🔒 **سیگار**\* + \[تک‌انتخابی\] + +* اصلاً مصرف نمی‌کنم. +* گاهی / تفریحی مصرف می‌کنم. +* مرتب مصرف می‌کنم. +* در حال ترک هستم. + +🔒 **قلیان**\* + \[تک‌انتخابی\] + +* اصلاً مصرف نمی‌کنم. +* گاهی / تفریحی مصرف می‌کنم. +* مرتب مصرف می‌کنم. +* در حال ترک هستم. + +🔒 **ویپ / سیگار الکترونیک**\* + \[تک‌انتخابی\] + +* اصلاً مصرف نمی‌کنم. +* گاهی / تفریحی مصرف می‌کنم. +* مرتب مصرف می‌کنم. +* در حال ترک هستم. + +🔒 **مشروبات الکلی**\* + \[تک‌انتخابی\] + +* اصلاً مصرف نمی‌کنم. +* مصرف الکل برای من خط قرمز جدی است. +* گاهی مصرف می‌کنم. +* مصرف می‌کنم. + +🔒 **مواد مخدر یا مواد غیرقانونی**\* + \[تک‌انتخابی\] + +* هرگز مصرف نکرده‌ام. +* سابقه مصرف داشته‌ام، اما اکنون مصرف نمی‌کنم. +* مصرف می‌کنم. +* در حال ترک یا درمان هستم. + +--- + +## **سبک زندگی و سلیقه‌ها** + +👁️ **نگرش به موسیقی**\* + \[تک‌انتخابی\] + +* به هیچ نوع موسیقی گوش نمی‌دهم. +* فقط نشید، آکاپلا، مذهبی یا بدون ساز گوش می‌دهم. +* موسیقی حلال و مجاز گوش می‌دهم. +* حساسیت خاصی روی نوع موسیقی ندارم. + +🔒 **نگرش به مراسم عروسی**\* + \[تک‌انتخابی\] + +* بدون مراسم یا بسیار ساده. +* کاملاً شرعی و تفکیک‌شده. +* مختلط محترمانه، بدون رقص و موسیقی غیرشرعی. +* مختلط همراه با موسیقی و رقص. +* هنوز تصمیم قطعی ندارم و بسته به توافق خانواده‌ها تصمیم می‌گیرم. + +👁️ **ویژگی‌های شخصیتی خودتان**\* + \[چندانتخابی\] + +* آرام و درونگرا +* اجتماعی و برونگرا +* احساسی +* منطقی +* شوخ‌طبع +* جدی +* اهل گفتگو +* خانواده‌دوست +* مستقل +* مسئولیت‌پذیر +* صبور +* منظم +* اهل برنامه‌ریزی +* انعطاف‌پذیر +* حساس و دقیق +* اهل رشد فردی + +👁️ **سرگرمی‌ها و علایق اصلی**\* + \[چندانتخابی\] + +* تلاوت قرآن و مطالعه دینی +* حضور در مسجد و هیئت +* فعالیت مذهبی و فرهنگی +* سفر زیارتی +* سفر سیاحتی +* طبیعت‌گردی +* ورزش +* مطالعه +* فیلم و سینما +* آشپزی +* هنر +* موسیقی +* بازی‌های فکری +* فعالیت اجتماعی و خیریه +* کافه و رستوران +* یادگیری زبان +* تکنولوژی و کامپیوتر + +👁️ **توضیح کوتاه درباره سبک زندگی خودتان** + \[فیلد متنی اختیاری\] + +--- + +# **بخش ۸: معیارها و خطوط قرمز همسر آینده** + +⚠️ این بخش کاملاً محرمانه است و فقط برای مچینگ و بررسی کارشناسان استفاده می‌شود. + +🔒 **بازه سنی مطلوب همسر آینده**\* + از \[عدد\] تا \[عدد\] سال + +🔒 **بازه قدی مطلوب همسر آینده**\* + \[چندانتخابی\] + +* مهم نیست. +* کمتر از ۱۶۰ +* ۱۶۰ تا ۱۷۰ +* ۱۷۰ تا ۱۸۰ +* ۱۸۰ تا ۱۹۰ +* بالای ۱۹۰ + +🔒 **تیپ بدنی مطلوب همسر آینده**\* + \[چندانتخابی\] + +* مهم نیست. +* لاغراندام +* متناسب +* ورزیده +* توپر +* درشت‌اندام + +🔒 **رنگ پوست مطلوب همسر آینده**\* + \[چندانتخابی\] + +* مهم نیست. +* سفید / روشن +* گندم‌گون / سبزه روشن +* سبزه تیره / قهوه‌ای +* تیره / سیاه‌پوست + +🔒 **قومیت، زبان یا ملیت مطلوب همسر آینده** + \[فیلد متنی اختیاری\] + +🔒 **حداقل سطح تحصیلات همسر آینده**\* + \[تک‌انتخابی\] + +* مهم نیست. +* حداقل دیپلم +* حداقل کارشناسی +* حداقل کارشناسی ارشد +* دکتری یا بالاتر ترجیح دارد. +* حتماً تحصیلات حوزوی / علوم دینی داشته باشد. +* تحصیلات دانشگاهی مهم نیست، اما بلوغ فکری مهم است. + +🔒 **وضعیت اشتغال مطلوب همسر آینده**\* + \[چندانتخابی\] + +* مهم نیست. +* شاغل باشد. +* دانشجو باشد. +* خانه‌دار باشد. +* کارآفرین / صاحب کسب‌وکار باشد. +* در مسیر رشد شغلی باشد. +* بسته به شرایط قابل گفتگو است. + +🔒 **پذیرش سابقه عقد یا ازدواج همسر آینده**\* + \[تک‌انتخابی\] + +* فقط مجرد؛ سابقه عقد یا ازدواج قبلی برایم خط قرمز است. +* مجرد ترجیح دارد، اما شرایط خاص را بررسی می‌کنم. +* تفاوتی ندارد. +* بستگی به علت جدایی، مدت ازدواج قبلی و شرایط خانوادگی دارد. + +🔒 **پذیرش داشتن فرزند از ازدواج قبلی**\* + \[تک‌انتخابی\] + +* به هیچ وجه نمی‌پذیرم. +* در شرایط خاص می‌پذیرم. +* تفاوتی ندارد. +* فقط اگر فرزند با او زندگی نکند، بررسی می‌کنم. + +🔒 **معیارهای پوشش و حجاب همسر آینده**\* + \[تک‌انتخابی متناسب با جنسیت\] + +برای آقایانی که به دنبال همسر خانم هستند: + +* پوشش کامل اسلامی مانند چادر، عبایا یا جلباب الزامی است. +* حجاب شرعی الزامی است، اما نوع آن مهم نیست. +* پوشش عرفی همراه با حجاب قابل قبول است. +* پوشش محجوب و سنگین مهم است، اما جزئیات قابل گفتگو است. +* حساسیت خاصی ندارم. + +برای خانم‌هایی که به دنبال همسر آقا هستند: + +* پوشش رسمی، سنگین و مذهبی داشته باشد. +* ساده، مرتب و محجوب باشد. +* پوشش معمولی و آراسته کافی است. +* پوشش مدرن برایم مشکلی ندارد. +* حساسیت خاصی ندارم. + +🔒 **تمایل به ادامه تحصیل همسر آینده**\* + \[تک‌انتخابی\] + +* مهم نیست. +* حتماً قصد ادامه تحصیل داشته باشد. +* ادامه تحصیل مثبت است، اما الزامی نیست. +* ترجیح می‌دهم بعد از ازدواج ادامه تحصیل ندهد. +* بسته به شرایط زندگی مشترک تصمیم می‌گیریم. + +🔒 **تمایل به اشتغال همسر آینده**\* + \[تک‌انتخابی\] + +* مهم نیست. +* حتماً شاغل باشد. +* حتماً خانه‌دار باشد. +* اختیار با خودش باشد. +* بسته به شرایط زندگی، فرزندآوری و توافق مشترک تصمیم می‌گیریم. +* فقط با شغلی که با ارزش‌های دینی و خانوادگی من سازگار باشد موافقم. + +🔒 **وضعیت خانوادگی همسر آینده**\* + \[چندانتخابی\] + +* این معیارها برایم مهم نیست. +* والدین همسرم طلاق نگرفته باشند. +* پدر همسر آینده‌ام در قید حیات باشد. +* مادر همسر آینده‌ام در قید حیات باشد. +* فضای مذهبی خانواده همسر برایم مهم است. +* خانواده همسر باید اهل ارتباط محترمانه و سالم باشند. + +🔒 **سطح ارتباط با خانواده‌ها بعد از ازدواج**\* + \[تک‌انتخابی\] + +* ارتباط نزدیک و پررنگ با خانواده‌ها را دوست دارم. +* ارتباط محترمانه اما با حفظ استقلال زندگی مشترک را ترجیح می‌دهم. +* ارتباط محدود و کنترل‌شده را ترجیح می‌دهم. +* بسته به شرایط خانواده‌ها تصمیم می‌گیرم. + +🔒 **میزان پایبندی مذهبی مطلوب همسر آینده**\* + \[تک‌انتخابی\] + +* بسیار مذهبی و مقید +* مذهبی معتدل +* عرفی اما محترم به دین +* این معیار برایم اهمیت زیادی ندارد. + +🔒 **نگرش سیاسی مطلوب همسر آینده**\* + \[تک‌انتخابی\] + +* حتماً همسو با دیدگاه من باشد. +* تفاوت دیدگاه سیاسی مهم نیست، به شرط احترام متقابل. +* ترجیح می‌دهم سیاسی نباشد. +* سیاست برایم اهمیتی در ازدواج ندارد. + +🔒 **حدود روابط همسر آینده با جنس مخالف**\* + \[تک‌انتخابی\] + +* بسیار رسمی و محدود باشد. +* معمولی و محترمانه باشد. +* اجتماعی‌تر باشد، اما در چارچوب شرع و اخلاق. + +🔒 **خط قرمزهای مربوط به دخانیات، الکل و مواد در همسر آینده**\* + \[چندانتخابی\] + +* سیگار برایم خط قرمز است. +* قلیان برایم خط قرمز است. +* ویپ برایم خط قرمز است. +* الکل برایم خط قرمز جدی است. +* مواد مخدر برایم خط قرمز قطعی است. +* مصرف تفریحی دخانیات را در شرایط خاص می‌پذیرم. +* هیچ‌کدام برایم خط قرمز نیست. + +🔒 **نگرش همسر آینده به موسیقی**\* + \[تک‌انتخابی\] + +* نباید به موسیقی گوش بدهد. +* فقط موسیقی مذهبی / بدون ساز / نشید قابل قبول است. +* موسیقی حلال و مجاز قابل قبول است. +* حساسیت خاصی ندارم. + +🔒 **نگرش همسر آینده به مراسم عروسی**\* + \[تک‌انتخابی\] + +* مراسم ساده یا بدون مراسم را ترجیح دهد. +* فقط مراسم کاملاً شرعی و تفکیک‌شده قابل قبول است. +* مراسم مختلط محترمانه و بدون رقص و موسیقی غیرشرعی قابل قبول است. +* مراسم مختلط با موسیقی و رقص قابل قبول است. +* بسته به توافق خانواده‌ها قابل تصمیم‌گیری است. + +🔒 **پذیرش بیماری خاص، معلولیت یا شرایط درمانی در همسر آینده**\* + \[تک‌انتخابی\] + +* برایم خط قرمز است. +* در شرایط خاص و با توضیح کامل بررسی می‌کنم. +* اگر مانع زندگی مشترک سالم نباشد، می‌پذیرم. +* موردی و با مشورت بررسی می‌کنم. + +🔒 **پذیرش سابقه مشاوره یا درمان روان‌شناختی همسر آینده**\* + \[تک‌انتخابی\] + +* برایم مشکلی ندارد. +* بستگی به شرایط فعلی و میزان ثبات دارد. +* برایم خط قرمز است. +* نیاز به بررسی جدی‌تر دارد. + +🔒 **ترجیح درباره محل زندگی بعد از ازدواج**\* + \[تک‌انتخابی\] + +* کشور محل زندگی طرف مقابل برایم مهم نیست. +* ترجیح می‌دهم در کشور فعلی خودم بمانم. +* ترجیح می‌دهم در کشور فعلی همسر آینده‌ام زندگی کنیم. +* فقط در شهر فعلی خودم حاضر به زندگی هستم. +* آماده مهاجرت به کشور ثالث هستم. +* بسته به کار، اقامت، خانواده و شرایط مالی تصمیم می‌گیرم. + +🔒 **زندگی با خانواده بعد از ازدواج**\* + \[تک‌انتخابی\] + +* فقط زندگی مستقل را می‌پذیرم. +* زندگی موقت با خانواده در ابتدای ازدواج قابل قبول است. +* زندگی با خانواده همسر یا خانواده خودم برایم مشکلی ندارد. +* بستگی به شرایط دارد. + +🔒 **توضیحات تکمیلی و سایر خطوط قرمز**\* + \[فیلد متنی بزرگ\] + راهنما: هر نکته مهمی که در گزینه‌های بالا نبود، اینجا بنویسید. + +--- + +# **بخش ۹: بارگذاری مدارک، احراز هویت و تصاویر** + +🔒 **تصویر چهره؛ عکس جدید و واضح**\* + \[بارگذاری تصویر\] + +⚠️ این تصویر به هیچ عنوان به طرف مقابل یا سایر کاربران نمایش داده نمی‌شود. عکس شما فقط توسط کارشناسان تأییدشده و هم‌جنس پلتفرم برای احراز هویت، بررسی تطابق ظاهری و جلوگیری از اختلافات ظاهری شدید بررسی می‌شود. + +راهنمای عکس مناسب: + +* عکس جدید و واضح باشد. +* چهره کاملاً مشخص باشد. +* فیلتر سنگین نداشته باشد. +* عکس گروهی نباشد. +* نور کافی داشته باشد. + +🔒 **تصویر کارت شناسایی معتبر**\* + \[بارگذاری تصویر\] + +مدارک قابل قبول: + +* پاسپورت +* کارت ملی +* گواهینامه +* کارت اقامت معتبر +* مدرک شناسایی رسمی کشور محل سکونت + +🔒 **تأیید تطابق مدارک و اطلاعات**\* + \[چک‌باکس\] + +☑️ تأیید می‌کنم که نام، سن، تصویر و اطلاعات هویتی من با مدارک بارگذاری‌شده مطابقت دارد. +