mobigrid-module 1.1.6 → 1.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. package/dist/components/CustomTable/CustomTable.d.ts +8 -0
  2. package/dist/components/CustomTable/Pagination.d.ts +8 -0
  3. package/dist/components/Icon.d.ts +6 -0
  4. package/dist/components/InvalidConfig.d.ts +2 -0
  5. package/dist/components/Layout/PageHeader.d.ts +13 -0
  6. package/dist/components/LoadingConfig.d.ts +2 -0
  7. package/dist/components/ui/alert.d.ts +8 -0
  8. package/dist/components/ui/button.d.ts +11 -0
  9. package/dist/components/ui/calendar.d.ts +8 -0
  10. package/dist/components/ui/date-picker-with-range.d.ts +7 -0
  11. package/dist/components/ui/dialog.d.ts +19 -0
  12. package/dist/components/ui/input.d.ts +3 -0
  13. package/dist/components/ui/pagination.d.ts +28 -0
  14. package/dist/components/ui/popover.d.ts +7 -0
  15. package/dist/components/ui/select.d.ts +13 -0
  16. package/dist/components/ui/sonner.d.ts +5 -0
  17. package/dist/components/ui/table.d.ts +10 -0
  18. package/dist/index.cjs +53 -0
  19. package/dist/index.cjs.map +1 -0
  20. package/dist/index.d.ts +9 -0
  21. package/dist/index.esm.js +70 -0
  22. package/dist/index.esm.js.map +1 -0
  23. package/dist/index.js +53 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/lib/utils.d.ts +2 -0
  26. package/dist/vite.config.d.ts +2 -0
  27. package/package.json +12 -9
  28. package/components/CustomTable/CustomTable.tsx +0 -182
  29. package/components/CustomTable/Pagination.tsx +0 -136
  30. package/components/Icon.tsx +0 -27
  31. package/components/InvalidConfig.tsx +0 -26
  32. package/components/Layout/PageHeader.tsx +0 -270
  33. package/components/LoadingConfig.tsx +0 -38
  34. package/components/ui/alert.tsx +0 -59
  35. package/components/ui/button.tsx +0 -57
  36. package/components/ui/calendar.tsx +0 -99
  37. package/components/ui/date-picker-with-range.tsx +0 -176
  38. package/components/ui/dialog.tsx +0 -132
  39. package/components/ui/input.tsx +0 -22
  40. package/components/ui/pagination.tsx +0 -142
  41. package/components/ui/popover.tsx +0 -31
  42. package/components/ui/select.tsx +0 -208
  43. package/components/ui/sonner.tsx +0 -30
  44. package/components/ui/table.tsx +0 -120
  45. package/index.d.ts +0 -55
  46. package/index.tsx +0 -209
  47. package/lib/utils.ts +0 -6
  48. package/tsconfig.json +0 -36
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
package/package.json CHANGED
@@ -1,10 +1,16 @@
1
1
  {
2
2
  "name": "mobigrid-module",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "",
5
5
  "type": "module",
6
- "main": "index.tsx",
7
- "typings": "index.d.ts",
6
+ "main": "dist/index.js",
7
+ "typings": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs"
12
+ }
13
+ },
8
14
  "scripts": {
9
15
  "test": "echo \"Error: no test specified\" && exit 1",
10
16
  "build": "rollup -c"
@@ -24,9 +30,11 @@
24
30
  "@tanstack/react-table": "^8.20.5",
25
31
  "axios": "^1.7.8",
26
32
  "date-fns": "^4.1.0",
33
+ "lucide-react": "^0.462.0",
27
34
  "next-themes": "^0.4.3",
28
35
  "react-day-picker": "8.10.1",
29
36
  "react-feather": "^2.0.10",
37
+ "rollup-plugin-node-polyfills": "^0.2.1",
30
38
  "rollup-plugin-peer-deps-external": "^2.2.4",
31
39
  "rollup-plugin-terser": "^7.0.2",
32
40
  "sonner": "^1.7.0",
@@ -65,11 +73,6 @@
65
73
  },
66
74
  "types": "dist/index.d",
