Skip to content

Commit e7ee0cf

Browse files
committed
Initial chart implementation
1 parent acce0b3 commit e7ee0cf

4 files changed

Lines changed: 785 additions & 0 deletions

File tree

components/alerts/list.tsx

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import {
2+
flexRender,
3+
getCoreRowModel,
4+
getSortedRowModel,
5+
useReactTable,
6+
} from '@tanstack/react-table'
7+
import { addWeeks, format, parseISO, subWeeks } from 'date-fns'
8+
import Link from 'next/link'
9+
import { useMemo } from 'react'
10+
import { FaArrowAltCircleDown, FaArrowAltCircleUp } from 'react-icons/fa'
11+
12+
export interface Changepoint {
13+
id: string
14+
name: string
15+
description: string
16+
probe_cc: string
17+
probe_asn: string
18+
start_time: string
19+
end_time: string
20+
domain: string
21+
change_dir: 'up' | 'down'
22+
}
23+
24+
const AlertList: React.FC<{ changepoints: Changepoint[] }> = ({
25+
changepoints,
26+
}) => {
27+
const columns = useMemo(
28+
() => [
29+
{
30+
header: 'Direction',
31+
accessorKey: 'change_dir',
32+
cell: ({ getValue }: { getValue: () => 'up' | 'down' }) => {
33+
const direction = getValue()
34+
return (
35+
<span className="inline-block align-middle">
36+
{direction === 'up' ? (
37+
<FaArrowAltCircleUp className="text-red-700" />
38+
) : (
39+
<FaArrowAltCircleDown className="text-green-700" />
40+
)}
41+
</span>
42+
)
43+
},
44+
},
45+
{
46+
header: 'Time',
47+
accessorKey: 'start_time',
48+
cell: ({ getValue }: { getValue: () => string }) => {
49+
const time = getValue()
50+
return time
51+
},
52+
},
53+
{
54+
header: 'Country',
55+
accessorKey: 'probe_cc',
56+
},
57+
{
58+
header: 'Network',
59+
accessorKey: 'probe_asn',
60+
cell: ({ getValue }: { getValue: () => string }) => {
61+
const asn = getValue()
62+
return `AS${asn}`
63+
},
64+
},
65+
{
66+
header: 'Domain',
67+
accessorKey: 'domain',
68+
},
69+
{
70+
header: 'See more',
71+
id: 'see_more',
72+
cell: ({ row }: { row: { original: Changepoint } }) => {
73+
const { probe_asn, probe_cc, domain, start_time } = row.original
74+
const startDate = parseISO(start_time)
75+
const since = format(subWeeks(startDate, 2), 'yyyy-MM-dd')
76+
const until = format(addWeeks(startDate, 2), 'yyyy-MM-dd')
77+
78+
const params = new URLSearchParams({
79+
probe_asn,
80+
probe_cc,
81+
domain,
82+
since,
83+
until,
84+
})
85+
86+
return (
87+
<Link
88+
href={`/chart/alert?${params.toString()}`}
89+
className="text-blue-600 hover:text-blue-800 underline"
90+
>
91+
See more
92+
</Link>
93+
)
94+
},
95+
},
96+
],
97+
[],
98+
)
99+
100+
const { getHeaderGroups, getRowModel } = useReactTable({
101+
columns,
102+
data: changepoints,
103+
getCoreRowModel: getCoreRowModel(),
104+
getSortedRowModel: getSortedRowModel(),
105+
})
106+
107+
return (
108+
<div className="flow-root overflow-x-auto">
109+
<table className="min-w-full divide-y divide-gray-400">
110+
<thead>
111+
{getHeaderGroups().map((headerGroup) => (
112+
<tr key={headerGroup.id}>
113+
{headerGroup.headers.map((header) => (
114+
<th
115+
key={header.id}
116+
className="px-3 py-3.5 text-sm text-start font-semibold text-gray-900"
117+
scope="col"
118+
>
119+
{flexRender(
120+
header.column.columnDef.header,
121+
header.getContext(),
122+
)}
123+
</th>
124+
))}
125+
</tr>
126+
))}
127+
</thead>
128+
<tbody>
129+
{getRowModel().rows.map((row) => {
130+
return (
131+
<tr key={row.id} className="even:bg-gray-50">
132+
{row.getVisibleCells().map((cell) => {
133+
return (
134+
<td
135+
key={cell.id}
136+
className="whitespace-nowrap px-3 py-4 text-sm"
137+
>
138+
{flexRender(
139+
cell.column.columnDef.cell,
140+
cell.getContext(),
141+
)}
142+
</td>
143+
)
144+
})}
145+
</tr>
146+
)
147+
})}
148+
</tbody>
149+
</table>
150+
</div>
151+
)
152+
}
153+
154+
export default AlertList

0 commit comments

Comments
 (0)