feat: 完成代码编写
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
'use client';
|
||||
|
||||
import { queryAnnouncement } from '@/services/user/announcement';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import {
|
||||
ColumnFiltersState,
|
||||
getCoreRowModel,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
PaginationState,
|
||||
useReactTable,
|
||||
} from '@tanstack/react-table';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@workspace/airo-ui/components/dialog';
|
||||
import { Pagination } from '@workspace/airo-ui/custom-components/pro-table/pagination';
|
||||
import { useImperativeHandle, useRef, useState } from 'react';
|
||||
import { Popup, PopupData, PopupRef } from './Popup';
|
||||
|
||||
export interface AnnouncementItem {
|
||||
id: number;
|
||||
title: string;
|
||||
content: string;
|
||||
pinned?: boolean;
|
||||
}
|
||||
|
||||
export interface DialogRef {
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
interface DialogProps {
|
||||
ref?: React.Ref<DialogRef>;
|
||||
}
|
||||
|
||||
export const AnnouncementDialog = ({ ref }: DialogProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [pagination, setPagination] = useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
pageSize: 10,
|
||||
});
|
||||
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
||||
const popupRef = useRef<PopupRef>(null);
|
||||
|
||||
const { data: announcementData, isLoading } = useQuery({
|
||||
queryKey: ['queryAnnouncement', pagination.pageIndex + 1, pagination.pageSize],
|
||||
queryFn: async () => {
|
||||
const { data } = await queryAnnouncement({
|
||||
page: pagination.pageIndex + 1,
|
||||
size: pagination.pageSize,
|
||||
pinned: true,
|
||||
popup: true,
|
||||
});
|
||||
return {
|
||||
list: data.data?.announcements || [],
|
||||
total: data.data?.total || 0,
|
||||
};
|
||||
},
|
||||
enabled: open, // 只在弹窗打开时查询数据
|
||||
});
|
||||
|
||||
const table = useReactTable({
|
||||
data: announcementData?.list || [],
|
||||
columns: [],
|
||||
onPaginationChange: setPagination,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
state: {
|
||||
columnFilters,
|
||||
pagination,
|
||||
},
|
||||
manualPagination: true,
|
||||
manualFiltering: true,
|
||||
rowCount: announcementData?.total || 0,
|
||||
});
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
setOpen(true);
|
||||
},
|
||||
close: () => {
|
||||
setOpen(false);
|
||||
},
|
||||
}));
|
||||
|
||||
const handleOpenPopup = (item: AnnouncementItem) => {
|
||||
const popupData: PopupData = {
|
||||
title: item.title,
|
||||
content: item.content,
|
||||
};
|
||||
popupRef.current?.open(popupData);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className='flex flex-col sm:grid sm:max-w-[600px]'>
|
||||
<DialogHeader>
|
||||
<DialogTitle className={'text-left text-2xl sm:text-4xl'}>网站公告</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className='space-y-4'>
|
||||
{isLoading ? (
|
||||
<div className='py-8 text-center'>加载中...</div>
|
||||
) : (
|
||||
<>
|
||||
{announcementData?.list?.map((item: AnnouncementItem) => {
|
||||
return (
|
||||
<div
|
||||
key={item.id}
|
||||
className='flex items-center rounded-[20px] bg-[#B5C9E2] px-4 py-2 sm:p-4'
|
||||
>
|
||||
<p className='line-clamp-2 flex-1 text-[10px] text-[#225BA9] sm:text-sm'>
|
||||
{item.pinned && '【置顶公告】'}{' '}
|
||||
<span className={`${item.pinned ? 'text-white' : 'text-[#4D4D4D]'}`}>
|
||||
{item.content}
|
||||
</span>
|
||||
</p>
|
||||
<div className='ml-2 w-[65px] text-right'>
|
||||
<span
|
||||
className='cursor-pointer text-xs text-[#225BA9] sm:text-sm'
|
||||
onClick={() => handleOpenPopup(item)}
|
||||
>
|
||||
查看详情
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* 使用 table 的分页器组件 */}
|
||||
{announcementData && announcementData.list && announcementData.list.length > 0 && (
|
||||
<div className='mt-6'>
|
||||
<Pagination
|
||||
table={table}
|
||||
text={{
|
||||
textRowsPerPage: '每页显示',
|
||||
textPageOf: (pageIndex, pageCount) =>
|
||||
`第 ${pageIndex} 页,共 ${pageCount} 页`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Popup ref={popupRef} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@workspace/airo-ui/components/dialog';
|
||||
import { Markdown } from '@workspace/ui/custom-components/markdown';
|
||||
import { useImperativeHandle, useState } from 'react';
|
||||
|
||||
export interface PopupData {
|
||||
title: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface PopupRef {
|
||||
open: (data: PopupData) => void;
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
interface PopupProps {
|
||||
ref?: React.Ref<PopupRef>;
|
||||
}
|
||||
|
||||
export const Popup = ({ ref }: PopupProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [data, setData] = useState<PopupData>({ title: '', content: '' });
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: (newData: PopupData) => {
|
||||
setData(newData);
|
||||
setOpen(true);
|
||||
},
|
||||
close: () => {
|
||||
setOpen(false);
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className='max-h-[350px] min-h-[220px] max-w-[80%] rounded-[25px] sm:max-w-[425px]'>
|
||||
<DialogHeader>
|
||||
<DialogTitle className={'sr-only'}>{data.title}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className={'pt-[30%]'}>
|
||||
<div className={'mb-4 text-xl'}>{data.title}</div>
|
||||
<Markdown>{data.content}</Markdown>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
@@ -18,10 +18,20 @@ import {
|
||||
} from '@workspace/ui/components/select';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
import {
|
||||
AnnouncementDialog,
|
||||
DialogRef,
|
||||
} from '@/app/(main)/(content)/(user)/dashboard/components/Announcement/Dialog';
|
||||
import {
|
||||
Popup,
|
||||
PopupRef,
|
||||
} from '@/app/(main)/(content)/(user)/dashboard/components/Announcement/Popup';
|
||||
import { Empty } from '@/components/empty';
|
||||
import { queryAnnouncement } from '@/services/user/announcement';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@workspace/airo-ui/components/popover';
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
@@ -35,6 +45,7 @@ import {
|
||||
} from '@workspace/ui/components/alert-dialog';
|
||||
import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
|
||||
import { differenceInDays, formatDate } from '@workspace/ui/utils';
|
||||
import { QRCodeCanvas } from 'qrcode.react';
|
||||
|
||||
const platforms: (keyof API.ApplicationPlatform)[] = [
|
||||
'windows',
|
||||
@@ -81,6 +92,19 @@ export default function Content() {
|
||||
protocol: ['vmess', 'vless'],
|
||||
};
|
||||
|
||||
const { data: announcementData } = useQuery({
|
||||
queryKey: ['queryAnnouncement'],
|
||||
queryFn: async () => {
|
||||
const { data } = await queryAnnouncement({
|
||||
page: 1,
|
||||
size: 4,
|
||||
pinned: true,
|
||||
popup: true,
|
||||
});
|
||||
return data.data?.announcements || [];
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data && userSubscribe?.length > 0 && !userSubscribeProtocol.length) {
|
||||
const list = getUserSubscribe(userSubscribe[0]?.token, data.protocol);
|
||||
@@ -97,20 +121,31 @@ export default function Content() {
|
||||
|
||||
const { user } = useGlobalStore();
|
||||
const totalAssets = (user?.balance || 0) + (user?.commission || 0) + (user?.gift_amount || 0);
|
||||
|
||||
// 获取当前选中项的显示标签
|
||||
const getCurrentLabel = () => {
|
||||
const currentIndex = userSubscribeProtocol.findIndex(
|
||||
(url) => url === userSubscribeProtocolCurrent,
|
||||
);
|
||||
return currentIndex !== -1 ? `${t('subscriptionUrl')}${currentIndex + 1}` : '地址1';
|
||||
};
|
||||
|
||||
const popupRef = useRef<PopupRef>(null);
|
||||
const dialogRef = useRef<DialogRef>(null);
|
||||
return (
|
||||
<>
|
||||
<div className={'grid grid-cols-1 gap-6 lg:grid-cols-2'}>
|
||||
<div className={'grid grid-cols-1 gap-[10px] sm:gap-6 lg:grid-cols-2'}>
|
||||
{/* 账户概况 Card */}
|
||||
<Card className='rounded-[20px] border border-[#D9D9D9] p-6 shadow-[0px_0px_52.6px_1px_rgba(15,44,83,0.05)]'>
|
||||
<div className='mb-4'>
|
||||
<h3 className='text-xl font-medium text-[#666666]'>账户概况</h3>
|
||||
<p className='mt-1 text-sm text-[#666666]'>
|
||||
<div className='mb-1 sm:mb-4'>
|
||||
<h3 className='text-base font-medium text-[#666666] sm:text-xl'>账户概况</h3>
|
||||
<p className='mt-1 text-xs text-[#666666] sm:text-sm'>
|
||||
{user?.auth_methods?.[0]?.auth_identifier}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='mb-6'>
|
||||
<span className='text-3xl font-medium text-[#091B33]'>年度套餐用户</span>
|
||||
<div className='mb-3 sm:mb-6'>
|
||||
<span className='text-2xl font-medium text-[#091B33] sm:text-3xl'>年度套餐用户</span>
|
||||
</div>
|
||||
|
||||
<div className='rounded-[20px] bg-[#EAEAEA] px-4 py-[10px]'>
|
||||
@@ -122,7 +157,7 @@ export default function Content() {
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='text-4xl font-medium text-[#225BA9]'>
|
||||
<div className='text-xl font-medium text-[#225BA9] sm:text-4xl'>
|
||||
<Display type='currency' value={totalAssets} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,7 +168,7 @@ export default function Content() {
|
||||
<div className='mb-4'>
|
||||
<h3 className='flex items-center justify-between text-[#666666]'>
|
||||
<div className={'flex items-center justify-between'}>
|
||||
<span className={'text-xl font-medium'}>套餐状态</span>
|
||||
<span className={'text-base font-medium sm:text-xl'}>套餐状态</span>
|
||||
<span className={'ml-2.5 rounded-full bg-[#A8D4ED] px-2 text-[8px] text-white'}>
|
||||
生效中
|
||||
</span>
|
||||
@@ -146,11 +181,11 @@ export default function Content() {
|
||||
replacement={userSubscribe?.[0]?.subscribe.replacement}
|
||||
/>
|
||||
</h3>
|
||||
<div className='mb-[22px] mt-1 text-sm text-[#666666]'>
|
||||
<div className='mb-2 text-sm text-[#666666] sm:mb-[22px] sm:mt-1'>
|
||||
套餐到期时间:{formatDate(userSubscribe?.[0]?.expire_time, false)}
|
||||
</div>
|
||||
<div className='mb-6'>
|
||||
<span className='text-3xl font-medium text-[#091B33]'>
|
||||
<div className='mb-3 sm:mb-6'>
|
||||
<span className='text-2xl font-medium text-[#091B33] sm:text-3xl'>
|
||||
{userSubscribe?.[0]?.subscribe.name}
|
||||
</span>
|
||||
</div>
|
||||
@@ -158,7 +193,7 @@ export default function Content() {
|
||||
|
||||
<div className='mb-4 flex items-center justify-between'>
|
||||
<div className='flex items-center gap-2'>
|
||||
<span className='text-sm'>可用设备</span>
|
||||
<span className='text-xs sm:text-sm'>可用设备</span>
|
||||
<div className='flex gap-2'>
|
||||
<div className='h-4 w-4 rounded-full bg-[#225BA9]'></div>
|
||||
<div className='h-4 w-4 rounded-full bg-[#D9D9D9]'></div>
|
||||
@@ -168,13 +203,13 @@ export default function Content() {
|
||||
<div className='h-4 w-4 rounded-full bg-[#D9D9D9]'></div>
|
||||
</div>
|
||||
</div>
|
||||
<span className='text-sm'>
|
||||
在线:undefined/{userSubscribe?.[0]?.subscribe.device_limit}
|
||||
<span className='text-xs sm:text-sm'>
|
||||
在线:uu/{userSubscribe?.[0]?.subscribe.device_limit}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className='mb-1 flex items-center justify-between'>
|
||||
<span className='text-sm'>
|
||||
<span className='text-xs sm:text-sm'>
|
||||
已使用流量/总流量:
|
||||
<Display
|
||||
type='traffic'
|
||||
@@ -188,7 +223,7 @@ export default function Content() {
|
||||
unlimited={!userSubscribe?.[0]?.traffic}
|
||||
/>
|
||||
</span>
|
||||
<span className='text-sm'>
|
||||
<span className='text-xs sm:text-sm'>
|
||||
剩余:
|
||||
{100 -
|
||||
(
|
||||
@@ -209,78 +244,73 @@ export default function Content() {
|
||||
</div>
|
||||
</Card>
|
||||
{/* 网站公告 Card */}
|
||||
<Card className='relative rounded-[20px] border border-[#EAEAEA] bg-gradient-to-b from-white to-[#EAEAEA] p-6 pb-0'>
|
||||
<Card className='relative order-4 rounded-[20px] border border-[#EAEAEA] bg-gradient-to-b from-white to-[#EAEAEA] p-6 pb-0 sm:order-none'>
|
||||
<div
|
||||
className={'absolute bottom-0 left-0 right-0 h-[60px] bg-white/30 backdrop-blur-[1px]'}
|
||||
></div>
|
||||
<div className='mb-4 flex items-center justify-between'>
|
||||
<h3 className='text-xl font-medium text-[#666666]'>网站公告</h3>
|
||||
<Button className='border-0 bg-transparent p-0 text-sm font-normal text-[#225BA9] shadow-none outline-0 hover:bg-transparent'>
|
||||
更多
|
||||
</Button>
|
||||
<div className='mb-3 flex items-center justify-between sm:mb-4'>
|
||||
<h3 className='text-base font-medium text-[#666666] sm:text-xl'>网站公告</h3>
|
||||
{announcementData?.length ? (
|
||||
<Button
|
||||
className='border-0 bg-transparent p-0 text-sm font-normal text-[#225BA9] shadow-none outline-0 hover:bg-transparent'
|
||||
onClick={() => dialogRef.current.open()}
|
||||
>
|
||||
更多
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className='space-y-4'>
|
||||
<div className='space-y-3 sm:space-y-4'>
|
||||
{/* 置顶公告 */}
|
||||
<div className='flex items-center rounded-[20px] bg-[#B5C9E2] p-4'>
|
||||
<p className='mb-2 line-clamp-2 flex-1 text-sm text-[#225BA9]'>
|
||||
【置顶公告】Airo
|
||||
Port提供IPLC/IEPL专线或BGP隧道中继,避免直连线路的拥堵,提供更低的延迟和更高的...
|
||||
</p>
|
||||
<div className='ml-2 w-[65px] text-right'>
|
||||
<span className='text-sm text-[#225BA9]'>查看详情</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 系统通知列表 */}
|
||||
<div className='space-y-3'>
|
||||
<div className='flex items-center gap-2 rounded-[20px] border bg-white p-4'>
|
||||
<p className='mb-2 line-clamp-2 flex-1 text-sm text-[#225BA9]'>
|
||||
【系统通知】充值成功
|
||||
<br />
|
||||
订单 ID:R20250729115302USDT 充值成功,钱包余额...
|
||||
</p>
|
||||
<div className='text-right'>
|
||||
<span className='text-sm text-[#225BA9]'>查看详情</span>
|
||||
{announcementData?.map((item) => {
|
||||
return (
|
||||
<div className='flex items-center rounded-[20px] bg-[#B5C9E2] px-4 py-2 sm:p-4'>
|
||||
<p className='line-clamp-2 flex-1 text-[10px] text-[#225BA9] sm:text-sm'>
|
||||
{item.pinned && '【置顶公告】'}{' '}
|
||||
<span className={`${item.pinned ? 'text-white' : 'text-[#4D4D4D]'}`}>
|
||||
{item.content}
|
||||
</span>
|
||||
</p>
|
||||
<div className='ml-2 w-[65px] text-right'>
|
||||
<span
|
||||
className='cursor-pointer text-xs text-[#225BA9] sm:text-sm'
|
||||
onClick={() => popupRef.current.open(item)}
|
||||
>
|
||||
查看详情
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='rounded-[20px] border bg-white p-4'>
|
||||
<p className='mb-2 line-clamp-2 flex-1 text-sm text-[#225BA9]'>
|
||||
【系统通知】充值成功
|
||||
<br />
|
||||
订单 ID:R20250729115302USDT 充值成功,钱包余额...
|
||||
</p>
|
||||
<div className='text-right'>
|
||||
<span className='text-sm text-[#225BA9]'>查看详情</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<Popup ref={popupRef} />
|
||||
<AnnouncementDialog ref={dialogRef} />
|
||||
</Card>
|
||||
|
||||
{/* 我的订阅 Card */}
|
||||
<Card className='rounded-[20px] border border-[#D9D9D9] p-6 shadow-[0px_0px_52.6px_1px_rgba(15,44,83,0.05)]'>
|
||||
<div className='mb-4 flex items-center justify-between'>
|
||||
<h3 className='text-xl font-medium text-[#666666]'>我的订阅</h3>
|
||||
<div className='flex items-center justify-between sm:mb-4'>
|
||||
<h3 className='text-base font-medium text-[#666666] sm:text-xl'>我的订阅</h3>
|
||||
<Link
|
||||
href={'/document'}
|
||||
className='border-0 bg-transparent p-0 text-sm font-normal text-[#225BA9] shadow-none outline-0 hover:bg-transparent'
|
||||
className='border-0 bg-transparent p-0 text-sm font-semibold text-[#225BA9] shadow-none outline-0 hover:bg-transparent sm:font-normal'
|
||||
>
|
||||
新手教程
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{userSubscribe?.[0] && data.protocol ? (
|
||||
<div className='space-y-4'>
|
||||
<p className='text-sm text-[#666666]'>直接复制订阅链接或点击二维码按钮扫码获取</p>
|
||||
<div className='space-y-2 sm:space-y-4'>
|
||||
<p className='text-xs font-light text-[#666666] sm:text-sm sm:font-normal'>
|
||||
复制订阅链接或点击二维码按钮扫码
|
||||
</p>
|
||||
|
||||
{/* 统计信息 */}
|
||||
<div className='rounded-[20px] bg-[#EAEAEA] p-4'>
|
||||
<div className='grid grid-cols-3 gap-4 text-center'>
|
||||
<div>
|
||||
<p className='text-xs text-[rgba(132,132,132,0.7)]'>总流量</p>
|
||||
<p className='text-lg font-medium text-[#0F2C53]'>
|
||||
<p className='text-[10px] text-[rgba(132,132,132,0.7)] sm:text-xs'>总流量</p>
|
||||
<p className='text-xs font-medium text-[#0F2C53] sm:text-lg'>
|
||||
<Display
|
||||
type='traffic'
|
||||
value={userSubscribe?.[0]?.traffic}
|
||||
@@ -289,16 +319,20 @@ export default function Content() {
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className='text-xs text-[rgba(132,132,132,0.7)]'>{t('nextResetDays')}</p>
|
||||
<p className='text-lg font-medium text-[#0F2C53]'>
|
||||
<p className='text-[10px] text-[rgba(132,132,132,0.7)] sm:text-xs'>
|
||||
{t('nextResetDays')}
|
||||
</p>
|
||||
<p className='text-xs font-medium text-[#0F2C53] sm:text-lg'>
|
||||
{userSubscribe?.[0]
|
||||
? differenceInDays(new Date(userSubscribe?.[0].reset_time), new Date())
|
||||
: t('noReset')}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className='text-xs text-[rgba(132,132,132,0.7)]'>{t('expirationDays')}</p>
|
||||
<p className='text-lg font-medium text-[#0F2C53]'>
|
||||
<p className='text-[10px] text-[rgba(132,132,132,0.7)] sm:text-xs'>
|
||||
{t('expirationDays')}
|
||||
</p>
|
||||
<p className='text-xs font-medium text-[#0F2C53] sm:text-lg'>
|
||||
{userSubscribe?.[0]?.expire_time
|
||||
? differenceInDays(new Date(userSubscribe?.[0].expire_time), new Date()) ||
|
||||
t('unknown')
|
||||
@@ -309,7 +343,7 @@ export default function Content() {
|
||||
</div>
|
||||
|
||||
{/* 订阅链接 */}
|
||||
<div className='rounded-[26px] bg-[#EAEAEA] p-4'>
|
||||
<div className='rounded-[26px] bg-[#EAEAEA] p-2 sm:p-4'>
|
||||
<div className='mb-3 flex flex-wrap justify-between gap-4'>
|
||||
{data?.protocol && data?.protocol.length > 1 && (
|
||||
<Tabs
|
||||
@@ -332,16 +366,20 @@ export default function Content() {
|
||||
)}
|
||||
</div>
|
||||
<div className={'mb-3 flex items-center justify-center gap-1'}>
|
||||
<div className={'flex items-center gap-2 rounded-[16px] bg-[#BABABA] pl-2'}>
|
||||
<div
|
||||
className={
|
||||
'flex items-center gap-1 rounded-full bg-[#BABABA] pl-1 sm:gap-2 sm:rounded-[16px] sm:pl-2'
|
||||
}
|
||||
>
|
||||
<Select
|
||||
value={userSubscribeProtocolCurrent}
|
||||
onValueChange={setUserSubscribeProtocolCurrent}
|
||||
>
|
||||
<SelectTrigger className='h-[35px] w-20 flex-shrink-0 rounded-[8px] border-none bg-[#D9D9D9] bg-transparent p-2 text-[13px] text-sm font-medium text-white shadow-none hover:bg-[#848484] focus:ring-0 [&>svg]:hidden'>
|
||||
<SelectTrigger className='h-auto w-auto flex-shrink-0 rounded-[16px] border-none bg-[#D9D9D9] px-2.5 py-0.5 text-[13px] text-sm font-medium text-white shadow-none hover:bg-[#848484] focus:ring-0 sm:h-[35px] sm:rounded-[8px] sm:p-2 [&>svg]:hidden'>
|
||||
<SelectValue>
|
||||
<div className='flex flex-col items-center justify-center'>
|
||||
<div>{t('subscriptionUrl')}1</div>
|
||||
<div className='h-0 w-0 border-l-[5px] border-r-[5px] border-t-[5px] border-l-transparent border-r-transparent border-t-white'></div>
|
||||
<div className='flex flex-col items-center justify-center text-[10px] sm:text-sm'>
|
||||
<div>{getCurrentLabel()}</div>
|
||||
<div className='-mt-0.5 h-0 w-0 scale-50 border-l-[5px] border-r-[5px] border-t-[5px] border-l-transparent border-r-transparent border-t-white sm:scale-100'></div>
|
||||
</div>
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
@@ -361,19 +399,42 @@ export default function Content() {
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<div className='flex-1 rounded-[16px] bg-white p-3 text-xs text-[#225BA9] shadow-[inset_0px_0px_7.6px_0px_rgba(0,0,0,0.25)]'>
|
||||
<div className={'line-clamp-2 break-all'}>{userSubscribeProtocolCurrent}</div>
|
||||
<div className='flex-1 rounded-full bg-white px-3 py-1 text-[10px] leading-tight text-[#225BA9] shadow-[inset_0px_0px_7.6px_0px_rgba(0,0,0,0.25)] sm:rounded-[16px] sm:p-3 sm:text-xs'>
|
||||
<div className={'line-clamp-2 break-all text-[10px] sm:text-base'}>
|
||||
{userSubscribeProtocolCurrent}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'ml-3 h-[40px] w-[40px] flex-shrink-0 rounded-lg bg-black'}></div>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<div
|
||||
className={
|
||||
'ml-3 h-[40px] w-[40px] flex-shrink-0 cursor-pointer rounded-lg bg-black'
|
||||
}
|
||||
></div>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className='w-auto rounded-xl p-4' align='end'>
|
||||
<div className='flex flex-col items-center gap-2'>
|
||||
<p className='text-muted-foreground text-center text-xs'>扫描码订阅</p>
|
||||
<QRCodeCanvas
|
||||
value={userSubscribeProtocolCurrent}
|
||||
size={120}
|
||||
bgColor='transparent'
|
||||
fgColor='rgb(34, 91, 169)'
|
||||
/>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
<div className='flex justify-between gap-2'>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button
|
||||
size='sm'
|
||||
className={'rounded-full bg-[#E22C2E] px-3 py-1 text-xs text-white'}
|
||||
className={
|
||||
'h-fit rounded-full bg-[#E22C2E] px-3 py-1 text-[10px] text-white sm:h-9 sm:text-xs'
|
||||
}
|
||||
variant='destructive'
|
||||
>
|
||||
{t('resetSubscription')}
|
||||
@@ -403,7 +464,7 @@ export default function Content() {
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
<Renewal
|
||||
className='rounded-full bg-[#A8D4ED] px-3 py-1 text-xs text-white'
|
||||
className='h-fit rounded-full bg-[#A8D4ED] px-3 py-1 text-[10px] text-white sm:h-9 sm:text-xs'
|
||||
id={userSubscribe?.[0]?.id}
|
||||
subscribe={userSubscribe?.[0]?.subscribe}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user