2024-02-02 23:50:24 +00:00
'use client'
2024-05-27 22:20:58 +00:00
import React from 'react'
import ReactDOM from 'react-dom/client'
import Link from 'next/link'
2024-02-02 23:50:24 +00:00
import {
2024-05-27 22:20:58 +00:00
keepPreviousData ,
QueryClient ,
useQuery ,
} from '@tanstack/react-query'
2024-02-02 23:50:24 +00:00
2024-05-27 22:20:58 +00:00
import {
PaginationState ,
useReactTable ,
getCoreRowModel ,
ColumnDef ,
flexRender ,
} from '@tanstack/react-table'
2024-02-02 23:50:24 +00:00
2024-05-27 22:20:58 +00:00
import { fetchStreamData , IStream } from '@/lib/streams'
2024-02-02 23:50:24 +00:00
2024-05-27 22:20:58 +00:00
const queryClient = new QueryClient ( )
2024-02-02 23:50:24 +00:00
2024-05-27 22:20:58 +00:00
function getStatusClass ( value : string ) {
switch ( value ) {
case 'issue' :
return 'is-warning' ;
case 'missing' :
return 'is-danger' ;
case 'good' :
return 'is-success' ;
default :
return '' ;
}
}
2024-02-02 23:50:24 +00:00
2024-05-27 22:20:58 +00:00
export default function StreamsTable() {
const rerender = React . useReducer ( ( ) = > ( { } ) , { } ) [ 1 ]
2024-02-02 23:50:24 +00:00
2024-05-27 22:20:58 +00:00
// name
// title
// platform
// date
// archiveStatus
const columns = React . useMemo < ColumnDef < IStream > [ ] > (
( ) = > [
{
header : 'VTuber' ,
accessorFn : d = > d . attributes . vtuber . data ? . attributes ? . displayName ,
2024-02-02 23:50:24 +00:00
} ,
2024-05-27 22:20:58 +00:00
{
header : 'Date' ,
accessorFn : d = > new Date ( d . attributes . date2 ) . toISOString ( ) . split ( 'T' ) . at ( 0 ) ,
cell : info = > < Link href = { ` /archive/ ${ info . row . original . attributes . cuid } ` } > { info . getValue ( ) as string } < / Link >
} ,
{
header : 'Platform' ,
accessorFn : d = > [
( d . attributes . isChaturbateStream && 'CB' ) ,
( d . attributes . isFanslyStream && 'Fansly' )
] . filter ( Boolean ) . join ( ', ' ) || '???'
} ,
{
header : 'Status' ,
accessorFn : d = > {
if ( ! d . attributes . archiveStatus ) return 'missing' ;
return d . attributes . archiveStatus
}
} ,
// {
// header: 'Name',
// footer: props => props.column.id,
// columns: [
// {
// accessorKey: 'firstName',
// cell: info => info.getValue(),
// footer: props => props.column.id,
// },
// {
// accessorFn: row => row.lastName,
// id: 'lastName',
// cell: info => info.getValue(),
// header: () => <span>Last Name</span>,
// footer: props => props.column.id,
// },
// ],
// },
] ,
[ ]
)
const [ pagination , setPagination ] = React . useState < PaginationState > ( {
pageIndex : 0 ,
pageSize : 50 ,
} )
const dataQuery = useQuery ( {
queryKey : [ 'streams' , pagination . pageIndex , pagination . pageSize ] ,
queryFn : ( ) = > fetchStreamData ( pagination ) ,
placeholderData : keepPreviousData , // don't have 0 rows flash while changing pages/loading next page,
staleTime : 1000
} , queryClient )
const defaultData = React . useMemo ( ( ) = > [ ] , [ ] )
const table = useReactTable ( {
data : dataQuery?.data?.rows ? ? defaultData ,
columns ,
// pageCount: dataQuery.data?.pageCount ?? -1, //you can now pass in `rowCount` instead of pageCount and `pageCount` will be calculated internally (new in v8.13.0)
rowCount : dataQuery.data?.rowCount , // new in v8.13.0 - alternatively, just pass in `pageCount` directly
state : {
pagination ,
} ,
onPaginationChange : setPagination ,
getCoreRowModel : getCoreRowModel ( ) ,
manualPagination : true , //we're doing manual "server-side" pagination
// getPaginationRowModel: getPaginationRowModel(), // If only doing manual pagination, you don't need this
debugTable : true ,
} )
return (
< div className = "p-2" >
< div className = "h-2" / >
< table className = 'table is-hoverable is-fullwidth' >
< thead >
{ table . getHeaderGroups ( ) . map ( headerGroup = > (
< tr key = { headerGroup . id } >
{ headerGroup . headers . map ( header = > {
return (
< th key = { header . id } colSpan = { header . colSpan } >
{ header . isPlaceholder ? null : (
< div >
{ flexRender (
header . column . columnDef . header ,
header . getContext ( )
) }
< / div >
) }
< / th >
)
} ) }
< / tr >
) ) }
< / thead >
< tbody >
{ table . getRowModel ( ) . rows . map ( row = > {
return (
< tr key = { row . id } >
{ row . getVisibleCells ( ) . map ( cell = > {
return (
< td
className = { getStatusClass ( cell . getValue ( ) as string ) }
key = { cell . id }
2024-02-02 23:50:24 +00:00
>
2024-05-27 22:20:58 +00:00
{ flexRender (
cell . column . columnDef . cell ,
cell . getContext ( )
) }
< / td >
)
} ) }
< / tr >
)
} ) }
< / tbody >
< / table >
< div className = "columns is-mobile is-vcentered" >
< div className = 'column is-half' >
< button
className = "button border rounded mx-1"
onClick = { ( ) = > table . firstPage ( ) }
disabled = { ! table . getCanPreviousPage ( ) }
>
{ '<<' }
< / button >
< button
className = "button border rounded mx-1"
onClick = { ( ) = > table . previousPage ( ) }
disabled = { ! table . getCanPreviousPage ( ) }
>
{ '<' }
< / button >
< button
className = "button border rounded mx-1"
onClick = { ( ) = > table . nextPage ( ) }
disabled = { ! table . getCanNextPage ( ) }
>
{ '>' }
< / button >
< button
className = "button border rounded mx-1"
onClick = { ( ) = > table . lastPage ( ) }
disabled = { ! table . getCanNextPage ( ) }
>
{ '>>' }
< / button >
< / div >
< div className = 'column is-half' >
< span > Page < / span >
< strong >
{ table . getState ( ) . pagination . pageIndex + 1 } of { ' ' }
{ table . getPageCount ( ) . toLocaleString ( ) }
< / strong >
< / div >
< / div >
{ /* second row with page number input and pages-per-screen select */ }
< div className = 'columns is-mobile is-vcentered' >
< div className = 'column is-2 ' >
< span className = 'is-text-centered' > Go to page : < / span >
< / div >
< div className = 'column is-3' >
< input
type = "number"
defaultValue = { table . getState ( ) . pagination . pageIndex + 1 }
onChange = { e = > {
const page = e . target . value ? Number ( e . target . value ) - 1 : 0
table . setPageIndex ( page )
} }
className = "input"
/ >
< / div >
< div className = 'column is-5' >
< div className = "select" >
< select
value = { table . getState ( ) . pagination . pageSize }
onChange = { e = > {
table . setPageSize ( Number ( e . target . value ) )
} }
>
{ [ 20 , 50 , 100 ] . map ( pageSize = > (
< option key = { pageSize } value = { pageSize } >
Show { pageSize }
< / option >
) ) }
< / select >
< / div >
< / div >
< / div >
< / div >
)
2024-02-02 23:50:24 +00:00
}