mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-02-16 05:11:10 -05:00
✨ feat(subscription): Improve layout and organization of subscription detail tabs
This commit is contained in:
parent
2215c7f2b9
commit
e4630f8ca9
@ -57,150 +57,154 @@ export function SubscriptionDetail({
|
|||||||
{t('onlineDevices')}
|
{t('onlineDevices')}
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value='logs'>
|
<div className='mt-4 max-h-[60dvh] overflow-y-auto'>
|
||||||
<ProTable<API.UserSubscribeLog, Record<string, unknown>>
|
<TabsContent value='logs'>
|
||||||
columns={[
|
<ProTable<API.UserSubscribeLog, Record<string, unknown>>
|
||||||
{
|
columns={[
|
||||||
accessorKey: 'ip',
|
{
|
||||||
header: 'IP',
|
accessorKey: 'ip',
|
||||||
},
|
header: 'IP',
|
||||||
{
|
},
|
||||||
accessorKey: 'user_agent',
|
{
|
||||||
header: t('userAgent'),
|
accessorKey: 'user_agent',
|
||||||
},
|
header: t('userAgent'),
|
||||||
{
|
},
|
||||||
accessorKey: 'token',
|
{
|
||||||
header: t('token'),
|
accessorKey: 'token',
|
||||||
},
|
header: t('token'),
|
||||||
{
|
},
|
||||||
accessorKey: 'created_at',
|
{
|
||||||
header: t('time'),
|
accessorKey: 'created_at',
|
||||||
cell: ({ row }) => formatDate(row.getValue('created_at')),
|
header: t('time'),
|
||||||
},
|
cell: ({ row }) => formatDate(row.getValue('created_at')),
|
||||||
]}
|
},
|
||||||
request={async (pagination) => {
|
]}
|
||||||
const { data } = await getUserSubscribeLogs({
|
request={async (pagination) => {
|
||||||
user_id: userId,
|
const { data } = await getUserSubscribeLogs({
|
||||||
subscribe_id: subscriptionId,
|
user_id: userId,
|
||||||
...pagination,
|
subscribe_id: subscriptionId,
|
||||||
});
|
...pagination,
|
||||||
return {
|
});
|
||||||
list: data.data?.list || [],
|
return {
|
||||||
total: data.data?.total || 0,
|
list: data.data?.list || [],
|
||||||
};
|
total: data.data?.total || 0,
|
||||||
}}
|
};
|
||||||
/>
|
}}
|
||||||
</TabsContent>
|
/>
|
||||||
<TabsContent value='traffic'>
|
</TabsContent>
|
||||||
<ProTable<API.TrafficLog, Record<string, unknown>>
|
<TabsContent value='traffic'>
|
||||||
columns={[
|
<ProTable<API.TrafficLog, Record<string, unknown>>
|
||||||
{
|
columns={[
|
||||||
accessorKey: 'download',
|
{
|
||||||
header: t('download'),
|
accessorKey: 'download',
|
||||||
cell: ({ row }) => <Display type='traffic' value={row.getValue('download')} />,
|
header: t('download'),
|
||||||
},
|
cell: ({ row }) => (
|
||||||
{
|
<Display type='traffic' value={row.getValue('download')} />
|
||||||
accessorKey: 'upload',
|
),
|
||||||
header: t('upload'),
|
},
|
||||||
cell: ({ row }) => <Display type='traffic' value={row.getValue('upload')} />,
|
{
|
||||||
},
|
accessorKey: 'upload',
|
||||||
{
|
header: t('upload'),
|
||||||
accessorKey: 'timestamp',
|
cell: ({ row }) => <Display type='traffic' value={row.getValue('upload')} />,
|
||||||
header: t('time'),
|
},
|
||||||
cell: ({ row }) => formatDate(row.getValue('timestamp')),
|
{
|
||||||
},
|
accessorKey: 'timestamp',
|
||||||
]}
|
header: t('time'),
|
||||||
request={async (pagination) => {
|
cell: ({ row }) => formatDate(row.getValue('timestamp')),
|
||||||
const { data } = await getUserSubscribeTrafficLogs({
|
},
|
||||||
user_id: userId,
|
]}
|
||||||
subscribe_id: subscriptionId,
|
request={async (pagination) => {
|
||||||
...pagination,
|
const { data } = await getUserSubscribeTrafficLogs({
|
||||||
} as API.GetUserSubscribeTrafficLogsParams);
|
user_id: userId,
|
||||||
return {
|
subscribe_id: subscriptionId,
|
||||||
list: data.data?.list || [],
|
...pagination,
|
||||||
total: data.data?.total || 0,
|
} as API.GetUserSubscribeTrafficLogsParams);
|
||||||
};
|
return {
|
||||||
}}
|
list: data.data?.list || [],
|
||||||
/>
|
total: data.data?.total || 0,
|
||||||
</TabsContent>
|
};
|
||||||
<TabsContent value='devices'>
|
}}
|
||||||
<ProTable<API.UserDevice, Record<string, unknown>>
|
/>
|
||||||
columns={[
|
</TabsContent>
|
||||||
{
|
<TabsContent value='devices'>
|
||||||
accessorKey: 'enabled',
|
<ProTable<API.UserDevice, Record<string, unknown>>
|
||||||
header: t('enable'),
|
columns={[
|
||||||
cell: ({ row }) => (
|
{
|
||||||
<Switch
|
accessorKey: 'enabled',
|
||||||
checked={row.getValue('enabled')}
|
header: t('enable'),
|
||||||
onChange={(checked) => {
|
cell: ({ row }) => (
|
||||||
console.log('Switch:', checked);
|
<Switch
|
||||||
}}
|
checked={row.getValue('enabled')}
|
||||||
/>
|
onChange={(checked) => {
|
||||||
),
|
console.log('Switch:', checked);
|
||||||
},
|
}}
|
||||||
{
|
/>
|
||||||
accessorKey: 'id',
|
),
|
||||||
header: 'ID',
|
},
|
||||||
},
|
{
|
||||||
{
|
accessorKey: 'id',
|
||||||
accessorKey: 'identifier',
|
header: 'ID',
|
||||||
header: 'IMEI',
|
},
|
||||||
},
|
{
|
||||||
{
|
accessorKey: 'identifier',
|
||||||
accessorKey: 'user_agent',
|
header: 'IMEI',
|
||||||
header: t('userAgent'),
|
},
|
||||||
},
|
{
|
||||||
{
|
accessorKey: 'user_agent',
|
||||||
accessorKey: 'ip',
|
header: t('userAgent'),
|
||||||
header: 'IP',
|
},
|
||||||
},
|
{
|
||||||
{
|
accessorKey: 'ip',
|
||||||
accessorKey: 'online',
|
header: 'IP',
|
||||||
header: t('loginStatus'),
|
},
|
||||||
cell: ({ row }) => (
|
{
|
||||||
<Badge variant={row.getValue('online') ? 'default' : 'destructive'}>
|
accessorKey: 'online',
|
||||||
{row.getValue('online') ? t('online') : t('offline')}
|
header: t('loginStatus'),
|
||||||
</Badge>
|
cell: ({ row }) => (
|
||||||
),
|
<Badge variant={row.getValue('online') ? 'default' : 'destructive'}>
|
||||||
},
|
{row.getValue('online') ? t('online') : t('offline')}
|
||||||
{
|
</Badge>
|
||||||
accessorKey: 'updated_at',
|
),
|
||||||
header: t('lastSeen'),
|
},
|
||||||
cell: ({ row }) => formatDate(row.getValue('updated_at')),
|
{
|
||||||
},
|
accessorKey: 'updated_at',
|
||||||
]}
|
header: t('lastSeen'),
|
||||||
request={async (pagination) => {
|
cell: ({ row }) => formatDate(row.getValue('updated_at')),
|
||||||
const { data } = await getUserSubscribeDevices({
|
},
|
||||||
user_id: userId,
|
]}
|
||||||
subscribe_id: subscriptionId,
|
request={async (pagination) => {
|
||||||
...pagination,
|
const { data } = await getUserSubscribeDevices({
|
||||||
});
|
user_id: userId,
|
||||||
return {
|
subscribe_id: subscriptionId,
|
||||||
list: data.data?.list || [],
|
...pagination,
|
||||||
total: data.data?.total || 0,
|
});
|
||||||
};
|
return {
|
||||||
}}
|
list: data.data?.list || [],
|
||||||
actions={{
|
total: data.data?.total || 0,
|
||||||
render: (row) => {
|
};
|
||||||
if (!row.identifier) return [];
|
}}
|
||||||
return [
|
actions={{
|
||||||
<ConfirmButton
|
render: (row) => {
|
||||||
key='offline'
|
if (!row.identifier) return [];
|
||||||
trigger={<Button variant='destructive'>{t('confirmOffline')}</Button>}
|
return [
|
||||||
title={t('confirmOffline')}
|
<ConfirmButton
|
||||||
description={t('kickOfflineConfirm', { ip: row.ip })}
|
key='offline'
|
||||||
onConfirm={async () => {
|
trigger={<Button variant='destructive'>{t('confirmOffline')}</Button>}
|
||||||
await kickOfflineByUserDevice({ id: row.id });
|
title={t('confirmOffline')}
|
||||||
toast.success(t('kickOfflineSuccess'));
|
description={t('kickOfflineConfirm', { ip: row.ip })}
|
||||||
}}
|
onConfirm={async () => {
|
||||||
cancelText={t('cancel')}
|
await kickOfflineByUserDevice({ id: row.id });
|
||||||
confirmText={t('confirm')}
|
toast.success(t('kickOfflineSuccess'));
|
||||||
/>,
|
}}
|
||||||
];
|
cancelText={t('cancel')}
|
||||||
},
|
confirmText={t('confirm')}
|
||||||
}}
|
/>,
|
||||||
/>
|
];
|
||||||
</TabsContent>
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</TabsContent>
|
||||||
|
</div>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user