mobigrid-module 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) 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/Layout/PageHeader.d.ts +13 -0
  5. package/dist/components/ui/alert.d.ts +8 -0
  6. package/dist/components/ui/button.d.ts +11 -0
  7. package/dist/components/ui/calendar.d.ts +8 -0
  8. package/dist/components/ui/date-picker-with-range.d.ts +7 -0
  9. package/dist/components/ui/dialog.d.ts +19 -0
  10. package/dist/components/ui/input.d.ts +3 -0
  11. package/dist/components/ui/pagination.d.ts +28 -0
  12. package/dist/components/ui/popover.d.ts +7 -0
  13. package/dist/components/ui/select.d.ts +13 -0
  14. package/dist/components/ui/sonner.d.ts +5 -0
  15. package/dist/components/ui/table.d.ts +10 -0
  16. package/dist/index.d.ts +9 -0
  17. package/dist/index.esm.js +70 -0
  18. package/dist/index.esm.js.map +1 -0
  19. package/dist/index.tsx +70 -0
  20. package/dist/index.tsx.map +1 -0
  21. package/dist/lib/utils.d.ts +2 -0
  22. package/package.json +67 -0
  23. package/rollup.config.js +35 -0
  24. package/src/components/CustomTable/CustomTable.tsx +182 -0
  25. package/src/components/CustomTable/Pagination.tsx +136 -0
  26. package/src/components/Icon.tsx +27 -0
  27. package/src/components/Layout/PageHeader.tsx +270 -0
  28. package/src/components/ui/alert.tsx +59 -0
  29. package/src/components/ui/button.tsx +57 -0
  30. package/src/components/ui/calendar.tsx +70 -0
  31. package/src/components/ui/date-picker-with-range.tsx +167 -0
  32. package/src/components/ui/dialog.tsx +120 -0
  33. package/src/components/ui/input.tsx +22 -0
  34. package/src/components/ui/pagination.tsx +117 -0
  35. package/src/components/ui/popover.tsx +31 -0
  36. package/src/components/ui/select.tsx +157 -0
  37. package/src/components/ui/sonner.tsx +30 -0
  38. package/src/components/ui/table.tsx +120 -0
  39. package/src/index.tsx +252 -0
  40. package/src/lib/utils.ts +6 -0
  41. package/tsconfig.json +27 -0
  42. package/vite.config.ts +6 -0
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "mobigrid-module",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.tsx",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1",
9
+ "build": "rollup -c"
10
+ },
11
+ "keywords": [],
12
+ "author": "",
13
+ "license": "ISC",
14
+ "dependencies": {
15
+ "@radix-ui/react-checkbox": "^1.1.2",
16
+ "@radix-ui/react-dialog": "^1.1.2",
17
+ "@radix-ui/react-popover": "^1.1.2",
18
+ "@radix-ui/react-select": "^2.1.2",
19
+ "@radix-ui/react-slot": "^1.1.0",
20
+ "@rollup/plugin-commonjs": "^28.0.1",
21
+ "@rollup/plugin-node-resolve": "^15.3.0",
22
+ "@rollup/plugin-typescript": "^12.1.1",
23
+ "@tanstack/react-table": "^8.20.5",
24
+ "axios": "^1.7.8",
25
+ "date-fns": "^4.1.0",
26
+ "lucide-react": "^0.462.0",
27
+ "next-themes": "^0.4.3",
28
+ "react-day-picker": "8.10.1",
29
+ "react-feather": "^2.0.10",
30
+ "rollup-plugin-peer-deps-external": "^2.2.4",
31
+ "rollup-plugin-terser": "^7.0.2",
32
+ "sonner": "^1.7.0",
33
+ "tslib": "^2.8.1"
34
+ },
35
+ "devDependencies": {
36
+ "@babel/cli": "^7.25.9",
37
+ "@babel/core": "^7.26.0",
38
+ "@babel/preset-env": "^7.26.0",
39
+ "@babel/preset-react": "^7.25.9",
40
+ "@babel/preset-typescript": "^7.26.0",
41
+ "@eslint/js": "^9.13.0",
42
+ "@rollup/plugin-json": "^6.1.0",
43
+ "@shadcn/ui": "^0.0.4",
44
+ "@types/node": "^22.10.1",
45
+ "@types/react": "^18.3.12",
46
+ "@types/react-dom": "^18.3.1",
47
+ "@vitejs/plugin-react": "^4.3.3",
48
+ "autoprefixer": "^10.4.20",
49
+ "class-variance-authority": "^0.7.0",
50
+ "clsx": "^2.1.1",
51
+ "eslint": "^9.13.0",
52
+ "eslint-plugin-react-hooks": "^5.0.0",
53
+ "eslint-plugin-react-refresh": "^0.4.14",
54
+ "globals": "^15.11.0",
55
+ "lucide-react": "^0.456.0",
56
+ "postcss": "^8.4.47",
57
+ "react": "^18.3.1",
58
+ "react-dom": "^18.3.1",
59
+ "tailwind-merge": "^2.5.5",
60
+ "tailwindcss": "^3.4.14",
61
+ "tailwindcss-animate": "^1.0.7",
62
+ "tsup": "^8.3.5",
63
+ "typescript": "^5.7.2",
64
+ "typescript-eslint": "^8.11.0",
65
+ "vite": "^5.4.10"
66
+ }
67
+ }
@@ -0,0 +1,35 @@
1
+ import resolve from "@rollup/plugin-node-resolve";
2
+ import commonjs from "@rollup/plugin-commonjs";
3
+ import peerDepsExternal from "rollup-plugin-peer-deps-external";
4
+ import typescript from "@rollup/plugin-typescript";
5
+ import { terser } from "rollup-plugin-terser";
6
+ import json from '@rollup/plugin-json';
7
+
8
+ export default {
9
+ input: "src/index.tsx",
10
+ output: [
11
+ {
12
+ file: "dist/index.tsx",
13
+ format: "cjs",
14
+ sourcemap: true,
15
+ },
16
+ {
17
+ file: "dist/index.esm.js",
18
+ format: "esm",
19
+ sourcemap: true,
20
+ },
21
+ ],
22
+ plugins: [
23
+ peerDepsExternal(),
24
+ resolve(),
25
+ commonjs(),
26
+ typescript({
27
+ tsconfig: "./tsconfig.json",
28
+ outDir: "./dist",
29
+ declarationDir: "./dist"
30
+ }),
31
+ terser(),
32
+ json(),
33
+ ],
34
+ external: ["react", "react-dom"],
35
+ };
@@ -0,0 +1,182 @@
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 "../../components/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
+ }
@@ -0,0 +1,136 @@
1
+ import React from "react";
2
+ import {
3
+ Pagination,
4
+ PaginationContent,
5
+ PaginationEllipsis,
6
+ PaginationItem,
7
+ PaginationLink,
8
+ PaginationNext,
9
+ PaginationPrevious,
10
+ } from "../../components/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
+ }
@@ -0,0 +1,27 @@
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;