2"use client";
5import React, { useEffect, useMemo, useState } from 'react';
8import axios from 'axios';
11import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, flexRender} from '@tanstack/react-table';
14import '../../styles/table.css'
16
18function ArtistTable() {
20
22 const [posts, setPosts] = useState([]);
25 const [sorting, setSorting] = useState([]);
28 const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 4});
30
32 const GetArtistsInfo = async () => {
33 try {
35 const response = await axios.get('http://localhost:9080/artists');
38 const artists = response.data;
40 const processedData = [];
42 for (const artist of artists) {
44 const { albums, ...rest } = artist;
46 for (const album of albums) {
48 processedData.push({ ...rest, ...album });
50 }
51 };
53 setPosts(processedData);
55 } catch (error) {
56 console.log(error);
57 }
58 };
60
62 const data = useMemo(() => [...posts], [posts]);
64
66 const columns = useMemo(() => [{
67 header: 'Artist Info',
68 columns: [
69 {
70 accessorKey: 'id',
71 header: 'Artist ID'
72 },
73 {
74 accessorKey: 'name',
75 header: 'Artist Name'
76 },
77 {
78 accessorKey: 'genres',
79 header: 'Genres'
80 }
81 ]
82 },
83 {
84 header: 'Albums',
85 columns: [
86 {
87 accessorKey: 'ntracks',
88 header: 'Number of Tracks'
89 },
90 {
91 accessorKey: 'title',
92 header: 'Title'
93 }
94 ]
95 }
96 ], []
97 );
99
101 const tableInstance = useReactTable({
102 columns,
103 data,
105 getCoreRowModel: getCoreRowModel(),
108 getPaginationRowModel: getPaginationRowModel(),
111 getSortedRowModel: getSortedRowModel(),
113 state:{
114 sorting: sorting,
115 pagination: pagination,
116 },
117 onSortingChange: setSorting,
118 onPaginationChange: setPagination,
119 });
121
123 const {
124 getHeaderGroups,
125 getRowModel,
126 getState,
127 setPageIndex,
128 setPageSize,
129 getCanPreviousPage,
130 getCanNextPage,
131 previousPage,
132 nextPage,
133 getPageCount,
134 } = tableInstance;
136
137 const {pageIndex, pageSize} = getState().pagination;
138
140 useEffect(() => {
141 GetArtistsInfo();
142 }, []);
144
146 return (
147 <>
148 <h2>Artist Web Service</h2>
150 <table>
151 <thead>
152 {getHeaderGroups().map(headerGroup => (
153 <tr key={headerGroup.id}>
154 {headerGroup.headers.map(header => (
155 <th key={header.id} colSpan={header.colSpan} onClick={header.column.getToggleSortingHandler()}>
156 {header.isPlaceholder ? null :(
157 <div>
158 {flexRender(header.column.columnDef.header, header.getContext())}
159 {
160 {
161 asc: " 🔼",
162 desc: " 🔽",
163 }[header.column.getIsSorted() ?? null]
164 }
165 </div>
166 )}
167 </th>
168 ))}
169 </tr>
170 ))}
171 </thead>
172 <tbody>
173 {getRowModel().rows.map(row => (
174 <tr key={row.id}>
175 {row.getVisibleCells().map(cell => (
176 <td key={cell.id}>
177 {flexRender(cell.column.columnDef.cell, cell.getContext())}
178 </td>
179 ))}
180 </tr>
181 ))}
182 </tbody>
183 </table>
185 <div className="pagination">
186 <button onClick={() => previousPage()} disabled={!getCanPreviousPage()}>
187 {'Previous'}
188 </button>{' '}
189 <div className="page-info">
190 <span>
191 Page{' '}
192 <strong>
193 {pageIndex + 1} of {getPageCount()}
194 </strong>{' '}
195 </span>
196 <span>
197 | Go to page:{' '}
198 <input
199 type="number"
200 defaultValue={pageIndex + 1}
201 onChange={e => {
202 const page = e.target.value ? Number(e.target.value) - 1 : 0
203 setPageIndex(page);
204 }}
205 style={{ width: '100px' }}
206 />
207 </span>{' '}
208 <select
209 value={pageSize}
210 onChange={e => {
211 setPageSize(Number(e.target.value))
212 }}
213 >
214 {[4, 5, 6, 9].map(pageSize => (
215 <option key={pageSize} value={pageSize}>
216 Show {pageSize}
217 </option>
218 ))}
219 </select>
220 </div>
221 <button onClick={() => nextPage()} disabled={!getCanNextPage()}>
222 {'Next'}
223 </button>{' '}
224 </div>
225 </>
226 );
228}
229
230export default ArtistTable231