Browse Source

feat: add InformationSheet component and implement multi-language support for questionnaire features

Dev
Muhammad A. Ghorbani 4 hours ago
parent
commit
31fb903b9a
  1. 1
      src/app/questions-list/questions-list-client.tsx
  2. 236
      src/app/questions-list/sections-request.tsx
  3. 24
      src/components/Componentes/information-sheet.tsx
  4. 2
      src/translations/locales/de.json
  5. 2
      src/translations/locales/en.json
  6. 2
      src/translations/locales/es.json
  7. 2
      src/translations/locales/fr.json
  8. 2
      src/translations/path_to_english.json

1
src/app/questions-list/questions-list-client.tsx

@ -800,6 +800,7 @@ export default function QuestionsListClient() {
{selectedSection ? (
<InformationSheet
icon={null}
showCloseButton={false}
title={({ close }) => (
<span className="flex w-full items-start justify-between gap-3 text-left">
<span className="group-14 leading-5 font-bold tracking-normal text-[#8B8B8B]">

236
src/app/questions-list/sections-request.tsx

@ -7,22 +7,200 @@ import InformationSheet from "@/components/Componentes/information-sheet";
import type { FormOverviewSection } from "@/hooks/marriage/use-form-schema";
import { useI18n } from "@/translations/provider";
const bookingTerms = [
"All provided information is held in strict confidence.",
"Data is utilized exclusively to ensure optimal matchmaking accuracy.",
];
type TermItem = {
title: string;
description: string;
};
type TermSection = {
category: string;
items: TermItem[];
};
const FIRST_ENTRY_TERMS_SEEN_KEY = "marriage:first-entry-terms-seen";
const FIRST_ENTRY_TERMS = [
...bookingTerms,
"Do you struggle to understand the underlying psychological drivers that dictate your interpersonal connections and communication barriers?",
"Taking this test is not mandatory, but it will help you better search for a spouse. The Kettle test is a test for self-knowledge and better understanding of your spouse.",
'Do you operate based on superficial behavioral adaptations, or are you aware of the deep "source traits" that fundamentally control your decision-making processes?',
"Do you struggle to understand the underlying psychological drivers that dictate your interpersonal connections and communication barriers?",
"Taking this test is not mandatory, but it will help you better search for a spouse. The Kettle test is a test for self-knowledge and better understanding of your spouse.",
'Do you operate based on superficial behavioral adaptations, or are you aware of the deep "source traits" that fundamentally control your decision-making processes?',
] as const;
const TERMS_SECTIONS: TermSection[] = [
{
category: "1. Acceptance of Rules and Platform Goal",
items: [
{
title: "Full Acceptance of Agreement",
description:
"Registration and use of any part of the application means reading and fully accepting all rules. If you do not agree, you must refrain from further use.",
},
{
title: "Changes and Updates",
description:
"The application reserves the right to edit the rules when necessary, and your continued use will constitute acceptance of the new changes.",
},
{
title: "Exclusive Goal of the Application",
description:
"This platform is designed solely for matchmaking and permanent marriage. Use with the purpose of dating, temporary relationships, or entertainment is prohibited.",
},
{
title: "Age and Legal Capacity Requirement",
description:
"Use of services is allowed only for individuals over 18 years of age who have the legal and religious capacity for marriage.",
},
],
},
{
category: "2. User Account, Security, and Authentication",
items: [
{
title: "Accuracy of Personal Information",
description:
"The user is obliged to enter all identity, occupational, educational, and marital status information completely accurately and honestly.",
},
{
title: "Prohibition of Fake Accounts",
description:
"Creating an account using the identity, name, mobile number, or photos of others, as well as creating multiple user accounts, is a serious violation.",
},
{
title: "Maintaining Account Security",
description:
"The responsibility for maintaining the confidentiality of the password and login code lies with the user, and transferring or renting the account to another person is prohibited.",
},
{
title: "Introducing a Trusted Person",
description:
"To enhance security, users can introduce a trusted family member. This information is used strictly for security and urgent cases.",
},
],
},
{
category: "3. Communications, Ethics, and User Behavior",
items: [
{
title: "Mutual Respect",
description:
"Conversations must be ethical and purposeful. Sending offensive, sexual, obscene, threatening, or harassing messages is strictly prohibited.",
},
{
title: "Respecting Others' Privacy",
description:
"Saving, sending, or publishing screenshots of conversations and photos of other users outside the application is a violation of privacy.",
},
{
title: "Absolute Prohibition of Financial Requests",
description:
"Requesting money, loans, gift cards, cryptocurrency, or any financial benefit from other users under any pretext is prohibited.",
},
{
title: "Prohibition of Commercial Activity",
description:
"Any advertising, marketing, selling goods, or raising capital within the application environment is considered a violation.",
},
{
title: "Respectful End of Conversation",
description:
"If the other party does not wish to continue the communication, the user is obliged to respect their decision and refrain from pursuing or causing harassment.",
},
],
},
{
category: "4. Privacy, Data, and Intellectual Property",
items: [
{
title: "Personal Information Protection",
description:
"The application is committed to protecting your sensitive information in accordance with the privacy policy and will not sell it to third parties without permission.",
},
{
title: "Public Profile Display",
description:
"By completing the profile, the user consents to their public information being displayed to other qualified users for service delivery.",
},
{
title: "Account Deletion Rules",
description:
"Upon requesting account deletion, your information is removed from public view, but necessary data for legal and security requirements will remain archived in the system.",
},
{
title: "Intellectual Property Rights",
description:
"All rights to software codes, design, database, and brand name belong to the platform, and any copying or scraping is prohibited.",
},
],
},
{
category: "5. Financial Terms and Subscriptions",
items: [
{
title: "Nature of Paid Services",
description:
"Payment is solely for using premium features and software infrastructure and does not provide any guarantee for marriage or finding a spouse.",
},
{
title: "Refund Policy",
description:
"Paid fees are non-refundable, except in definitive cases of system technical errors.",
},
{
title: "Disclaimer for External Transactions",
description:
"The application holds no responsibility for financial transactions between users or outside the application's official payment gateway.",
},
],
},
{
category: "6. Monitoring, Violations, and Legal Prosecution",
items: [
{
title: "Confidential Reporting",
description:
"Users must report violations, suspicious behavior, or financial requests through the report violation option. The identity of the reporter remains confidential.",
},
{
title: "Authorities of Application Moderators",
description:
"The platform reserves the right to block, restrict, or suspend the user account without prior notice if any violation or breach of rules is detected.",
},
{
title: "Cooperation with Law Enforcement",
description:
"In the event of cybercrimes, fraud, or threats, the application will refer the necessary information to judicial and law enforcement authorities.",
},
{
title: "Dispute Resolution",
description:
"Any legal dispute must first be pursued through application support. If no agreement is reached, the competent authority will be the courts of the city where the application is registered.",
},
],
},
{
category: "7. Disclaimer and In-Person Meetings",
items: [
{
title: "Role of the Application",
description:
"This platform is only a facilitator for initial communication and does not replace family background research, counseling, and pre-marital investigations.",
},
{
title: "Responsibility for Accuracy of Claims",
description:
"Accurate verification of users' claims regarding their financial, occupational, marital, and health status is the responsibility of the user and their family.",
},
{
title: "Responsibility for In-Person Meetings",
description:
"Planning and deciding to meet in person is entirely the responsibility of the users, and the application assumes no liability for any incidents or potential damages.",
},
{
title: "Safety Recommendations in Meetings",
description:
"It is strongly recommended that initial meetings be held in crowded public places, and that a family member or a trusted person be kept informed.",
},
{
title: "Force Majeure Conditions",
description:
"In the event of occurrences beyond control, such as a nationwide internet outage, natural disasters, or sanctions, the application will have no liability for temporary service outages.",
},
],
},
];
export default function SectionsRequest({
sections,
@ -87,6 +265,7 @@ export default function SectionsRequest({
return (
<InformationSheet
icon={null}
showCloseButton={false}
title={({ close }) => (
<span className="flex w-full items-start justify-between gap-3 text-start">
<span className="text-[14px] leading-5 font-bold tracking-normal text-[#8B8B8B]">
@ -103,11 +282,34 @@ export default function SectionsRequest({
</span>
)}
description={
<ul className="max-h-[60dvh] space-y-2 overflow-y-auto ps-4 text-start text-[12px] leading-[1.35] font-medium list-disc text-[#4C4C4C] marker:text-[#2B2B2B]">
{FIRST_ENTRY_TERMS.map((item, index) => (
<li key={`${index}-${item}`}>{(t as Record<string, string>)[item] || item}</li>
))}
<div className="h-[56dvh] max-h-[60dvh] space-y-4 overflow-y-auto pr-1 text-start text-[12px] leading-[1.45] text-[#4C4C4C]">
{TERMS_SECTIONS.map((section, idx) => (
<div key={idx} className="space-y-2">
<h4 className="text-[13px] font-bold text-[#F14B46]">
{(t as Record<string, string>)[section.category] || section.category}
</h4>
<ul className="space-y-2 list-disc ps-4 marker:text-[#2B2B2B]">
{section.items.map((item, itemIdx) => {
const translatedTitle =
(t as Record<string, string>)[item.title] || item.title;
const translatedDesc =
(t as Record<string, string>)[item.description] ||
item.description;
return (
<li key={itemIdx} className="leading-relaxed">
<span className="font-bold text-[#262626]">
{translatedTitle}:{" "}
</span>
<span className="font-normal text-[#525252]">
{translatedDesc}
</span>
</li>
);
})}
</ul>
</div>
))}
</div>
}
buttons={({ close }) => (
<Button className="rounded-[8px]" onClick={close}>

24
src/components/Componentes/information-sheet.tsx

@ -6,7 +6,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
import Button from "./button";
import { LoadingSkeleton } from "./loading-skeleton";
import { LoadingThreeDot } from "./loading-three-dot";
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { useSheetScrollLock } from "./use-sheet-scroll-lock";
import { useI18n } from "@/translations/provider";
const EXIT_ANIMATION_MS = 220;
@ -226,10 +226,7 @@ export function InformationSheet({
}, EXIT_ANIMATION_MS);
}, [isClosing, onClose]);
useHardwareBackHandler(() => {
closeSheet();
return true;
}, isVisible && !isClosing);
useSheetScrollLock(isVisible && !isClosing, { onBack: closeSheet });
const controls = { close: closeSheet };
const resolvedTitle = typeof title === "function" ? title(controls) : title;
@ -242,23 +239,6 @@ export function InformationSheet({
buttons
);
useEffect(() => {
if (!isVisible) {
return;
}
const previousBodyOverflow = document.body.style.overflow;
const previousHtmlOverflow = document.documentElement.style.overflow;
document.body.style.overflow = "hidden";
document.documentElement.style.overflow = "hidden";
return () => {
document.body.style.overflow = previousBodyOverflow;
document.documentElement.style.overflow = previousHtmlOverflow;
};
}, [isVisible]);
if (!isVisible) {
return null;
}

2
src/translations/locales/de.json

@ -740,7 +740,7 @@
"marriages": "marriages",
"matches": "matches",
"play": "play",
"terms & conditions": "terms & conditions",
"terms & conditions": "Allgemeine Geschäftsbedingungen",
"user profiles": "user profiles",
"user@example.com": "user@example.com",
"video": "video",

2
src/translations/locales/en.json

@ -753,7 +753,7 @@
"marriages": "marriages",
"matches": "matches",
"play": "play",
"terms & conditions": "terms & conditions",
"terms & conditions": "Terms & Conditions",
"user profiles": "user profiles",
"user@example.com": "user@example.com",
"video": "video",

2
src/translations/locales/es.json

@ -740,7 +740,7 @@
"marriages": "marriages",
"matches": "matches",
"play": "play",
"terms & conditions": "terms & conditions",
"terms & conditions": "Términos y Condiciones",
"user profiles": "user profiles",
"user@example.com": "usuario@ejemplo.com",
"video": "video",

2
src/translations/locales/fr.json

@ -740,7 +740,7 @@
"marriages": "marriages",
"matches": "matches",
"play": "play",
"terms & conditions": "terms & conditions",
"terms & conditions": "Conditions Générales",
"user profiles": "user profiles",
"user@example.com": "utilisateur@exemple.com",
"video": "video",

2
src/translations/path_to_english.json

@ -202,7 +202,7 @@
"maleRejectionWarning.noPenalty": "Confirming this rejection will not result in any penalty. Instead, it simply enters your status into a 2-day decision window to finalize the case.",
"maleRejectionWarning.swipeText": "Swipe to confirm rejection",
"onboarding.submitProcess": "Submit Process",
"onboarding.termsAndConditions": "terms & conditions",
"onboarding.termsAndConditions": "Terms & Conditions",
"onboarding.welcomeWarning": "Dear user, while welcoming you to the Habib Marij application, please read the following rules and regulations carefully before using the services of this platform. Your registration and use of this application constitutes full acceptance of these rules.",
"onboarding.eligibilityTitle": "1. Eligibility and Membership Requirements",
"onboarding.legalAgeLabel": "Legal Age:",

Loading…
Cancel
Save