-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathAppsDataSourcesTable.tsx
More file actions
117 lines (110 loc) · 3.96 KB
/
AppsDataSourcesTable.tsx
File metadata and controls
117 lines (110 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"use client";
import { useGetPagesUnderRoute } from "@/lib/nextra-compat";
import { type Page } from "nextra";
import Link from "next/link";
import { ExternalLinkIcon } from "lucide-react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
// --- Helper to flatten all pages recursively ---
function flattenPages(pages) {
let result = [];
for (const page of pages) {
if (page.children) {
result = result.concat(flattenPages(page.children));
} else {
result.push(page);
}
}
return result;
}
export const AppsDataSourcesTable = () => {
const allPages = useGetPagesUnderRoute("/integrations/apps-data-sources");
const pages = flattenPages(allPages).filter(
(page) =>
page.route !== "/integrations/apps-data-sources" &&
page.route !== "/pages/integrations/apps-data-sources" &&
page.route.includes("/integrations/apps-data-sources/")
);
// Sort pages by title
const sortedPages = pages.sort((a, b) => {
const titleA = a.frontMatter?.title || a.name;
const titleB = b.frontMatter?.title || b.name;
return titleA.localeCompare(titleB);
});
return (
<div className="space-y-4">
<div className="rounded-lg border border-gray-200 dark:border-gray-700">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-12">Logo</TableHead>
<TableHead>Name</TableHead>
<TableHead>Description</TableHead>
<TableHead className="w-20">Link</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{sortedPages.map((page) => {
const title = page.frontMatter?.title ||
page.name
.split("-")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
const description = page.frontMatter?.description || "No description available";
const icon = page.frontMatter?.icon || null;
return (
<TableRow key={page.route} className="hover:bg-gray-50 dark:hover:bg-gray-800">
<TableCell className="w-12">
{icon ? (
<img
src={icon}
alt={title}
className="w-8 h-8 object-contain"
onError={(e) => {
e.currentTarget.style.display = 'none';
}}
/>
) : (
<div className="w-8 h-8 bg-gray-200 dark:bg-gray-700 rounded flex items-center justify-center">
<span className="text-xs text-gray-500 dark:text-gray-400">
{title.charAt(0).toUpperCase()}
</span>
</div>
)}
</TableCell>
<TableCell className="font-medium text-black dark:text-white">
{title}
</TableCell>
<TableCell className="text-sm text-gray-600 dark:text-gray-300 max-w-md">
{description}
</TableCell>
<TableCell className="w-20">
<Link
href={page.route}
className="inline-flex items-center gap-1 text-blue-500 hover:text-blue-600 transition-colors text-sm"
>
View
<ExternalLinkIcon className="w-3 h-3" />
</Link>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</div>
{sortedPages.length === 0 && (
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
No app data sources found.
</div>
)}
</div>
);
};
export default AppsDataSourcesTable;