diff --git a/.env b/.env index 24dc277..28623f6 100644 --- a/.env +++ b/.env @@ -5,4 +5,4 @@ VITE_API_URL=https://accounts.business-harmony.com/api VITE_IDENTITY_URL=https://accounts.business-harmony.com/connect/token VITE_IDENTITY_CLIENT_ID=harmony_identity VITE_IDENTITY_SCOPE=openid profile offline_access -IMAGE_BASE_URL=https://accounts.business-harmony.com/uploads/ +VITE_IMAGE_BASE_URL=https://accounts.business-harmony.com/api/uploads diff --git a/public/locales/en/completionForm.json b/public/locales/en/completionForm.json index ba8f78d..b736bdc 100644 --- a/public/locales/en/completionForm.json +++ b/public/locales/en/completionForm.json @@ -34,7 +34,9 @@ "submitError": "Error in registering information", "submitting": "Submitting...", "success": "Success", - "agreement": "1. Confidentiality of Information: Harmony commits under no circumstances to disclose users’ identity information, such as phone numbers, email addresses, passwords, user IDs, or any related data, to third parties.\n\n2. User information is used solely for providing authentication services and remains confidential even after account deactivation or termination.\n\n3. Harmony is obliged to implement necessary security measures to prevent unauthorized access.\n\n4. Responsibility for Account Security: Users must protect their accounts and choose strong, non-guessable passwords. Periodic password changes and immediate action in case of suspected unauthorized access are required. Any misuse of the account due to user negligence is the responsibility of the user.\n\n5. Security Breaches and Cyber Attacks: Harmony is not responsible for security breaches caused by cyber attacks beyond the system's control. However, Harmony employs up-to-date security standards and encryption to prevent such incidents.\n\n6. User Negligence in Protecting Information: If account information is disclosed due to user negligence or error, Harmony bears no responsibility. Determining such cases, based on system security logs, is the responsibility of Harmony's technical manager.\n\n7. Accurate Logging of Activities: All events related to registering, editing, and deleting information in the system are accurately and immutably logged. Claims regarding deletion or modification of data without logs are invalid unless supported by documentation provided by the user.\n\n8. Service Updates: Harmony services may be updated or changed over time. Continued use of the system after changes implies acceptance of the new terms. If users disagree, they may request account deletion.\n\n9. User Support: Support is provided only via email and phone, free of charge. Harmony is not obligated to provide in-person support or training beyond basic services.\n\n10. Official Communication Channels: Harmony communicates with users only via the phone number and email registered in the user account. Official announcements are sent through these channels.\n\n11. Official Domains for Communication: All emails from Harmony are sent exclusively from the domain harmony.id. Users must verify this to prevent phishing or similar attacks.\n\n12. Compliance with Iranian Laws: Users must comply with all applicable laws of the Islamic Republic of Iran, including the “Electronic Commerce Law,” “Computer Crimes Law,” and related legislation. Responsibility for violations rests with the user.\n\n13. Temporary Data Retention After Account Termination: Upon account termination or deletion, user information is stored securely for 30 days and permanently deleted thereafter.\n\n14. Ownership of User Data: All data submitted by users belongs to them. Harmony has no ownership over this information. Users are responsible for the accuracy, quality, and legality of their data.\n\n15. Purposeful Use of Identity Information: Collected identity information during registration is used only for authentication and basic services. It will not be shared with any third party without explicit user consent, except under a court order or legal authority.\n\n16. Permanent Data Confidentiality: Harmony commits to maintaining confidentiality of collected information even after the end of the user relationship or account closure.\n\n17. Limitation of Liability: Harmony is not liable for direct or indirect damages resulting from use or inability to use the authentication services.\n\n18. Disruptions in Communication Infrastructure: Harmony is not responsible for disruptions caused by the internet, infrastructure services, or other issues beyond its control.\n\n19. Force Majeure and Unforeseen Events: Harmony bears no responsibility for natural disasters, strikes, power outages, cyber attacks, or other events beyond its control that prevent service delivery.\n\n20. Services Dependent on Third Parties: If parts of the authentication services are provided by third parties, the usage terms of those services are the responsibility of those companies, and Harmony bears no liability.\n\n21. Guarantee of Data Access in Case of Service Termination: If Harmony ceases operations permanently, it commits to keeping servers active for two years and allowing users access to their data.\n\n22. Notification of Service Interruptions: If service interruption is necessary, Harmony must notify users at least 12 hours in advance via email or SMS." + "agreement": "1. Confidentiality of Information: Harmony commits under no circumstances to disclose users’ identity information, such as phone numbers, email addresses, passwords, user IDs, or any related data, to third parties.\n\n2. User information is used solely for providing authentication services and remains confidential even after account deactivation or termination.\n\n3. Harmony is obliged to implement necessary security measures to prevent unauthorized access.\n\n4. Responsibility for Account Security: Users must protect their accounts and choose strong, non-guessable passwords. Periodic password changes and immediate action in case of suspected unauthorized access are required. Any misuse of the account due to user negligence is the responsibility of the user.\n\n5. Security Breaches and Cyber Attacks: Harmony is not responsible for security breaches caused by cyber attacks beyond the system's control. However, Harmony employs up-to-date security standards and encryption to prevent such incidents.\n\n6. User Negligence in Protecting Information: If account information is disclosed due to user negligence or error, Harmony bears no responsibility. Determining such cases, based on system security logs, is the responsibility of Harmony's technical manager.\n\n7. Accurate Logging of Activities: All events related to registering, editing, and deleting information in the system are accurately and immutably logged. Claims regarding deletion or modification of data without logs are invalid unless supported by documentation provided by the user.\n\n8. Service Updates: Harmony services may be updated or changed over time. Continued use of the system after changes implies acceptance of the new terms. If users disagree, they may request account deletion.\n\n9. User Support: Support is provided only via email and phone, free of charge. Harmony is not obligated to provide in-person support or training beyond basic services.\n\n10. Official Communication Channels: Harmony communicates with users only via the phone number and email registered in the user account. Official announcements are sent through these channels.\n\n11. Official Domains for Communication: All emails from Harmony are sent exclusively from the domain harmony.id. Users must verify this to prevent phishing or similar attacks.\n\n12. Compliance with Iranian Laws: Users must comply with all applicable laws of the Islamic Republic of Iran, including the “Electronic Commerce Law,” “Computer Crimes Law,” and related legislation. Responsibility for violations rests with the user.\n\n13. Temporary Data Retention After Account Termination: Upon account termination or deletion, user information is stored securely for 30 days and permanently deleted thereafter.\n\n14. Ownership of User Data: All data submitted by users belongs to them. Harmony has no ownership over this information. Users are responsible for the accuracy, quality, and legality of their data.\n\n15. Purposeful Use of Identity Information: Collected identity information during registration is used only for authentication and basic services. It will not be shared with any third party without explicit user consent, except under a court order or legal authority.\n\n16. Permanent Data Confidentiality: Harmony commits to maintaining confidentiality of collected information even after the end of the user relationship or account closure.\n\n17. Limitation of Liability: Harmony is not liable for direct or indirect damages resulting from use or inability to use the authentication services.\n\n18. Disruptions in Communication Infrastructure: Harmony is not responsible for disruptions caused by the internet, infrastructure services, or other issues beyond its control.\n\n19. Force Majeure and Unforeseen Events: Harmony bears no responsibility for natural disasters, strikes, power outages, cyber attacks, or other events beyond its control that prevent service delivery.\n\n20. Services Dependent on Third Parties: If parts of the authentication services are provided by third parties, the usage terms of those services are the responsibility of those companies, and Harmony bears no liability.\n\n21. Guarantee of Data Access in Case of Service Termination: If Harmony ceases operations permanently, it commits to keeping servers active for two years and allowing users access to their data.\n\n22. Notification of Service Interruptions: If service interruption is necessary, Harmony must notify users at least 12 hours in advance via email or SMS.", + "successfulCodeSent": "Verification code sent successfully.", + "problem": "There is a problem" }, "validation": { "firstNameRequired": "First name is required.", diff --git a/public/locales/en/setting.json b/public/locales/en/setting.json index b2162f4..4c50a53 100644 --- a/public/locales/en/setting.json +++ b/public/locales/en/setting.json @@ -69,7 +69,8 @@ "errorSendCode": "Failed to send code", "phoneVerified": "Phone number verified", "errorConfirmCode": "Failed to confirm code", - "errorChangePhone": "Failed to change phone number" + "errorChangePhone": "Failed to change phone number", + "verificationCodeSent": "Verification code sent" }, "active": { diff --git a/public/locales/fa/completionForm.json b/public/locales/fa/completionForm.json index bb609a8..ecd406c 100644 --- a/public/locales/fa/completionForm.json +++ b/public/locales/fa/completionForm.json @@ -42,7 +42,9 @@ "problem": "مشکلی پیش آمده", "codeVerified": "کد با موفقیت تایید شد", "invalidCode": "کد نامعتبر است", - "agreement": "۱. محرمانگی اطلاعات هارمونی متعهد می‌شود تحت هیچ شرایطی اطلاعات هویتی کاربران نظیر شماره تلفن، ایمیل، رمز عبور، شناسه کاربری و هرگونه داده مرتبط را در اختیار اشخاص ثالث قرار ندهد. اطلاعات کاربران صرفاً در چارچوب ارائه خدمات احراز هویت مورد استفاده قرار گرفته و حتی پس از غیرفعال‌سازی حساب یا قطع همکاری، این اطلاعات محرمانه باقی خواهد ماند. هارمونی موظف به پیاده‌سازی تدابیر امنیتی لازم برای جلوگیری از هرگونه دسترسی غیرمجاز می‌باشد.\n\n۲. مسئولیت حفظ اطلاعات ورود: کاربر موظف است از حساب کاربری خود محافظت کند و رمز عبوری ایمن و غیرقابل حدس انتخاب نماید. تغییر دوره‌ای رمز عبور و اقدام فوری در صورت احساس خطر دسترسی غیرمجاز الزامی است. مسئولیت هرگونه سوءاستفاده از حساب کاربری به دلیل بی‌احتیاطی کاربر، بر عهده خود وی خواهد بود.\n\n۳. رخنه‌های امنیتی و حملات سایبری: هارمونی در برابر رخنه‌های امنیتی ناشی از حملات سایبری که خارج از کنترل سیستم است، مسئولیتی ندارد. با این حال، هارمونی از به‌روزترین استانداردهای امنیتی و رمزنگاری برای جلوگیری از چنین حوادثی بهره می‌برد.\n\n۴. قصور کاربر در حفاظت از اطلاعات: چنانچه اطلاعات حساب کاربری به دلیل سهل‌انگاری یا اشتباه کاربر افشا شود، هارمونی مسئولیتی در این خصوص ندارد. تشخیص چنین مواردی بر اساس لاگ‌های امنیتی سیستم، بر عهده مدیر فنی هارمونی خواهد بود.\n\n۵. ثبت دقیق فعالیت‌ها در لاگ‌ها: تمامی رویدادهای مرتبط با ثبت، ویرایش و حذف اطلاعات در سیستم، به‌صورت دقیق و غیرقابل‌تغییر در لاگ کاربران ثبت می‌گردد. هرگونه ادعا مبنی بر حذف یا تغییر داده‌ها بدون ردپای لاگ قابل پذیرش نیست مگر با ارائه مستندات از سوی کاربر.\n\n۶. به‌روزرسانی خدمات: خدمات هارمونی ممکن است به مرور زمان به‌روزرسانی یا تغییر پیدا کند. ادامه استفاده از سیستم پس از اعمال تغییرات به معنای پذیرش مقررات جدید است. در صورت عدم موافقت، کاربر می‌تواند درخواست حذف حساب خود را ارائه دهد.\n\n۷. پشتیبانی کاربران: پشتیبانی خدمات صرفاً از طریق ایمیل و تماس تلفنی صورت می‌گیرد و رایگان است. هارمونی تعهدی به ارائه پشتیبانی حضوری یا آموزش‌های فراتر از خدمات پایه ندارد.\n\n۸. راه‌های ارتباط رسمی: هارمونی تنها از طریق شماره تلفن و ایمیل ثبت‌شده در حساب کاربر با وی در ارتباط خواهد بود. اطلاعیه‌ها و اعلانات رسمی از این مسیرها انجام می‌گیرد.\n\n۹. دامنه‌های رسمی ارتباط: تمام ایمیل‌های ارسالی از سوی هارمونی صرفاً با دامنه‌ی harmony.id ارسال می‌شود. کاربران موظف به بررسی این نشانی برای جلوگیری از فیشینگ و حملات مشابه هستند.\n\n۱۰. رعایت قوانین جمهوری اسلامی ایران: کاربر موظف است در استفاده از سیستم، کلیه قوانین جاری کشور، از جمله «قانون تجارت الکترونیکی»، «قانون جرائم رایانه‌ای» و سایر قوانین مرتبط را رعایت نماید. مسئولیت هرگونه تخلف بر عهده کاربر خواهد بود.\n\n۱۱. نگهداری موقت اطلاعات پس از فسخ حساب: در صورت فسخ یا حذف حساب، اطلاعات کاربر به مدت ۳۰ روز در فضای امن نگهداری می‌شود و پس از آن، به‌طور غیرقابل‌بازگشت حذف خواهد شد.\n\n۱۲. مالکیت اطلاعات کاربر: تمام اطلاعات ثبت‌شده توسط کاربر متعلق به خود اوست و هارمونی هیچ‌گونه مالکیتی بر این اطلاعات ندارد. کاربر مسئول صحت، کیفیت و قانونی بودن داده‌های خود می‌باشد.\n\n۱۳. استفاده هدفمند از اطلاعات شناسایی: اطلاعات هویتی جمع‌آوری‌شده هنگام ثبت‌نام تنها برای احراز هویت و ارائه خدمات پایه مورد استفاده قرار می‌گیرد. این اطلاعات بدون رضایت صریح کاربر، به هیچ نهاد یا شخص ثالثی منتقل نخواهد شد. تبصره: اطلاعات هویتی کاربران صرفاً در صورت حکم مقام قضایی یا مراجع ذی‌صلاح و در چارچوب قوانین، قابل ارائه خواهد بود.\n\n۱۴. محرمانگی دائمی داده‌ها: هارمونی متعهد است حتی پس از اتمام رابطه کاربری یا انحلال حساب، اطلاعات جمع‌آوری‌شده را به عنوان محرمانه حفظ نماید.\n\n۱۵. محدودیت مسئولیت: هارمونی مسئولیتی در قبال خسارات مستقیم یا غیرمستقیمی که به دلیل استفاده یا عدم استفاده از خدمات احراز هویت ایجاد شود، نخواهد داشت.\n\n۱۶. اختلال در بسترهای ارتباطی: هارمونی در برابر اختلال‌های ناشی از شبکه اینترنت، خدمات زیرساختی یا هرگونه مشکل خارج از کنترل خود، مسئولیتی ندارد.\n\n۱۷. حوادث قهری و غیرمترقبه: در صورت وقوع بلایای طبیعی، اعتصاب، قطعی برق، حملات سایبری یا هرگونه رخداد خارج از کنترل هارمونی که مانع ارائه خدمات شود، مسئولیتی متوجه هارمونی نخواهد بود.\n\n۱۸. خدمات وابسته به سایر سرویس‌ها: چنانچه بخشی از خدمات احراز هویت توسط شرکت‌های ثالث ارائه شود، قوانین استفاده از این سرویس‌ها بر عهده همان شرکت‌هاست و هارمونی نسبت به آن‌ها مسئولیتی ندارد.\n\n۱۹. تضمین دسترسی به اطلاعات در صورت توقف فعالیت: در صورت توقف دائمی فعالیت هارمونی، این شرکت متعهد است به مدت دو سال، سرورها را فعال نگه دارد و امکان دسترسی کاربران به اطلاعات خود را فراهم سازد.\n\n۲۰. اطلاع‌رسانی در مورد قطع سرویس‌ها: در صورت نیاز به توقف خدمات، هارمونی موظف است حداقل ۱۲ ساعت قبل، این موضوع را از طریق ایمیل یا پیامک به اطلاع کاربران برساند." + "agreement": "۱. محرمانگی اطلاعات هارمونی متعهد می‌شود تحت هیچ شرایطی اطلاعات هویتی کاربران نظیر شماره تلفن، ایمیل، رمز عبور، شناسه کاربری و هرگونه داده مرتبط را در اختیار اشخاص ثالث قرار ندهد. اطلاعات کاربران صرفاً در چارچوب ارائه خدمات احراز هویت مورد استفاده قرار گرفته و حتی پس از غیرفعال‌سازی حساب یا قطع همکاری، این اطلاعات محرمانه باقی خواهد ماند. هارمونی موظف به پیاده‌سازی تدابیر امنیتی لازم برای جلوگیری از هرگونه دسترسی غیرمجاز می‌باشد.\n\n۲. مسئولیت حفظ اطلاعات ورود: کاربر موظف است از حساب کاربری خود محافظت کند و رمز عبوری ایمن و غیرقابل حدس انتخاب نماید. تغییر دوره‌ای رمز عبور و اقدام فوری در صورت احساس خطر دسترسی غیرمجاز الزامی است. مسئولیت هرگونه سوءاستفاده از حساب کاربری به دلیل بی‌احتیاطی کاربر، بر عهده خود وی خواهد بود.\n\n۳. رخنه‌های امنیتی و حملات سایبری: هارمونی در برابر رخنه‌های امنیتی ناشی از حملات سایبری که خارج از کنترل سیستم است، مسئولیتی ندارد. با این حال، هارمونی از به‌روزترین استانداردهای امنیتی و رمزنگاری برای جلوگیری از چنین حوادثی بهره می‌برد.\n\n۴. قصور کاربر در حفاظت از اطلاعات: چنانچه اطلاعات حساب کاربری به دلیل سهل‌انگاری یا اشتباه کاربر افشا شود، هارمونی مسئولیتی در این خصوص ندارد. تشخیص چنین مواردی بر اساس لاگ‌های امنیتی سیستم، بر عهده مدیر فنی هارمونی خواهد بود.\n\n۵. ثبت دقیق فعالیت‌ها در لاگ‌ها: تمامی رویدادهای مرتبط با ثبت، ویرایش و حذف اطلاعات در سیستم، به‌صورت دقیق و غیرقابل‌تغییر در لاگ کاربران ثبت می‌گردد. هرگونه ادعا مبنی بر حذف یا تغییر داده‌ها بدون ردپای لاگ قابل پذیرش نیست مگر با ارائه مستندات از سوی کاربر.\n\n۶. به‌روزرسانی خدمات: خدمات هارمونی ممکن است به مرور زمان به‌روزرسانی یا تغییر پیدا کند. ادامه استفاده از سیستم پس از اعمال تغییرات به معنای پذیرش مقررات جدید است. در صورت عدم موافقت، کاربر می‌تواند درخواست حذف حساب خود را ارائه دهد.\n\n۷. پشتیبانی کاربران: پشتیبانی خدمات صرفاً از طریق ایمیل و تماس تلفنی صورت می‌گیرد و رایگان است. هارمونی تعهدی به ارائه پشتیبانی حضوری یا آموزش‌های فراتر از خدمات پایه ندارد.\n\n۸. راه‌های ارتباط رسمی: هارمونی تنها از طریق شماره تلفن و ایمیل ثبت‌شده در حساب کاربر با وی در ارتباط خواهد بود. اطلاعیه‌ها و اعلانات رسمی از این مسیرها انجام می‌گیرد.\n\n۹. دامنه‌های رسمی ارتباط: تمام ایمیل‌های ارسالی از سوی هارمونی صرفاً با دامنه‌ی harmony.id ارسال می‌شود. کاربران موظف به بررسی این نشانی برای جلوگیری از فیشینگ و حملات مشابه هستند.\n\n۱۰. رعایت قوانین جمهوری اسلامی ایران: کاربر موظف است در استفاده از سیستم، کلیه قوانین جاری کشور، از جمله «قانون تجارت الکترونیکی»، «قانون جرائم رایانه‌ای» و سایر قوانین مرتبط را رعایت نماید. مسئولیت هرگونه تخلف بر عهده کاربر خواهد بود.\n\n۱۱. نگهداری موقت اطلاعات پس از فسخ حساب: در صورت فسخ یا حذف حساب، اطلاعات کاربر به مدت ۳۰ روز در فضای امن نگهداری می‌شود و پس از آن، به‌طور غیرقابل‌بازگشت حذف خواهد شد.\n\n۱۲. مالکیت اطلاعات کاربر: تمام اطلاعات ثبت‌شده توسط کاربر متعلق به خود اوست و هارمونی هیچ‌گونه مالکیتی بر این اطلاعات ندارد. کاربر مسئول صحت، کیفیت و قانونی بودن داده‌های خود می‌باشد.\n\n۱۳. استفاده هدفمند از اطلاعات شناسایی: اطلاعات هویتی جمع‌آوری‌شده هنگام ثبت‌نام تنها برای احراز هویت و ارائه خدمات پایه مورد استفاده قرار می‌گیرد. این اطلاعات بدون رضایت صریح کاربر، به هیچ نهاد یا شخص ثالثی منتقل نخواهد شد. تبصره: اطلاعات هویتی کاربران صرفاً در صورت حکم مقام قضایی یا مراجع ذی‌صلاح و در چارچوب قوانین، قابل ارائه خواهد بود.\n\n۱۴. محرمانگی دائمی داده‌ها: هارمونی متعهد است حتی پس از اتمام رابطه کاربری یا انحلال حساب، اطلاعات جمع‌آوری‌شده را به عنوان محرمانه حفظ نماید.\n\n۱۵. محدودیت مسئولیت: هارمونی مسئولیتی در قبال خسارات مستقیم یا غیرمستقیمی که به دلیل استفاده یا عدم استفاده از خدمات احراز هویت ایجاد شود، نخواهد داشت.\n\n۱۶. اختلال در بسترهای ارتباطی: هارمونی در برابر اختلال‌های ناشی از شبکه اینترنت، خدمات زیرساختی یا هرگونه مشکل خارج از کنترل خود، مسئولیتی ندارد.\n\n۱۷. حوادث قهری و غیرمترقبه: در صورت وقوع بلایای طبیعی، اعتصاب، قطعی برق، حملات سایبری یا هرگونه رخداد خارج از کنترل هارمونی که مانع ارائه خدمات شود، مسئولیتی متوجه هارمونی نخواهد بود.\n\n۱۸. خدمات وابسته به سایر سرویس‌ها: چنانچه بخشی از خدمات احراز هویت توسط شرکت‌های ثالث ارائه شود، قوانین استفاده از این سرویس‌ها بر عهده همان شرکت‌هاست و هارمونی نسبت به آن‌ها مسئولیتی ندارد.\n\n۱۹. تضمین دسترسی به اطلاعات در صورت توقف فعالیت: در صورت توقف دائمی فعالیت هارمونی، این شرکت متعهد است به مدت دو سال، سرورها را فعال نگه دارد و امکان دسترسی کاربران به اطلاعات خود را فراهم سازد.\n\n۲۰. اطلاع‌رسانی در مورد قطع سرویس‌ها: در صورت نیاز به توقف خدمات، هارمونی موظف است حداقل ۱۲ ساعت قبل، این موضوع را از طریق ایمیل یا پیامک به اطلاع کاربران برساند.", + "successfulCodeSent": "کد تایید با موفقیت ارسال شد.", + "problem": "مشکلی پیش آمده" }, "validation": { "firstNameRequired": "وارد کردن نام الزامی است.", diff --git a/public/locales/fa/setting.json b/public/locales/fa/setting.json index 5a33613..e469895 100644 --- a/public/locales/fa/setting.json +++ b/public/locales/fa/setting.json @@ -70,7 +70,8 @@ "errorSendCode": "ارسال کد با خطا مواجه شد", "phoneVerified": "تلفن همراه تایید شد", "errorConfirmCode": "تایید کد با خطا مواجه شد", - "errorChangePhone": "تغییر تلفن همراه با خطا مواجه شد" + "errorChangePhone": "تغییر تلفن همراه با خطا مواجه شد", + "verificationCodeSent": "کد تایید ارسال شد" }, "active": { diff --git a/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx b/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx index 6ec07f3..e85c694 100644 --- a/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx +++ b/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx @@ -99,7 +99,7 @@ export const CompleteSignUp = ({ helperText={inputError ? error : ''} autoFocus slotProps={{ - htmlInput: { dir: 'auto', sx: { lineHeight: 1.5, paddingX: 0 } }, + htmlInput: { dir: 'auto', sx: { lineHeight: 1.5 } }, input: { endAdornment: ( ) => { let newValue = event.target.value; + newValue = replacePersianWithRealNumbers(newValue); if (newValue.startsWith('09')) { newValue = newValue.substring(1); } @@ -152,7 +153,7 @@ export function LoginRegisterForm({ helperText={inputError ? error : ''} autoFocus slotProps={{ - htmlInput: { dir: 'auto', sx: { lineHeight: 1.5, paddingX: 0 } }, + htmlInput: { dir: 'auto', sx: { lineHeight: 1.5 } }, input: { endAdornment: ( { + if (otpCode.length === 4) { + handleVerifyOTP(); + } + }, [otpCode]); + useEffect(() => { let interval: NodeJS.Timeout; if (resendTimer > 0) { diff --git a/src/features/authentication/components/AuthenticationSteps/VerifyPhoneNumber.tsx b/src/features/authentication/components/AuthenticationSteps/VerifyPhoneNumber.tsx index 2b9b0fc..9943fe3 100644 --- a/src/features/authentication/components/AuthenticationSteps/VerifyPhoneNumber.tsx +++ b/src/features/authentication/components/AuthenticationSteps/VerifyPhoneNumber.tsx @@ -35,6 +35,12 @@ export function VerifyPhoneNumber({ const { loading: confirmSmsOtpLoading, execute: confirmSmsOtpCall } = useApi(confirmSmsOtp); + useEffect(() => { + if (otpCode.length === 4) { + handleVerifyOTP(); + } + }, [otpCode]); + useEffect(() => { let interval: NodeJS.Timeout; if (resendTimer > 0) { diff --git a/src/features/authentication/components/CountryCodeSelector.tsx b/src/features/authentication/components/CountryCodeSelector.tsx index 2aa9709..fd42dac 100644 --- a/src/features/authentication/components/CountryCodeSelector.tsx +++ b/src/features/authentication/components/CountryCodeSelector.tsx @@ -16,6 +16,7 @@ import { useTranslation } from 'react-i18next'; import { countries, type Country } from '../../../data/countries'; import type { CountryCode } from '@/types/commonTypes'; import { Icon } from '@rkheftan/harmony-ui'; +import { LTRBox } from '@/components/common/LTRBox'; interface CountryCodeSelectorProps { show: boolean; value: CountryCode; @@ -187,7 +188,9 @@ export function CountryCodeSelector({ {filteredCountries.length === 0 ? ( - {t('messages.noResualtFound')} + + {t('messages.noResualtFound', { ns: 'common' })} + ) : ( @@ -209,7 +212,9 @@ export function CountryCodeSelector({ - {country.phone} + + {country.phone} + )) diff --git a/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx b/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx index e9c8045..d914114 100644 --- a/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx +++ b/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx @@ -48,6 +48,12 @@ export function ForgetPasswordOtp({ execute: confirmForgetPassCodeCall, } = useApi(confirmForgetPassCode); + useEffect(() => { + if (otpCode.length === 4) { + handleVerifyOTP(); + } + }, [otpCode]); + useEffect(() => { let interval: NodeJS.Timeout; if (resendTimer > 0) { diff --git a/src/features/authentication/components/ForgetPassword/ForgettedPasswordInfo.tsx b/src/features/authentication/components/ForgetPassword/ForgettedPasswordInfo.tsx index 0ab10ab..5b2df84 100644 --- a/src/features/authentication/components/ForgetPassword/ForgettedPasswordInfo.tsx +++ b/src/features/authentication/components/ForgetPassword/ForgettedPasswordInfo.tsx @@ -12,6 +12,7 @@ import type { SendForgetPassCodeRequest } from '../../types/userTypes'; import { isPhoneNumber } from '@/utils/regexes/isValidPhoneNumber'; import { useToast } from '@rkheftan/harmony-ui'; import { useApi } from '@/hooks/useApi'; +import { replacePersianWithRealNumbers } from '@/utils/replacePersianWithRealNumbers'; export interface ForgettedPasswordInfoProps { forgettedPasswordInfo: string; @@ -46,6 +47,7 @@ export function ForgettedPasswordInfo({ const handleInputChange = (event: React.ChangeEvent) => { let newValue = event.target.value; + newValue = replacePersianWithRealNumbers(newValue); if (newValue.startsWith('09')) { newValue = newValue.substring(1); } @@ -138,7 +140,7 @@ export function ForgettedPasswordInfo({ helperText={inputError ? error : ''} autoFocus slotProps={{ - htmlInput: { dir: 'auto', sx: { lineHeight: 1.5, paddingX: 0 } }, + htmlInput: { dir: 'auto', sx: { lineHeight: 1.5 } }, input: { endAdornment: ( ('year'); const { Adapter, locale, formatString, dayOfWeekFormatter } = useMemo(() => { if (isFarsi) { @@ -44,11 +44,7 @@ export default function DateOfBirth({ value, onChange }: DateOfBirthProps) { const dayNumber = isFarsi ? formatJalali(props.day, 'dd') : format(props.day, 'dd'); - return ( - - {toLocaleDigits(dayNumber, i18n.language)} - - ); + return {dayNumber}; }; const CustomCalendarIcon = () => ( @@ -58,23 +54,23 @@ export default function DateOfBirth({ value, onChange }: DateOfBirthProps) { return ( setOpenView(newView)} + onYearChange={() => setOpenView('month')} slotProps={{ - textField: { - fullWidth: true, - }, + textField: { fullWidth: true }, popper: { sx: { - '& .MuiDateCalendar-root': { - // TODO: fix this to use textfield width instead of defining hardcode - width: '309px', - }, + '& .MuiDateCalendar-root': { width: '309px' }, }, }, }} diff --git a/src/features/authentication/components/UserCompletionForm/EmailSection.tsx b/src/features/authentication/components/UserCompletionForm/EmailSection.tsx index 8f4344e..9eed37b 100644 --- a/src/features/authentication/components/UserCompletionForm/EmailSection.tsx +++ b/src/features/authentication/components/UserCompletionForm/EmailSection.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { TextField, Box, @@ -13,30 +13,35 @@ import { useTranslation } from 'react-i18next'; import { TickCircle, Edit2 } from 'iconsax-react'; import { Icon } from '@rkheftan/harmony-ui'; import { type EmailSectionProps } from '../../types/settingForm'; -import { toLocaleDigits } from '@/utils/persianDigit'; import { isNumeric } from '@/utils/regexes/isNumeric'; +import { sanitizeLocalNumber } from '@/utils/regexes/sanitizeNumber'; -export function EmailSection({ - showEmail, - setShowEmail, - email, - setEmail, - codeSent, - verificationCode, - setVerificationCode, - buttonState, - handleSendCode, - handleVerifyCode, - emailVerified, - isVerifyingCode, - isSendingCode, - handleEditEmail, - errors, - touched, - handleBlur, - countdown, -}: EmailSectionProps) { - const { t, i18n } = useTranslation('completionForm'); +const ADORN_W = 24; +const INPUT_H = 56; + +export function EmailSection(props: EmailSectionProps) { + const { + showEmail, + setShowEmail, + email, + setEmail, + codeSent, + verificationCode, + setVerificationCode, + buttonState, + handleSendCode, + handleVerifyCode, + emailVerified, + isVerifyingCode, + isSendingCode, + handleEditEmail, + errors, + touched, + handleBlur, + countdown, + } = props; + + const { t } = useTranslation('completionForm'); const handleToggleEmail = (e: React.ChangeEvent) => { setShowEmail(e.target.checked); @@ -45,29 +50,31 @@ export function EmailSection({ const handleVerificationCodeChange = ( e: React.ChangeEvent, ) => { - const value = e.target.value; - // Allow only digits and enforce the max length - if (isNumeric(value) && value.length <= 4) { - setVerificationCode(value); + const normalized = sanitizeLocalNumber(e.target.value); + if (isNumeric(normalized) && normalized.length <= 4) { + setVerificationCode(normalized); } }; const formatTimerValue = () => { const m = String(Math.floor(countdown / 60)).padStart(2, '0'); const s = String(countdown % 60).padStart(2, '0'); - return toLocaleDigits(`${m}:${s}`, i18n.language); + return `${m}:${s}`; }; + useEffect(() => { + if (buttonState !== 'counting') { + setVerificationCode(''); + } + }, [buttonState, setVerificationCode]); + + const showCodeSection = + showEmail && codeSent && !emailVerified && buttonState === 'counting'; + return ( <> - + + {showEmail && ( - + setEmail(e.target.value)} onBlur={() => handleBlur('email')} disabled={isSendingCode || codeSent} error={touched.email && !!errors.email} helperText={touched.email && errors.email} - sx={{ flex: '1 1 260px' }} + sx={{ + flex: '1 1 260px', + '& .MuiOutlinedInput-root': { height: INPUT_H }, + }} slotProps={{ input: { - startAdornment: - !isVerifyingCode && emailVerified ? ( - - - - ) : null, - endAdornment: codeSent ? ( - - - - + startAdornment: ( + + + + + + - ) : null, + ), + endAdornment: ( + + + + + + + + + + ), }, }} /> + {!isVerifyingCode && !emailVerified && (buttonState === 'counting' ? ( @@ -140,6 +177,8 @@ export function EmailSection({ width: { xs: '100%', sm: '156px' }, alignSelf: 'center', textAlign: 'center', + lineHeight: `${INPUT_H}px`, + height: INPUT_H, }} color="primary" variant="body1" @@ -154,41 +193,53 @@ export function EmailSection({ sx={{ width: { xs: '100%', sm: '156px' }, alignSelf: 'center', + height: INPUT_H, }} > {t('completion.vericationCodeButton')} ))} - {!emailVerified && codeSent && ( + + {showCodeSection && ( handleBlur('verificationCode')} error={touched.verificationCode && !!errors.verificationCode} helperText={touched.verificationCode && errors.verificationCode} + inputProps={{ + inputMode: 'numeric', + pattern: '[0-9]*', + maxLength: 4, + }} /> + @@ -98,12 +98,6 @@ export default function SocialMediaMenu({ {t('settingForm.google')} - - - - - {t('settingForm.apple')} - ); diff --git a/src/utils/regexes/normalizeDigits.ts b/src/utils/regexes/normalizeDigits.ts new file mode 100644 index 0000000..f4c9963 --- /dev/null +++ b/src/utils/regexes/normalizeDigits.ts @@ -0,0 +1,9 @@ +const PERSIAN = '۰۱۲۳۴۵۶۷۸۹'; +const ARABIC = '٠١٢٣٤٥٦٧٨٩'; +export const normalizeDigits = (str: string) => + str.replace(/[\u06F0-\u06F9\u0660-\u0669]/g, (d) => { + const iP = PERSIAN.indexOf(d); + if (iP !== -1) return String(iP); + const iA = ARABIC.indexOf(d); + return iA !== -1 ? String(iA) : d; + }); diff --git a/src/utils/regexes/sanitizeNumber.ts b/src/utils/regexes/sanitizeNumber.ts new file mode 100644 index 0000000..6888bec --- /dev/null +++ b/src/utils/regexes/sanitizeNumber.ts @@ -0,0 +1,4 @@ +import { normalizeDigits } from './normalizeDigits'; + +export const sanitizeLocalNumber = (v: string) => + normalizeDigits(v).replace(/\D+/g, ''); diff --git a/src/utils/replacePersianWithRealNumbers.ts b/src/utils/replacePersianWithRealNumbers.ts new file mode 100644 index 0000000..fdaace5 --- /dev/null +++ b/src/utils/replacePersianWithRealNumbers.ts @@ -0,0 +1,10 @@ +export const replacePersianWithRealNumbers = (text: string): string => { + const persianDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; + return text + .split('') + .map((char) => { + const index = persianDigits.indexOf(char); + return index === -1 ? char : index.toString(); + }) + .join(''); +};