From e964780e6fc3325cca7d3c81582eb67158c994e9 Mon Sep 17 00:00:00 2001 From: Fringg Date: Sat, 16 May 2026 04:07:25 +0300 Subject: [PATCH] refactor(devices): close all MED/LOW review items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Extract DEVICE_ALIAS_MAX_LENGTH to src/constants/devices.ts so the user page and admin page share one source of truth (mirroring the bot's ALIAS_MAX_LENGTH=64). Was duplicated as a magic 64 in both files (MED-5). - Replace ✓ / ✕ / ✏️ glyphs in AdminUserDetail.tsx with inline SVGs, matching the icon style already used by Subscription.tsx for the same rename/save/cancel actions. Eliminates the platform-dependent emoji rendering inconsistency (MED-4). - Add haptic feedback to the user-side renameDeviceMutation — notification('success') on save, notification('error') on failure. Brings it in line with the other Subscription.tsx mutations (LOW-9). - Translate the new rename keys into zh.json and fa.json (en.json already covered in the previous follow-up). Cabinet now ships full parity across all 4 locales for the rename UI. --- src/constants/devices.ts | 8 +++++ src/locales/fa.json | 10 +++++- src/locales/zh.json | 10 +++++- src/pages/AdminUserDetail.tsx | 63 +++++++++++++++++++++++++++++++---- src/pages/Subscription.tsx | 7 +++- 5 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 src/constants/devices.ts diff --git a/src/constants/devices.ts b/src/constants/devices.ts new file mode 100644 index 0000000..5cfcc17 --- /dev/null +++ b/src/constants/devices.ts @@ -0,0 +1,8 @@ +/** + * Maximum length of a user-set local device alias. + * + * Mirrors `ALIAS_MAX_LENGTH` in the bot's `user_device_aliases` table. + * Keep this value in sync with `app/database/crud/user_device_alias.py` + * (Python side enforces it at the DB column width AND at the API layer). + */ +export const DEVICE_ALIAS_MAX_LENGTH = 64; diff --git a/src/locales/fa.json b/src/locales/fa.json index c26fb6d..d67089d 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -454,6 +454,11 @@ "month": "ماه", "myDevices": "دستگاه‌های من", "noDevices": "هیچ دستگاه متصلی نیست", + "renameDevice": "تغییر نام", + "renameDeviceSave": "ذخیره", + "renameDeviceCancel": "لغو", + "renameDevicePlaceholder": "نام دستگاه", + "deviceRenamed": "نام دستگاه به‌روزرسانی شد", "perExtraDevice": "/ دستگاه اضافی", "perMonth": "/ماه", "purchasedTraffic": "ترافیک خریداری شده", @@ -2667,7 +2672,10 @@ "none": "دستگاه متصلی وجود ندارد", "resetAll": "بازنشانی همه", "deleted": "دستگاه حذف شد", - "allDeleted": "همه دستگاه‌ها بازنشانی شدند" + "allDeleted": "همه دستگاه‌ها بازنشانی شدند", + "rename": "تغییر نام", + "renameSave": "ذخیره", + "renamed": "نام دستگاه به‌روزرسانی شد" }, "referral": { "title": "برنامه ارجاع", diff --git a/src/locales/zh.json b/src/locales/zh.json index dcac98d..5b5860f 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -454,6 +454,11 @@ "month": "月", "myDevices": "我的设备", "noDevices": "没有已连接的设备", + "renameDevice": "重命名", + "renameDeviceSave": "保存", + "renameDeviceCancel": "取消", + "renameDevicePlaceholder": "设备名称", + "deviceRenamed": "设备名称已更新", "perExtraDevice": "/ 额外设备", "perMonth": "/月", "purchasedTraffic": "已购流量", @@ -2666,7 +2671,10 @@ "none": "没有已连接的设备", "resetAll": "重置全部", "deleted": "设备已删除", - "allDeleted": "所有设备已重置" + "allDeleted": "所有设备已重置", + "rename": "重命名", + "renameSave": "保存", + "renamed": "设备名称已更新" }, "referral": { "title": "推荐计划", diff --git a/src/pages/AdminUserDetail.tsx b/src/pages/AdminUserDetail.tsx index 19fd343..6ae22c6 100644 --- a/src/pages/AdminUserDetail.tsx +++ b/src/pages/AdminUserDetail.tsx @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback, useRef, useMemo } from 'react'; import { useParams, useNavigate } from 'react-router'; import { useTranslation } from 'react-i18next'; import i18n from '../i18n'; +import { DEVICE_ALIAS_MAX_LENGTH } from '../constants/devices'; import { useCurrency } from '../hooks/useCurrency'; import { useNotify } from '../platform/hooks/useNotify'; import { @@ -2479,7 +2480,7 @@ export default function AdminUserDetail() { type="text" autoFocus value={editingDeviceName} - maxLength={64} + maxLength={DEVICE_ALIAS_MAX_LENGTH} placeholder={ device.platform || device.device_model || @@ -2522,7 +2523,7 @@ export default function AdminUserDetail() { type="button" onClick={() => handleRenameDevice(device.hwid)} disabled={renameSaving} - className="rounded-lg px-2 py-1 text-xs text-success-400 transition-all hover:bg-success-500/15 disabled:opacity-50" + className="rounded-lg px-2 py-1 text-success-400 transition-all hover:bg-success-500/15 disabled:opacity-50" title={t( 'admin.users.detail.devices.renameSave', t( @@ -2530,8 +2531,24 @@ export default function AdminUserDetail() { '\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C', ), )} + aria-label={t( + 'admin.users.detail.devices.renameSave', + '\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C', + )} > - {'\u2713'} + ) : ( @@ -2557,13 +2590,29 @@ export default function AdminUserDetail() { setEditingDeviceHwid(device.hwid); setEditingDeviceName(device.local_name || ''); }} - className="rounded-lg px-2 py-1 text-xs text-dark-500 transition-all hover:bg-accent-500/15 hover:text-accent-400" + className="rounded-lg px-2 py-1 text-dark-500 transition-all hover:bg-accent-500/15 hover:text-accent-400" title={t( 'admin.users.detail.devices.rename', '\u041F\u0435\u0440\u0435\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u0442\u044C', )} + aria-label={t( + 'admin.users.detail.devices.rename', + '\u041F\u0435\u0440\u0435\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u0442\u044C', + )} > - {'\u270F\uFE0F'} +