67
75
  "files": [
68
- "dist",
69
- "index.tsx",
70
- "index.d.ts",
71
- "components",
72
- "lib",
73
- "tsconfig.json"
76
+ "dist"
74
77
  ]
75
78
  }
@@ -1,182 +0,0 @@
1
- import React from "react";
2
- import {
3
- flexRender,
4
- getCoreRowModel,
5
- useReactTable,
6
- } from "@tanstack/react-table";
7
- import {
8
- Table,
9
- TableBody,
10
- TableCell,
11
- TableHead,
12
- TableHeader,
13
- TableRow,
14
- } from "../ui/table";
15
- import { format } from "date-fns";
16
- import Icon from "../Icon";
17
-
18
- interface TableProps {
19
- data: any[];
20
- columns: any[];
21
- isLoading: boolean;
22
- }
23
-
24
- export function CustomTable({ data, columns, isLoading }: TableProps) {
25
- const table = useReactTable({
26
- data: isLoading ? [] : data,
27
- columns: columns.map((col) => ({
28
- accessorKey: col.key,
29
- header: col.title,
30
- cell: (info) => {
31
- if (col.key === "ACTIONS_BUTTONS") {
32
- return (
33
- <div className="flex gap-2 justify-end">
34
- {col.actions?.map((action: any, index: number) => (
35
- <button
36
- key={index}
37
- className={`inline-flex items-center px-2 py-1 text-sm rounded-full transition-colors duration-200 ${
38
- index === 0
39
- ? "text-blue-700 bg-blue-50 border border-blue-200 hover:bg-blue-100"
40
- : index === 1
41
- ? "text-green-700 bg-green-50 border border-green-200 hover:bg-green-100"
42
- : index === 2
43
- ? "text-purple-700 bg-purple-50 border border-purple-200 hover:bg-purple-100"
44
- : index === 3
45
- ? "text-orange-700 bg-orange-50 border border-orange-200 hover:bg-orange-100"
46
- : "text-gray-700 bg-gray-50 border border-gray-200 hover:bg-gray-100"
47
- }`}
48
- onClick={() => {
49
- console.log(action.action, info.row.original);
50
- }}
51
- >
52
- {action.icon && (
53
- <svg
54
- xmlns="http://www.w3.org/2000/svg"
55
- width="16"
56
- height="16"
57
- viewBox="0 0 24 24"
58
- fill="none"
59
- stroke="currentColor"
60
- strokeWidth="2"
61
- strokeLinecap="round"
62
- strokeLinejoin="round"
63
- className="mr-2"
64
- >
65
- <Icon name={action.icon.replace(/^icon-/, '')} className="mr-2" />
66
- </svg>
67
- )}
68
- {action.label}
69
- </button>
70
- ))}
71
- </div>
72
- );
73
- }
74
- if (col.type === "status") {
75
- const statusColors: { [key: string]: string } = {
76
- PENDING: "bg-yellow-100 text-yellow-800",
77
- PAID: "bg-green-100 text-green-800",
78
- CANCELLED: "bg-red-100 text-red-800",
79
- CANCEL_STARTED: "bg-orange-100 text-orange-800",
80
- ECHEC: "bg-gray-100 text-gray-800",
81
- };
82
- const status = info.getValue() as string;
83
- return (
84
- <div className="flex items-center justify-center">
85
- <span
86
- className={`px-2 py-1 rounded-full text-xs font-medium text-center ${
87
- statusColors[status] || "bg-gray-100 text-gray-800"
88
- }`}
89
- >
90
- {status || "-"}
91
- </span>
92
- </div>
93
- );
94
- }
95
- if (col.type === "money") {
96
- return `${info.getValue()} ${col.currency}`;
97
- }
98
- if (col.type === "date") {
99
- return format(new Date(info.getValue() as string), "dd-MM-yyyy");
100
- }
101
- if (col.scroll) {
102
- return (
103
- <div className="max-h-24 overflow-y-auto">
104
- {info.getValue()}
105
- </div>
106
- );
107
- }
108
- return info.getValue();
109
- },
110
- })),
111
- getCoreRowModel: getCoreRowModel(),
112
- enableMultiRowSelection: true,
113
- enableRowSelection: true,
114
- state: {
115
- rowSelection: {},
116
- },
117
- });
118
-
119
- return (
120
- <Table className="border border-gray-200 rounded-md">
121
- <TableHeader className="bg-gray-50">
122
- {table.getHeaderGroups().map((headerGroup) => (
123
- <TableRow key={headerGroup.id}>
124
- {headerGroup.headers.map((header) => (
125
- <TableHead key={header.id} className="font-medium text-gray-800 py-2">
126
- {flexRender(
127
- header.column.columnDef.header,
128
- header.getContext()
129
- )}
130
- </TableHead>
131
- ))}
132
- </TableRow>
133
- ))}
134
- </TableHeader>
135
- <TableBody>
136
- {isLoading ? (
137
- <TableRow>
138
- <TableCell colSpan={columns.length} className="text-center py-4">
139
- <svg
140
- className="animate-spin h-5 w-5 mx-auto mb-2"
141
- xmlns="http://www.w3.org/2000/svg"
142
- fill="none"
143
- viewBox="0 0 24 24"
144
- >
145
- <circle
146
- className="opacity-25"
147
- cx="12"
148
- cy="12"
149
- r="10"
150
- stroke="currentColor"
151
- strokeWidth="4"
152
- ></circle>
153
- <path
154
- className="opacity-75"
155
- fill="currentColor"
156
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
157
- ></path>
158
- </svg>
159
- Chargement des données...
160
- </TableCell>
161
- </TableRow>
162
- ) : !data || data.length === 0 ? (
163
- <TableRow>
164
- <TableCell colSpan={columns.length} className="text-center py-4">
165
- Aucune donnée disponible
166
- </TableCell>
167
- </TableRow>
168
- ) : (
169
- table.getRowModel().rows.map((row) => (
170
- <TableRow key={row.id} className="bg-white hover:bg-gray-100">
171
- {row.getVisibleCells().map((cell) => (
172
- <TableCell key={cell.id}>
173
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
174
- </TableCell>
175
- ))}
176
- </TableRow>
177
- ))
178
- )}
179
- </TableBody>
180
- </Table>
181
- );
182
- }
@@ -1,136 +0,0 @@
1
- import React from "react";
2
- import {
3
- Pagination,
4
- PaginationContent,
5
- PaginationEllipsis,
6
- PaginationItem,
7
- PaginationLink,
8
- PaginationNext,
9
- PaginationPrevious,
10
- } from "../ui/pagination";
11
-
12
- interface PaginationProps {
13
- currentPage: number;
14
- totalPages: number;
15
- onPageChange: (page: number) => void;
16
- }
17
-
18
- export default function ({
19
- currentPage,
20
- totalPages,
21
- onPageChange,
22
- }: PaginationProps) {
23
- const renderPaginationItems = () => {
24
- const items = [];
25
-
26
- // Previous button
27
- items.push(
28
- <PaginationItem key="prev">
29
- <PaginationPrevious
30
- href="#"
31
- onClick={(e) => {
32
- e.preventDefault();
33
- if (currentPage > 1) onPageChange(currentPage - 1);
34
- }}
35
- />
36
- </PaginationItem>
37
- );
38
-
39
- // First page
40
- items.push(
41
- <PaginationItem key={1}>
42
- <PaginationLink
43
- href="#"
44
- isActive={currentPage === 1}
45
- onClick={(e) => {
46
- e.preventDefault();
47
- onPageChange(1);
48
- }}
49
- >
50
- 1
51
- </PaginationLink>
52
- </PaginationItem>
53
- );
54
-
55
- // Calculate visible page range
56
- let startPage = Math.max(2, currentPage - 1);
57
- let endPage = Math.min(totalPages - 1, currentPage + 1);
58
-
59
- // Add ellipsis after first page if needed
60
- if (startPage > 2) {
61
- items.push(
62
- <PaginationItem key="ellipsis1">
63
- <PaginationEllipsis />
64
- </PaginationItem>
65
- );
66
- }
67
-
68
- // Add middle pages
69
- for (let i = startPage; i <= endPage; i++) {
70
- items.push(
71
- <PaginationItem key={i}>
72
- <PaginationLink
73
- href="#"
74
- isActive={currentPage === i}
75
- onClick={(e) => {
76
- e.preventDefault();
77
- onPageChange(i);
78
- }}
79
- >
80
- {i}
81
- </PaginationLink>
82
- </PaginationItem>
83
- );
84
- }
85
-
86
- // Add ellipsis before last page if needed
87
- if (endPage < totalPages - 1) {
88
- items.push(
89
- <PaginationItem key="ellipsis2">
90
- <PaginationEllipsis />
91
- </PaginationItem>
92
- );
93
- }
94
-
95
- // Last page (if not already included)
96
- if (totalPages > 1) {
97
- items.push(
98
- <PaginationItem key={totalPages}>
99
- <PaginationLink
100
- href="#"
101
- isActive={currentPage === totalPages}
102
- onClick={(e) => {
103
- e.preventDefault();
104
- onPageChange(totalPages);
105
- }}
106
- >
107
- {totalPages}
108
- </PaginationLink>
109
- </PaginationItem>
110
- );
111
- }
112
-
113
- // Next button
114
- items.push(
115
- <PaginationItem key="next">
116
- <PaginationNext
117
- href="#"
118
- onClick={(e) => {
119
- e.preventDefault();
120
- if (currentPage < totalPages) onPageChange(currentPage + 1);
121
- }}
122
- />
123
- </PaginationItem>
124
- );
125
-
126
- return items;
127
- };
128
-
129
- return (
130
- <Pagination>
131
- <PaginationContent>
132
- {renderPaginationItems()}
133
- </PaginationContent>
134
- </Pagination>
135
- );
136
- }
@@ -1,27 +0,0 @@
1
- import React from "react";
2
- import * as FeatherIcons from 'react-feather';
3
- import { IconProps as FeatherIconProps } from 'react-feather';
4
-
5
- interface IconProps extends Omit<FeatherIconProps, 'ref'> {
6
- name: string;
7
- }
8
-
9
- const Icon = ({ name, ...props }: IconProps): JSX.Element | null => {
10
- const formatIconName = (iconName: string): string => {
11
- return iconName
12
- .split(/[-_]/)
13
- .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
14
- .join('');
15
- };
16
-
17
- const IconComponent = FeatherIcons[formatIconName(name) as keyof typeof FeatherIcons];
18
-
19
- if (!IconComponent) {
20
- console.warn(`Icon "${name}" not found in react-feather library`);
21
- return null;
22
- }
23
-
24
- return <IconComponent {...props} />;
25
- };
26
-
27
- export default Icon;
@@ -1,26 +0,0 @@
1
- import React from "react";
2
-
3
- export default function InvalidConfig() {
4
- return (
5
- <div
6
- style={{
7
- display: "flex",
8
- justifyContent: "center",
9
- alignItems: "center",
10
- height: "100vh",
11
- }}
12
- >
13
- <div style={{ position: "absolute" }}>
14
- <svg
15
- className="h-5 w-5 mx-auto mb-2"
16
- xmlns="http://www.w3.org/2000/svg"
17
- viewBox="0 0 24 24"
18
- fill="red"
19
- >
20
- <path d="M18.3 5.71a.996.996 0 00-1.41 0L12 10.59 7.11 5.7A.996.996 0 105.7 7.11L10.59 12 5.7 16.89a.996.996 0 101.41 1.41L12 13.41l4.89 4.89a.996.996 0 101.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z" />
21
- </svg>
22
- <div>Invalid configuration</div>
23
- </div>
24
- </div>
25
- );
26
- }
@@ -1,270 +0,0 @@
1
- import * as React from "react";
2
- import { DatePickerWithRange } from "../ui/date-picker-with-range";
3
- import { Button } from "../ui/button";
4
- import { DateRange } from "react-day-picker";
5
- import { Input } from "../ui/input";
6
- import {
7
- Select,
8
- SelectItem,
9
- SelectContent,
10
- SelectValue,
11
- SelectTrigger,
12
- } from "../ui/select";
13
- import { useState, useMemo } from "react";
14
-
15
- interface PageHeaderProps {
16
- title: string;
17
- filters: any;
18
- configFilters: any;
19
- setFilters: (filters: any) => void;
20
- onSearch: () => void;
21
- count: number;
22
- isLoading: boolean;
23
- setCurrentPage: (page: number) => void;
24
- }
25
-
26
- export function PageHeader({
27
- title,
28
- filters,
29
- setFilters,
30
- configFilters,
31
- onSearch,
32
- count,
33
- isLoading,
34
- setCurrentPage,
35
- }: PageHeaderProps) {
36
- const [initialFilters, setInitialFilters] = React.useState(filters);
37
-
38
- const [exportDisabled, setExportDisabled] = useState(false);
39
- const filtersChanged = React.useMemo(() => {
40
- return JSON.stringify(initialFilters) !== JSON.stringify(filters);
41
- }, [initialFilters, filters]);
42
-
43
- const handleSearch = async () => {
44
- setInitialFilters(filters);
45
- if (filtersChanged) await setCurrentPage(1);
46
- onSearch();
47
- };
48
-
49
- const handleDateChange = (date: DateRange | undefined) => {
50
- setFilters({ ...filters, fromDate: date?.from, toDate: date?.to });
51
- };
52
-
53
- const handleExport = async (ctx: string) => {
54
- try {
55
- const response = await fetch(
56
- (() => {
57
- let url = `/cashplus/newfront/templates/extract-action.cfm?ctx=${ctx}`;
58
- for (const [key, value] of Object.entries(filters)) {
59
- if (value && typeof value !== "object") {
60
- if (key === "fromDate" || key === "toDate") {
61
- const date = new Date(value as string);
62
- url =
63
- url +
64
- `&${key}=${date.getFullYear()}-${String(
65
- date.getMonth() + 1
66
- ).padStart(2, "0")}-${String(date.getDate()).padStart(
67
- 2,
68
- "0"
69
- )}`;
70
- continue;
71
- }
72
-
73
- url = url + `&${key}=${value}`;
74
- }
75
- }
76
- return url;
77
- })()
78
- );
79
-
80
- if (!response.ok) {
81
- throw new Error("Export failed");
82
- }
83
-
84
- const blob = await response.blob();
85
- const url = window.URL.createObjectURL(blob);
86
- const a = document.createElement("a");
87
- a.href = url;
88
- const fileName = `${title.replace(/\s+/g, "_")}_${filters.fromDate}_${
89
- filters.toDate
90
- }_.csv`;
91
- a.download = fileName;
92
- document.body.appendChild(a);
93
- a.click();
94
- window.URL.revokeObjectURL(url);
95
- document.body.removeChild(a);
96
- } catch (error) {
97
- console.error("Export error:", error);
98
- }
99
- };
100
-
101
- return (
102
- <div className="flex flex-col gap-2">
103
- <h1 className="text-2xl font-bold text-[rgb(0,137,149)]">
104
- <svg
105
- xmlns="http://www.w3.org/2000/svg"
106
- width="24"
107
- height="24"
108
- viewBox="0 0 24 24"
109
- fill="none"
110
- stroke="rgb(0, 137, 149)"
111
- strokeWidth="2"
112
- strokeLinecap="round"
113
- strokeLinejoin="round"
114
- className="inline-block mr-2"
115
- >
116
- <line x1="8" y1="6" x2="21" y2="6" />
117
- <line x1="8" y1="12" x2="21" y2="12" />
118
- <line x1="8" y1="18" x2="21" y2="18" />
119
- <line x1="3" y1="6" x2="3.01" y2="6" />
120
- <line x1="3" y1="12" x2="3.01" y2="12" />
121
- <line x1="3" y1="18" x2="3.01" y2="18" />
122
- </svg>
123
-
124
- {title}
125
- <span className="ml-2 px-2 py-1 text-sm bg-gray-100 text-[rgb(0,137,149)] rounded-full">
126
- {count}
127
- </span>
128
- </h1>
129
- <div className="border-b border-gray-100 mb-4"></div>
130
- <div className="flex gap-4 flex-wrap justify-between">
131
- <DatePickerWithRange
132
- dateFrom={filters.fromDate}
133
- dateTo={filters.toDate}
134
- handleDateChange={handleDateChange}
135
- />
136
- {configFilters &&
137
- configFilters.map((filter: any, index: number) => (
138
- <div key={`${filter.name}-${index}`}>
139
- {filter.type === "Text" && (
140
- <Input
141
- type="text"
142
- placeholder={filter.placeholder}
143
- value={filters[filter.name]}
144
- onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
145
- setFilters({ ...filters, [filter.name]: e.target.value })
146
- }
147
- onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
148
- if (e.key === "Enter") {
149
- handleSearch();
150
- }
151
- }}
152
- />
153
- )}
154
- {filter.type === "Select" && (
155
- <Select
156
- disabled={filter.disabled || filter.options.length === 0}
157
- value={filters[filter.name]}
158
- onValueChange={(value: string) => {
159
- setFilters({
160
- ...filters,
161
- [filter.name]: value === "_empty" ? undefined : value,
162
- });
163
- }}
164
- >
165
- <SelectTrigger>
166
- <SelectValue placeholder={filter.placeholder} />
167
- </SelectTrigger>
168
- <SelectContent>
169
- {useMemo(
170
- () =>
171
- filter.options.map(
172
- (
173
- option: { VALUE: string; NAME: string },
174
- optionIndex: number
175
- ) => (
176
- <SelectItem
177
- key={`${option.VALUE}-${optionIndex}`}
178
- value={option.VALUE || "_empty"}
179
- >
180
- {option.NAME}
181
- </SelectItem>
182
- )
183
- ),
184
- [filter.options]
185
- )}
186
- </SelectContent>
187
- </Select>
188
- )}
189
- </div>
190
- ))}
191
- <div className="flex gap-2 ml-auto">
192
- {configFilters.some((filter: any) => filter.type === "Export") && (
193
- <Button
194
- disabled={exportDisabled}
195
- onClick={async () => {
196
- setExportDisabled(true);
197
- const exportFilter = configFilters.find(
198
- (filter: any) => filter.type === "Export"
199
- );
200
- await handleExport(exportFilter?.ctx);
201
- const timer = setInterval(() => {
202
- setExportDisabled(false);
203
- clearInterval(timer);
204
- }, 30000);
205
- }}
206
- size="sm"
207
- >
208
- <svg
209
- xmlns="http://www.w3.org/2000/svg"
210
- width="16"
211
- height="16"
212
- viewBox="0 0 24 24"
213
- fill="none"
214
- stroke="currentColor"
215
- strokeWidth="2"
216
- strokeLinecap="round"
217
- strokeLinejoin="round"
218
- >
219
- <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
220
- <polyline points="7 10 12 15 17 10" />
221
- <line x1="12" y1="15" x2="12" y2="3" />
222
- </svg>
223
- CSV
224
- </Button>
225
- )}
226
- <Button size="sm" onClick={handleSearch} disabled={isLoading}>
227
- {filtersChanged ? (
228
- <>
229
- <svg
230
- xmlns="http://www.w3.org/2000/svg"
231
- width="16"
232
- height="16"
233
- viewBox="0 0 24 24"
234
- fill="none"
235
- stroke="currentColor"
236
- strokeWidth="2"
237
- strokeLinecap="round"
238
- strokeLinejoin="round"
239
- >
240
- <circle cx="11" cy="11" r="8" />
241
- <path d="m21 21-4.3-4.3" />
242
- </svg>
243
- Recherche
244
- </>
245
- ) : (
246
- <>
247
- <svg
248
- width="16"
249
- height="16"
250
- viewBox="0 0 24 24"
251
- fill="none"
252
- stroke={"currentColor"}
253
- strokeWidth="2"
254
- strokeLinecap="round"
255
- strokeLinejoin="round"
256
- className="reload-icon"
257
- aria-hidden="true"
258
- >
259
- <path d="M21 12a9 9 0 11-3-6.74" />
260
- <path d="M21 3v6h-6" />
261
- </svg>
262
- Actualiser
263
- </>
264
- )}
265
- </Button>
266
- </div>
267
- </div>
268
- </div>
269
- );
270
- }