Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@
"account_info": "Account Information",
"username": "Username",
"email": "Email",
"change_email": "Change email",
"change_email_subject": "Request to change Pushy account email",
"change_email_body": "Current account email: {{email}}\n\nPlease describe the new email address you want to use and include any required identity verification details.",
"service_version": "Plan",
"service_expire": "Expires",
"no_expire": "None",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@
"account_info": "账户信息",
"username": "用户名",
"email": "邮箱",
"change_email": "修改邮箱",
"change_email_subject": "申请修改 Pushy 账户邮箱",
"change_email_body": "当前账户邮箱:{{email}}\n\n请说明需要修改为的新邮箱,并附上必要的身份验证信息。",
"service_version": "服务版本",
"service_expire": "服务有效期至",
"no_expire": "无",
Expand Down
24 changes: 21 additions & 3 deletions src/pages/user/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { LogoutOutlined } from '@ant-design/icons';
import { useQueries, useQuery } from '@tanstack/react-query';
import { Button, Descriptions, Grid, message, Popover, Spin } from 'antd';
import {
Button,
Descriptions,
Grid,
message,
Popover,
Space,
Spin,
} from 'antd';
import { useTranslation } from 'react-i18next';
import { api } from '@/services/api';
import { logout } from '@/services/auth';
Expand All @@ -14,11 +22,13 @@ import {
} from './purchase-controls';
import { QuotaDetailsPanel, type QuotaUsageRow } from './quota-details';

const SUPPORT_EMAIL = 'hi@charmlot.com';

const getInvoiceHint = (t: (key: string) => string) => (
<div>
<p>
{t('user.invoice_hint_before_email')}
<a href="mailto:hi@charmlot.com">hi@charmlot.com</a>
<a href={`mailto:${SUPPORT_EMAIL}`}>{SUPPORT_EMAIL}</a>
{t('user.invoice_hint_after_email')}
</p>
<p>
Expand Down Expand Up @@ -72,6 +82,9 @@ function UserPanel() {
);
}
const { name, email, tier, quota } = user;
const changeEmailHref = `mailto:${SUPPORT_EMAIL}?subject=${encodeURIComponent(
t('user.change_email_subject'),
)}&body=${encodeURIComponent(t('user.change_email_body', { email }))}`;
const defaultQuota = quotas[tier as keyof typeof quotas];
const currentQuota = quota || defaultQuota;

Expand Down Expand Up @@ -178,7 +191,12 @@ function UserPanel() {
>
<Descriptions.Item label={t('user.username')}>{name}</Descriptions.Item>
<Descriptions.Item label={t('user.email')}>
<span className="break-all">{email}</span>
<Space size="small" wrap className="min-w-0">
<span className="break-all">{email}</span>
<Button href={changeEmailHref} size="small" type="link">
{t('user.change_email')}
</Button>
</Space>
</Descriptions.Item>
<Descriptions.Item label={t('user.service_version')}>
<div className="grid min-w-0 gap-3 sm:grid-cols-[minmax(160px,180px)_160px] sm:items-center">
Expand Down