feat(sub): redesign the subscription page around usage, tabs and app imports

The info page was a long key/value table followed by every link and two
app dropdowns, and it rendered left-to-right even for Persian and Arabic.
It now leads with a usage ring, the remaining quota and a stats grid, and
splits the rest into Subscription / Apps / Configs tabs.

- Status tells expired, data-used-up and disabled apart instead of one
  "Inactive", replacing the hard-coded English expiry chip.
- The Apps tab keeps every Android and iOS app with its existing deep
  link, preselects the visitor's platform and adds Windows: Hiddify and
  Clash Verge Rev import directly, v2rayN copies the link.
- fa-IR and ar-EG render right-to-left; URLs, IDs and sizes stay LTR.
- The footer shows the support link and the client refresh interval, so
  subPageContext now carries subUpdates (also in ?format=info).
- Status, days-left and app deep-link logic lives in subPageModel.ts,
  with unit tests pinning the deep links the page already shipped.
This commit is contained in:
Sanaei
2026-09-16 01:17:04 +02:00
parent 01ce2bcecb
commit e26cf1d3ed
42 changed files with 1869 additions and 877 deletions
+15 -3
View File
@@ -80,8 +80,6 @@
"somethingWentWrong": "مشکلی پیش آمد",
"subscription": {
"title": "اطلاعات سابسکریپشن",
"subId": "شناسه اشتراک",
"email": "ایمیل",
"status": "وضعیت",
"downloaded": "دانلود",
"uploaded": "آپلود",
@@ -93,7 +91,21 @@
"unlimited": "نامحدود",
"noExpiry": "بدون انقضا",
"copyAllConfigs": "کپی همه کانفیگ‌ها",
"copyAllConfigsCopied": "همه کانفیگ‌ها کپی شدند"
"copyAllConfigsCopied": "همه کانفیگ‌ها کپی شدند",
"daysLeft": "روز باقی‌مانده",
"expired": "منقضی شده",
"depleted": "حجم تمام شده",
"ofTotal": "از {total}",
"tabLinks": "اشتراک",
"tabApps": "اپلیکیشن‌ها",
"tabConfigs": "کانفیگ‌ها",
"scanTitle": "اسکن با گوشی",
"scanHint": "این کد را در اپلیکیشن VPN اسکن کنید تا اشتراک بدون کپی‌کردن لینک اضافه شود.",
"updateInterval": "به‌روزرسانی خودکار هر {hours} ساعت",
"support": "پشتیبانی",
"qrTitle": "اسکن. افزودن. اتصال.",
"qrHint": "با اپلیکیشن کلاینت اسکن کنید. این کد را به کسی ندهید.",
"saveQr": "ذخیره QR"
},
"menu": {
"theme": "تم",