matarial-init 1.0.0 → 1.0.1
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 +71 -36
- package/index.js +26 -0
- package/package.json +6 -6
- package/bin/cli.js +0 -7
- package/bin/copy-src.js +0 -86
- package/bin/postinstall.js +0 -6
package/README.md
CHANGED
|
@@ -1,62 +1,97 @@
|
|
|
1
1
|
# matarial-init
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A standard NPM package providing a dynamic workflow React Context, components, and interactive Dashboard with live public placeholder API integration.
|
|
4
|
+
|
|
5
|
+
Installs strictly into `node_modules` without modifying your project's folders, and removes completely on `npm uninstall`.
|
|
4
6
|
|
|
5
7
|
---
|
|
6
8
|
|
|
7
|
-
##
|
|
9
|
+
## 📦 Installation
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
Run inside your React project:
|
|
11
|
+
Install into your project's `node_modules`:
|
|
11
12
|
```bash
|
|
12
13
|
npm install matarial-init
|
|
13
14
|
```
|
|
14
|
-
During installation, the `postinstall` script will automatically copy the full `src/` directory into your project root.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
You can also run the initialization script directly anytime:
|
|
16
|
+
To remove:
|
|
20
17
|
```bash
|
|
21
|
-
|
|
18
|
+
npm uninstall matarial-init
|
|
22
19
|
```
|
|
20
|
+
*(Removes the package cleanly from `node_modules` without leaving any artifacts in your project).*
|
|
23
21
|
|
|
24
22
|
---
|
|
25
23
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
- **`src/context/`**:
|
|
29
|
-
- `dataContext.js`: `DataContext` declaration & default public placeholder API fetch handler (`https://jsonplaceholder.typicode.com`).
|
|
30
|
-
- `DataContext.jsx`: `DataProvider` component wrapping your React app.
|
|
31
|
-
- `useData.jsx`: Dynamic workflow hook supporting fetching, caching, loading/error states, and mutations (`addData`, `updateData`, `deleteData`, `refresh`).
|
|
32
|
-
- **`src/pages/`**:
|
|
33
|
-
- `DashBoard.jsx`: Dynamic Dashboard with live public placeholder API integration, resource tabs (Posts, Todos, Users), metrics cards, search filter, pagination, record modals, and deletion.
|
|
34
|
-
- `Books.jsx`, `Members.jsx`, `MyBooks.jsx`, `Penalty.jsx`, `Home.jsx`, `Signin.jsx`, `SignUp.jsx`.
|
|
35
|
-
- **`src/components/`**:
|
|
36
|
-
- `Table.jsx`, `Modal.jsx`, `Button.jsx`, `Input.jsx`, `Header.jsx`, `Sidebar.jsx`, `Navbar.jsx`.
|
|
37
|
-
- **`src/layout/`**: `DashboardLayout.jsx`, `PublicLayout.jsx`.
|
|
38
|
-
- **`src/routes/`**: `ProtectedRoute.jsx`, `PublicRoute.jsx`.
|
|
39
|
-
- **`src/validation/`**: Yup validation schemas.
|
|
40
|
-
- **`src/constants/`**: Permissions and storage keys.
|
|
41
|
-
- **`src/uttils/`**: Local persistence helpers.
|
|
24
|
+
## 🚀 Usage
|
|
42
25
|
|
|
43
|
-
|
|
26
|
+
You can import any of the components, contexts, hooks, or pages directly from `"matarial-init"`:
|
|
44
27
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
### 1. Wrap your application with `DataProvider`
|
|
29
|
+
```jsx
|
|
30
|
+
import React from "react"
|
|
31
|
+
import { DataProvider } from "matarial-init"
|
|
32
|
+
import App from "./App"
|
|
33
|
+
|
|
34
|
+
export default function Root() {
|
|
35
|
+
return (
|
|
36
|
+
<DataProvider>
|
|
37
|
+
<App />
|
|
38
|
+
</DataProvider>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
49
41
|
```
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
|
|
43
|
+
### 2. Use the `useData` dynamic workflow hook
|
|
44
|
+
```jsx
|
|
45
|
+
import { useData } from "matarial-init"
|
|
46
|
+
|
|
47
|
+
export function PostList() {
|
|
48
|
+
// Automatically fetches from https://jsonplaceholder.typicode.com/posts
|
|
49
|
+
const { collection, loading, error, refresh, addData, deleteData } = useData("posts")
|
|
50
|
+
|
|
51
|
+
if (loading) return <p>Loading...</p>
|
|
52
|
+
if (error) return <p>Error loading data</p>
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div>
|
|
56
|
+
<button onClick={refresh}>Refresh</button>
|
|
57
|
+
<ul>
|
|
58
|
+
{collection.map(post => (
|
|
59
|
+
<li key={post.id}>
|
|
60
|
+
{post.title}
|
|
61
|
+
<button onClick={() => deleteData(p => p.id !== post.id)}>Delete</button>
|
|
62
|
+
</li>
|
|
63
|
+
))}
|
|
64
|
+
</ul>
|
|
65
|
+
</div>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3. Use the dynamic `Dashboard` page
|
|
71
|
+
```jsx
|
|
72
|
+
import { Dashboard } from "matarial-init"
|
|
73
|
+
|
|
74
|
+
export function DashboardPage() {
|
|
75
|
+
return <Dashboard />
|
|
76
|
+
}
|
|
53
77
|
```
|
|
54
78
|
|
|
55
79
|
---
|
|
56
80
|
|
|
57
|
-
##
|
|
81
|
+
## 🧩 Exported Members
|
|
82
|
+
|
|
83
|
+
- **Context & Hooks**: `DataProvider`, `DataContext`, `defaultSource`, `useData`, `usePermission`
|
|
84
|
+
- **Pages**: `Dashboard`, `Books`, `Members`, `MyBooks`, `Penalty`, `Home`, `SignIn`, `SignUp`
|
|
85
|
+
- **Components**: `Table`, `Modal`, `Button`, `Input`, `Header`, `Sidebar`, `Navbar`
|
|
86
|
+
- **Layouts & Routes**: `DashboardLayout`, `PublicLayout`, `ProtectedRoute`, `PublicRoute`
|
|
87
|
+
- **Utilities**: `getData`, `setData`, `getCollection`, `addData`, `updateData`, `deleteData`, `clearData`
|
|
88
|
+
- **Constants**: `STORAGE_KEYS`, `SIDEBAR_MENU`, `PERMISSIONS`, `Role`
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 🚢 Publishing
|
|
58
93
|
|
|
59
|
-
To publish
|
|
94
|
+
To publish to the npm registry:
|
|
60
95
|
```bash
|
|
61
96
|
npm login
|
|
62
97
|
npm publish --access public
|
package/index.js
CHANGED
|
@@ -1,9 +1,35 @@
|
|
|
1
|
+
// Context & Hooks
|
|
1
2
|
export { DataContext, defaultSource } from "./src/context/dataContext.js"
|
|
2
3
|
export { DataProvider } from "./src/context/DataContext.jsx"
|
|
3
4
|
export { useData } from "./src/context/useData.jsx"
|
|
5
|
+
export { usePermission } from "./src/hooks/usePermission.jsx"
|
|
6
|
+
|
|
7
|
+
// UI Components
|
|
8
|
+
export { default as Button } from "./src/components/Button.jsx"
|
|
9
|
+
export { default as Input } from "./src/components/Input.jsx"
|
|
10
|
+
export { Modal } from "./src/components/Modal.jsx"
|
|
11
|
+
export { Table } from "./src/components/Table.jsx"
|
|
12
|
+
export { Header } from "./src/components/Header.jsx"
|
|
13
|
+
export { Sidebar } from "./src/components/Sidebar.jsx"
|
|
14
|
+
export { default as Navbar } from "./src/components/Navbar.jsx"
|
|
15
|
+
|
|
16
|
+
// Layouts & Routes
|
|
17
|
+
export { DashboardLayout } from "./src/layout/DashboardLayout.jsx"
|
|
18
|
+
export { PublicLayout } from "./src/layout/PublicLayout.jsx"
|
|
19
|
+
export { ProtectedRoute } from "./src/routes/ProtectedRoute.jsx"
|
|
20
|
+
export { PublicRoute } from "./src/routes/PublicRoute.jsx"
|
|
21
|
+
|
|
22
|
+
// Pages
|
|
4
23
|
export { default as Dashboard } from "./src/pages/DashBoard.jsx"
|
|
5
24
|
export { default as Books } from "./src/pages/Books.jsx"
|
|
6
25
|
export { default as Members } from "./src/pages/Members.jsx"
|
|
7
26
|
export { default as MyBooks } from "./src/pages/MyBooks.jsx"
|
|
27
|
+
export { default as Penalty } from "./src/pages/Penalty.jsx"
|
|
28
|
+
export { default as Home } from "./src/pages/Home.jsx"
|
|
8
29
|
export { default as SignIn } from "./src/pages/Signin.jsx"
|
|
9
30
|
export { default as SignUp } from "./src/pages/SignUp.jsx"
|
|
31
|
+
|
|
32
|
+
// Constants & Utilities
|
|
33
|
+
export * from "./src/constants/storageKeys.js"
|
|
34
|
+
export * from "./src/constants/permissions.js"
|
|
35
|
+
export * from "./src/uttils/persistence.js"
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matarial-init",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Dynamic workflow React Context, components, and Dashboard library.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
|
-
"
|
|
8
|
-
|
|
7
|
+
"module": "index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./index.js",
|
|
10
|
+
"./*": "./*"
|
|
9
11
|
},
|
|
10
12
|
"files": [
|
|
11
13
|
"src",
|
|
12
|
-
"bin",
|
|
13
14
|
"index.js",
|
|
14
15
|
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
|
-
"postinstall": "node ./bin/postinstall.js",
|
|
18
18
|
"dev": "vite",
|
|
19
19
|
"build": "vite build",
|
|
20
20
|
"lint": "eslint .",
|
package/bin/cli.js
DELETED
package/bin/copy-src.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import path from "path"
|
|
3
|
-
import { fileURLToPath } from "url"
|
|
4
|
-
|
|
5
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
6
|
-
const __dirname = path.dirname(__filename)
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Recursively copies all files and directories from source to destination.
|
|
10
|
-
*/
|
|
11
|
-
export function copyFolderSync(from, to) {
|
|
12
|
-
if (!fs.existsSync(to)) {
|
|
13
|
-
fs.mkdirSync(to, { recursive: true })
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const entries = fs.readdirSync(from, { withFileTypes: true })
|
|
17
|
-
|
|
18
|
-
for (const entry of entries) {
|
|
19
|
-
const srcPath = path.join(from, entry.name)
|
|
20
|
-
const destPath = path.join(to, entry.name)
|
|
21
|
-
|
|
22
|
-
if (entry.isDirectory()) {
|
|
23
|
-
copyFolderSync(srcPath, destPath)
|
|
24
|
-
} else {
|
|
25
|
-
fs.copyFileSync(srcPath, destPath)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Detects the root directory of the consumer project.
|
|
32
|
-
*/
|
|
33
|
-
export function detectConsumerDir() {
|
|
34
|
-
const packageDir = path.resolve(__dirname, "..")
|
|
35
|
-
|
|
36
|
-
// Case 1: If installed inside node_modules, find the parent project root
|
|
37
|
-
const parts = packageDir.split(path.sep)
|
|
38
|
-
const nmIndex = parts.lastIndexOf("node_modules")
|
|
39
|
-
if (nmIndex > 0) {
|
|
40
|
-
const consumerRoot = parts.slice(0, nmIndex).join(path.sep)
|
|
41
|
-
if (consumerRoot && fs.existsSync(consumerRoot)) {
|
|
42
|
-
return consumerRoot
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Case 2: If invoked via npm install, npm sets INIT_CWD to the invoking directory
|
|
47
|
-
if (process.env.INIT_CWD) {
|
|
48
|
-
const initCwd = path.resolve(process.env.INIT_CWD)
|
|
49
|
-
if (initCwd !== packageDir) {
|
|
50
|
-
return initCwd
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Case 3: Direct CLI execution (e.g. npx matarial-init)
|
|
55
|
-
return process.cwd()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Installs the package's src directory into the target project directory.
|
|
60
|
-
*/
|
|
61
|
-
export function installSrc(targetBaseDir = null) {
|
|
62
|
-
const packageDir = path.resolve(__dirname, "..")
|
|
63
|
-
const resolvedTarget = path.resolve(targetBaseDir || detectConsumerDir())
|
|
64
|
-
|
|
65
|
-
// Skip if running within the package's own root during local development or build
|
|
66
|
-
if (resolvedTarget === packageDir) {
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const sourceSrc = path.join(packageDir, "src")
|
|
71
|
-
const targetSrc = path.join(resolvedTarget, "src")
|
|
72
|
-
|
|
73
|
-
if (!fs.existsSync(sourceSrc)) {
|
|
74
|
-
console.error(`\x1b[31m[matarial-init] Error: Source 'src' directory not found at: ${sourceSrc}\x1b[0m`)
|
|
75
|
-
return
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
console.log(`\x1b[36m[matarial-init] Installing 'src' folder into: ${targetSrc}...\x1b[0m`)
|
|
80
|
-
copyFolderSync(sourceSrc, targetSrc)
|
|
81
|
-
console.log(`\x1b[32m✔ [matarial-init] Successfully installed 'src' folder into your project!\x1b[0m`)
|
|
82
|
-
console.log(`\x1b[35m[matarial-init] Included: DataContext, useData, Dashboard, Components, Routes, Layout, and Utils.\x1b[0m`)
|
|
83
|
-
} catch (err) {
|
|
84
|
-
console.error(`\x1b[31m[matarial-init] Failed to copy 'src' folder: ${err.message}\x1b[0m`)
|
|
85
|
-
}
|
|
86
|
-
}
|