react-admin-crud-manager 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.
- package/README.md +40 -0
- package/package.json +55 -0
- package/src/App.jsx +5 -0
- package/src/components/Button/Button.jsx +85 -0
- package/src/components/Chip/Chip.jsx +71 -0
- package/src/components/CrudPage.jsx +532 -0
- package/src/components/Details/Details.jsx +134 -0
- package/src/components/Filter/FilterDrawer.jsx +99 -0
- package/src/components/Form/Form.jsx +51 -0
- package/src/components/Form/components/Checkbox.jsx +119 -0
- package/src/components/Form/components/ImagePicker.jsx +128 -0
- package/src/components/Form/components/Input.jsx +71 -0
- package/src/components/Form/components/InputLabel.jsx +12 -0
- package/src/components/Form/components/PhoneInput.jsx +221 -0
- package/src/components/Form/components/RenderFields.jsx +181 -0
- package/src/components/Form/components/Select.jsx +191 -0
- package/src/components/Form/components/Switch.jsx +64 -0
- package/src/components/Form/components/TextArea.jsx +31 -0
- package/src/components/Form/components/TinyEditor.jsx +113 -0
- package/src/components/Loader/Spinner.jsx +21 -0
- package/src/components/Modal/Modal.jsx +152 -0
- package/src/components/Table/Table.jsx +554 -0
- package/src/components/Table/components/ImagePreview.jsx +58 -0
- package/src/components/Table/components/TableSkeleton.jsx +39 -0
- package/src/data/countries.js +252 -0
- package/src/data/teams.js +130 -0
- package/src/index.css +170 -0
- package/src/lib/utils.js +74 -0
- package/src/main.jsx +11 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# React Admin CRUD Manager
|
|
2
|
+
|
|
3
|
+
A reusable React CRUD admin template with modular components for rapid admin dashboard development.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
- Plug-and-play CRUD page component
|
|
7
|
+
- Modular, customizable UI components (Table, Modal, Form, etc.)
|
|
8
|
+
- Built with React 18+
|
|
9
|
+
- Tailwind CSS for styling
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
npm install react-admin-crud-manager
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
import { CrudPage } from 'react-admin-crud-manager';
|
|
21
|
+
|
|
22
|
+
function App() {
|
|
23
|
+
const config = {
|
|
24
|
+
title: 'Users',
|
|
25
|
+
fetchData: async () => { /* fetch logic */ },
|
|
26
|
+
// ...other config options
|
|
27
|
+
};
|
|
28
|
+
return <CrudPage config={config} />;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Components
|
|
33
|
+
- `CrudPage`: Main CRUD page component
|
|
34
|
+
- `Table`, `Modal`, `Form`, etc.: Available for advanced use
|
|
35
|
+
|
|
36
|
+
## Props
|
|
37
|
+
See the source or future documentation for full prop details.
|
|
38
|
+
|
|
39
|
+
## License
|
|
40
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-admin-crud-manager",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A reusable React CRUD admin template with modular components.",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"react",
|
|
14
|
+
"admin",
|
|
15
|
+
"crud",
|
|
16
|
+
"template",
|
|
17
|
+
"component-library"
|
|
18
|
+
],
|
|
19
|
+
"author": "Dev Flips",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/devflips/react-admin-crud-manager.git"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": ">=18.0.0",
|
|
27
|
+
"react-dom": ">=18.0.0"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"dev": "vite",
|
|
31
|
+
"build": "vite build",
|
|
32
|
+
"preview": "vite preview"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@iconify/react": "^6.0.2",
|
|
36
|
+
"@tinymce/tinymce-react": "^6.3.0",
|
|
37
|
+
"axios": "^1.11.0",
|
|
38
|
+
"clsx": "^2.1.1",
|
|
39
|
+
"date-fns": "^3.6.0",
|
|
40
|
+
"js-cookie": "^3.0.5",
|
|
41
|
+
"lucide-react": "^0.446.0",
|
|
42
|
+
"notistack": "^3.0.2",
|
|
43
|
+
"prop-types": "^15.8.1",
|
|
44
|
+
"react": "18.2.0",
|
|
45
|
+
"react-dom": "18.2.0",
|
|
46
|
+
"react-router-dom": "^7.9.1",
|
|
47
|
+
"tinymce": "^8.3.2"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
51
|
+
"autoprefixer": "10.4.15",
|
|
52
|
+
"tailwindcss": "3.3.3",
|
|
53
|
+
"vite": "^5.0.8"
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/App.jsx
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
const Button = React.forwardRef(
|
|
4
|
+
(
|
|
5
|
+
{
|
|
6
|
+
className = "",
|
|
7
|
+
variant = "contained",
|
|
8
|
+
color = "default",
|
|
9
|
+
size = "default",
|
|
10
|
+
fullWidth = false,
|
|
11
|
+
children,
|
|
12
|
+
...props
|
|
13
|
+
},
|
|
14
|
+
ref
|
|
15
|
+
) => {
|
|
16
|
+
const baseStyles =
|
|
17
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-400 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";
|
|
18
|
+
|
|
19
|
+
const sizes = {
|
|
20
|
+
sm: "h-8 px-3 rounded-md text-sm",
|
|
21
|
+
md: "h-9 px-4 rounded-md text-sm",
|
|
22
|
+
lg: "h-11 px-6 rounded-md text-base",
|
|
23
|
+
xl: "h-12 px-8 rounded-lg text-lg",
|
|
24
|
+
default: "h-9 px-4 rounded-md text-sm",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const colorVariants = {
|
|
28
|
+
primary: {
|
|
29
|
+
contained:
|
|
30
|
+
"bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500 shadow-sm",
|
|
31
|
+
outlined:
|
|
32
|
+
"border border-blue-600 bg-transparent text-blue-600 hover:bg-blue-50 focus:ring-blue-500",
|
|
33
|
+
text: "bg-transparent text-blue-600 hover:bg-blue-50 focus:ring-blue-500",
|
|
34
|
+
},
|
|
35
|
+
success: {
|
|
36
|
+
contained:
|
|
37
|
+
"bg-green-600 text-white hover:bg-green-700 focus:ring-green-500 shadow-sm",
|
|
38
|
+
outlined:
|
|
39
|
+
"border border-green-600 bg-transparent text-green-600 hover:bg-green-50 focus:ring-green-500",
|
|
40
|
+
text: "bg-transparent text-green-600 hover:bg-green-50 focus:ring-green-500",
|
|
41
|
+
},
|
|
42
|
+
error: {
|
|
43
|
+
contained:
|
|
44
|
+
"bg-red-600 text-white hover:bg-red-700 focus:ring-red-500 shadow-sm",
|
|
45
|
+
outlined:
|
|
46
|
+
"border border-red-600 bg-transparent text-red-600 hover:bg-red-50 focus:ring-red-500",
|
|
47
|
+
text: "bg-transparent text-red-600 hover:bg-red-50 focus:ring-red-500",
|
|
48
|
+
},
|
|
49
|
+
default: {
|
|
50
|
+
contained:
|
|
51
|
+
"border bg-gray-200 text-gray-800 hover:bg-gray-300 focus:ring-gray-300 shadow-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 dark:hover:bg-gray-600 dark:focus:ring-gray-600",
|
|
52
|
+
outlined:
|
|
53
|
+
"border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-gray-300 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-gray-700 dark:focus:ring-gray-500",
|
|
54
|
+
text: "bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-gray-300 dark:text-gray-200 dark:hover:bg-gray-700 dark:focus:ring-gray-500",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const colorStyles =
|
|
59
|
+
colorVariants[color]?.[variant] || colorVariants.default.contained;
|
|
60
|
+
const sizeStyles = sizes[size];
|
|
61
|
+
|
|
62
|
+
const combinedClassName = `
|
|
63
|
+
${baseStyles}
|
|
64
|
+
${colorStyles}
|
|
65
|
+
${sizeStyles}
|
|
66
|
+
${fullWidth ? "w-full" : ""}
|
|
67
|
+
${className}
|
|
68
|
+
`.trim();
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<button
|
|
72
|
+
ref={ref}
|
|
73
|
+
type={props.type || "button"}
|
|
74
|
+
className={combinedClassName}
|
|
75
|
+
{...props}
|
|
76
|
+
>
|
|
77
|
+
{children}
|
|
78
|
+
</button>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
Button.displayName = "Button";
|
|
84
|
+
|
|
85
|
+
export default Button;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
const BADGE_COLORS = {
|
|
4
|
+
blue: {
|
|
5
|
+
bg: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300",
|
|
6
|
+
border:
|
|
7
|
+
"border border-blue-300 text-blue-700 dark:border-blue-700 dark:text-blue-300",
|
|
8
|
+
},
|
|
9
|
+
teal: {
|
|
10
|
+
bg: "bg-teal-100 text-teal-800 dark:bg-teal-900/30 dark:text-teal-300",
|
|
11
|
+
border:
|
|
12
|
+
"border border-teal-300 text-teal-700 dark:border-teal-700 dark:text-teal-300",
|
|
13
|
+
},
|
|
14
|
+
purple: {
|
|
15
|
+
bg: "bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-300",
|
|
16
|
+
border:
|
|
17
|
+
"border border-purple-300 text-purple-700 dark:border-purple-700 dark:text-purple-300",
|
|
18
|
+
},
|
|
19
|
+
yellow: {
|
|
20
|
+
bg: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300",
|
|
21
|
+
border:
|
|
22
|
+
"border border-yellow-300 text-yellow-700 dark:border-yellow-700 dark:text-yellow-300",
|
|
23
|
+
},
|
|
24
|
+
green: {
|
|
25
|
+
bg: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300",
|
|
26
|
+
border:
|
|
27
|
+
"border border-green-300 text-green-700 dark:border-green-700 dark:text-green-300",
|
|
28
|
+
},
|
|
29
|
+
red: {
|
|
30
|
+
bg: "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300",
|
|
31
|
+
border:
|
|
32
|
+
"border border-red-300 text-red-700 dark:border-red-700 dark:text-red-300",
|
|
33
|
+
},
|
|
34
|
+
gray: {
|
|
35
|
+
bg: "bg-gray-100 text-gray-800 dark:bg-gray-900/30 dark:text-gray-300",
|
|
36
|
+
border:
|
|
37
|
+
"border border-gray-300 text-gray-700 dark:border-gray-700 dark:text-gray-300",
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const BADGE_VARIANTS = {
|
|
42
|
+
contained: "bg",
|
|
43
|
+
outline: "border !bg-transparent",
|
|
44
|
+
soft: "bg opacity-90",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const Chip = ({
|
|
48
|
+
label,
|
|
49
|
+
variant = "contained", // contained | outline | soft
|
|
50
|
+
color = "green",
|
|
51
|
+
className = "",
|
|
52
|
+
}) => {
|
|
53
|
+
const colorConfig = BADGE_COLORS[color] || BADGE_COLORS.green;
|
|
54
|
+
const variantKey = BADGE_VARIANTS[variant] || BADGE_VARIANTS.contained;
|
|
55
|
+
|
|
56
|
+
const variantClasses =
|
|
57
|
+
variant === "outline" ? colorConfig.border : colorConfig.bg;
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<span
|
|
61
|
+
className={`inline-flex justify-center items-center rounded-sm text-xs font-semibold px-3 py-1 min-w-[78px]
|
|
62
|
+
${variantClasses}
|
|
63
|
+
${variantKey}
|
|
64
|
+
${className}`}
|
|
65
|
+
>
|
|
66
|
+
{label}
|
|
67
|
+
</span>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default Chip;
|