156 lines
3.7 KiB
TypeScript
156 lines
3.7 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import {
|
|
DataTable,
|
|
TableColumn,
|
|
Badge,
|
|
Group,
|
|
Text,
|
|
SidebarLayout,
|
|
Sidebar
|
|
} from '@skybridge/web-components';
|
|
import { IconEye, IconCopy } from '@tabler/icons-react';
|
|
import { notifications } from '@mantine/notifications';
|
|
import { apiService, Application } from '../services/apiService';
|
|
import ApplicationSidebar from './ApplicationSidebar';
|
|
import dayjs from 'dayjs';
|
|
|
|
const Applications: React.FC = () => {
|
|
const [applications, setApplications] = useState<Application[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
const [editingApp, setEditingApp] = useState<Application | null>(null);
|
|
|
|
useEffect(() => {
|
|
loadApplications();
|
|
}, []);
|
|
|
|
const loadApplications = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const response = await apiService.getApplications(100, 0);
|
|
setApplications(response.data);
|
|
} catch (error) {
|
|
console.error('Failed to load applications:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleAdd = () => {
|
|
setEditingApp(null);
|
|
setSidebarOpen(true);
|
|
};
|
|
|
|
const handleEdit = (app: Application) => {
|
|
setEditingApp(app);
|
|
setSidebarOpen(true);
|
|
};
|
|
|
|
const handleDelete = async (app: Application) => {
|
|
await apiService.deleteApplication(app.app_id);
|
|
loadApplications();
|
|
};
|
|
|
|
const handleSuccess = () => {
|
|
setSidebarOpen(false);
|
|
setEditingApp(null);
|
|
loadApplications();
|
|
};
|
|
|
|
const copyToClipboard = (text: string) => {
|
|
navigator.clipboard.writeText(text);
|
|
notifications.show({
|
|
title: 'Copied',
|
|
message: 'Copied to clipboard',
|
|
color: 'blue',
|
|
});
|
|
};
|
|
|
|
const columns: TableColumn[] = [
|
|
{
|
|
key: 'app_id',
|
|
label: 'Application ID',
|
|
render: (value) => <Text fw={500}>{value}</Text>
|
|
},
|
|
{
|
|
key: 'type',
|
|
label: 'Type',
|
|
render: (value: string[]) => (
|
|
<Group gap="xs">
|
|
{value.map((type) => (
|
|
<Badge key={type} variant="light" size="sm">
|
|
{type}
|
|
</Badge>
|
|
))}
|
|
</Group>
|
|
)
|
|
},
|
|
{
|
|
key: 'owner',
|
|
label: 'Owner',
|
|
render: (value: any) => (
|
|
<Text size="sm" c="dimmed">
|
|
{value.name} ({value.owner})
|
|
</Text>
|
|
)
|
|
},
|
|
{
|
|
key: 'created_at',
|
|
label: 'Created',
|
|
render: (value) => (
|
|
<Text size="sm">
|
|
{dayjs(value).format('MMM DD, YYYY')}
|
|
</Text>
|
|
)
|
|
},
|
|
];
|
|
|
|
const customActions = [
|
|
{
|
|
key: 'view',
|
|
label: 'View Details',
|
|
icon: <IconEye size={14} />,
|
|
onClick: (app: Application) => {
|
|
// Could open a modal or navigate to details page
|
|
console.log('View details for:', app.app_id);
|
|
},
|
|
},
|
|
{
|
|
key: 'copy',
|
|
label: 'Copy App ID',
|
|
icon: <IconCopy size={14} />,
|
|
onClick: (app: Application) => copyToClipboard(app.app_id),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<SidebarLayout
|
|
sidebarOpened={sidebarOpen}
|
|
sidebarWidth={450}
|
|
sidebar={
|
|
<ApplicationSidebar
|
|
opened={sidebarOpen}
|
|
onClose={() => setSidebarOpen(false)}
|
|
onSuccess={handleSuccess}
|
|
editingApp={editingApp}
|
|
/>
|
|
}
|
|
>
|
|
<DataTable
|
|
data={applications}
|
|
columns={columns}
|
|
loading={loading}
|
|
title="Applications"
|
|
searchable
|
|
onAdd={handleAdd}
|
|
onEdit={handleEdit}
|
|
onDelete={handleDelete}
|
|
onRefresh={loadApplications}
|
|
customActions={customActions}
|
|
emptyMessage="No applications found"
|
|
/>
|
|
</SidebarLayout>
|
|
);
|
|
};
|
|
|
|
export default Applications; |