From 748463bcaf74587bfac1c6bce483793e7743c68e Mon Sep 17 00:00:00 2001 From: mortezaei Date: Mon, 17 Aug 2026 16:03:59 +0330 Subject: [PATCH] feat: add subscription required UI/translations and webview action tests --- WEBVIEW_ACTION_DOWNLOAD.md | 43 ++++ src/app/request-accepted/page.tsx | 3 +- .../Componentes/navigation-button.tsx | 186 +++++++++-------- .../subscription-required-sheet.tsx | 111 +++++----- src/lib/webview-actions.test.ts | 191 ++++++++++++++++++ src/translations/locales/ar.json | 6 +- src/translations/locales/az.json | 6 +- src/translations/locales/bn.json | 6 +- src/translations/locales/da.json | 6 +- src/translations/locales/de.json | 6 +- src/translations/locales/en.json | 6 +- src/translations/locales/es.json | 6 +- src/translations/locales/fa.json | 6 +- src/translations/locales/fr.json | 6 +- src/translations/locales/gu.json | 6 +- src/translations/locales/ha.json | 6 +- src/translations/locales/he.json | 6 +- src/translations/locales/hi.json | 6 +- src/translations/locales/id.json | 6 +- src/translations/locales/ks.json | 6 +- src/translations/locales/pt.json | 6 +- src/translations/locales/ru.json | 6 +- src/translations/locales/sw.json | 6 +- src/translations/locales/tg.json | 6 +- src/translations/locales/tr.json | 6 +- src/translations/locales/ul.json | 6 +- src/translations/locales/ur.json | 6 +- src/translations/locales/uz.json | 6 +- src/translations/locales/zh.json | 6 +- 29 files changed, 511 insertions(+), 167 deletions(-) create mode 100644 src/lib/webview-actions.test.ts diff --git a/WEBVIEW_ACTION_DOWNLOAD.md b/WEBVIEW_ACTION_DOWNLOAD.md index 9523df9..e9d4cec 100644 --- a/WEBVIEW_ACTION_DOWNLOAD.md +++ b/WEBVIEW_ACTION_DOWNLOAD.md @@ -973,6 +973,47 @@ void _handleUploadFile(dynamic payload) async { --- +## ۵. خرید حبیب کوین (`buy_coin`) + +### هدف + +وقتی کاربر برای پرداخت هزینه اشتراک یا معرفی مورد کوین کافی ندارد (دریافت خطای `Not enough coins` از سرور)، وب باید به کاربر دکمه‌ای برای شارژ حساب نمایش دهد. با کلیک کاربر، وب یک پیام JSON با اکشن `buy_coin` به Flutter ارسال می‌کند تا فلاتر به‌صورت native صفحه لیست پکیج‌های حبیب کوین (`PackagesListPage`) را روی WebView باز کند. کاربر پس از خرید پکیج و زدن دکمه بازگشت (Back)، مجدداً به همان صفحه وب بازمی‌گردد و می‌تواند پرداخت را تکرار کند. + +### Action اصلی + +```text +buy_coin +``` + +### پیام ارسالی از Web به Flutter + +```json +{ + "action": "buy_coin" +} +``` + +### امضای تابع در Web (src/lib/webview-actions.ts) + +```ts +/** + * Ask Flutter to open the Habib Coin packages list page (Add Coin). + */ +export function buyHabibCoinPackages(): boolean { + return postActionToFlutter("buy_coin"); +} +``` + +### رفتار سمت Flutter + +فلاتر بدون نیاز به payload اضافی اکشن `buy_coin` را دریافت کرده و صفحه خرید پکیج را باز می‌کند: + +```dart +'buy_coin' => context.pushPage(const PackagesListPage()), +``` + +--- + ## جمع‌بندی actionها | Action | کاربرد | @@ -981,3 +1022,5 @@ void _handleUploadFile(dynamic payload) async { | `upload_file` | انتخاب فایل/تصویر/ویدیو از دستگاه و آپلود به سرور (یا بازگرداندن base64) | | `copy_to_clipboard` | کپی متن در clipboard دستگاه | | `open_external_url` | باز کردن URL در مرورگر یا اپ خارجی | +| `buy_coin` | باز کردن صفحه خرید پکیج‌های حبیب کوین (`PackagesListPage`) در فلاتر | + diff --git a/src/app/request-accepted/page.tsx b/src/app/request-accepted/page.tsx index 1d54052..0f94681 100644 --- a/src/app/request-accepted/page.tsx +++ b/src/app/request-accepted/page.tsx @@ -312,7 +312,8 @@ export default function RequestAcceptedPage() { if (msg === "Not enough coins") { setIsInsufficientCoins(true); setPaymentError( - "Insufficient coin balance. Please recharge your account.", + t["Insufficient coin balance. Please recharge your account."] || + "Insufficient coin balance. Please recharge your account.", ); } else { setPaymentError(msg); diff --git a/src/components/Componentes/navigation-button.tsx b/src/components/Componentes/navigation-button.tsx index d332090..21065a8 100644 --- a/src/components/Componentes/navigation-button.tsx +++ b/src/components/Componentes/navigation-button.tsx @@ -1,29 +1,29 @@ "use client"; +import { useQueryClient } from "@tanstack/react-query"; import Image from "next/image"; import { useRouter } from "next/navigation"; import type { ButtonHTMLAttributes, ReactNode } from "react"; -import { useState, useRef, useEffect } from "react"; +import { useEffect, useRef, useState } from "react"; import { GoArrowLeft } from "react-icons/go"; import { HiEllipsisVertical } from "react-icons/hi2"; -import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main"; import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; -import { useI18n } from "@/translations/provider"; -import HelpModal from "./help-modal"; -import SupportSheet from "./support-sheet"; -import InformationSheet from "./information-sheet"; -import { useQueryClient } from "@tanstack/react-query"; -import { UiIcon } from "./ui-icon"; -import ErrorToast from "./error-toast"; -import { hasSupportAccess } from "./support-access"; import { - useHabcoinPaymentMutation, extractHabcoinPaymentUrl, + useHabcoinPaymentMutation, } from "@/hooks/marriage/use-habcoin-payment"; +import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main"; import { buyHabibCoinPackages, isInFlutterWebView, } from "@/lib/webview-actions"; +import { useI18n } from "@/translations/provider"; +import ErrorToast from "./error-toast"; +import HelpModal from "./help-modal"; +import InformationSheet from "./information-sheet"; +import { hasSupportAccess } from "./support-access"; +import SupportSheet from "./support-sheet"; +import { UiIcon } from "./ui-icon"; type NavigationButtonIcon = | "back" @@ -123,93 +123,93 @@ export function NavigationButton({ )}
- + - -
+ )} + + + )} /> @@ -272,9 +272,7 @@ export function NavigationButton({ case "info": return