proje-react-panel 1.0.4 → 1.0.6
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/.idea/jsLinters/eslint.xml +6 -0
- package/.idea/prettier.xml +7 -0
- package/.idea/vcs.xml +1 -0
- package/README.md +18 -10
- package/dist/api/crudApi.d.ts +4 -4
- package/dist/components/layout/Layout.d.ts +1 -2
- package/dist/index.cjs.js +2 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.esm.js +2 -2
- package/package.json +5 -11
- package/src/api/crudApi.ts +19 -5
- package/src/components/layout/Layout.tsx +1 -3
- package/src/index.ts +0 -2
- package/dist/bundle.css +0 -128
- package/scripts/generate-nestjs-entity.js +0 -147
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "proje-react-panel",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.6",
|
4
4
|
"description": "",
|
5
5
|
"author": "SEFA DEMİR",
|
6
6
|
"license": "ISC",
|
@@ -14,8 +14,7 @@
|
|
14
14
|
"scripts": {
|
15
15
|
"test": "echo \"Error: no test specified\" && exit 1",
|
16
16
|
"build": "rollup -c ",
|
17
|
-
"lint": "eslint src --ext .ts,.tsx"
|
18
|
-
"generate-nestjs-entity": "node scripts/generate-nestjs-entity.js"
|
17
|
+
"lint": "eslint src --ext .ts,.tsx"
|
19
18
|
},
|
20
19
|
"repository": {
|
21
20
|
"type": "git",
|
@@ -26,15 +25,10 @@
|
|
26
25
|
"url": "https://github.com/demirsefa/proje-react-panel/issues"
|
27
26
|
},
|
28
27
|
"homepage": "https://github.com/demirsefa/proje-react-panel#readme",
|
29
|
-
"dependencies": {
|
30
|
-
"axios": "^1.8.3",
|
31
|
-
"react-hook-form": "^7.54.2",
|
32
|
-
"rollup-plugin-serve": "^3.0.0"
|
33
|
-
},
|
28
|
+
"dependencies": {},
|
34
29
|
"devDependencies": {
|
35
30
|
"@hookform/resolvers": "^4.1.3",
|
36
31
|
"@rollup/plugin-commonjs": "^28.0.3",
|
37
|
-
"@rollup/plugin-json": "^6.1.0",
|
38
32
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
39
33
|
"@types/react": "^19.0.10",
|
40
34
|
"@types/react-dom": "^19.0.4",
|
@@ -43,13 +37,13 @@
|
|
43
37
|
"class-transformer": "^0.5.1",
|
44
38
|
"class-validator": "^0.14.1",
|
45
39
|
"eslint": "^8.57.1",
|
46
|
-
"node-sass": "^9.0.0",
|
47
40
|
"react": "^19.0.0",
|
41
|
+
"react-hook-form": "^7.54.2",
|
48
42
|
"react-router-dom": "^7.3.0",
|
49
43
|
"reflect-metadata": "^0.2.2",
|
50
44
|
"rollup": "^4.35.0",
|
51
45
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
52
|
-
"rollup-plugin-
|
46
|
+
"rollup-plugin-serve": "^3.0.0",
|
53
47
|
"rollup-plugin-terser": "^7.0.2",
|
54
48
|
"rollup-plugin-typescript2": "^0.36.0",
|
55
49
|
"typescript": "^5.8.2"
|
package/src/api/crudApi.ts
CHANGED
@@ -1,16 +1,30 @@
|
|
1
|
-
import axios from 'axios';
|
2
1
|
|
3
2
|
export const CrudApi = {
|
4
3
|
getList: (api: string, page: number) => {
|
5
|
-
return
|
4
|
+
return fetch(api, {
|
5
|
+
method: "GET",
|
6
|
+
headers: { "Content-Type": "application/json" },
|
7
|
+
body: JSON.stringify({ page }),
|
8
|
+
}).then((res) => res.json());
|
6
9
|
},
|
7
10
|
create: (api: string, data: any) => {
|
8
|
-
return
|
11
|
+
return fetch(api, {
|
12
|
+
method: "POST",
|
13
|
+
headers: { "Content-Type": "application/json" },
|
14
|
+
body: JSON.stringify(data),
|
15
|
+
}).then((res) => res.json());
|
9
16
|
},
|
10
17
|
details(api: string, id: any) {
|
11
|
-
return
|
18
|
+
return fetch(`${api}/${id}`, {
|
19
|
+
method: "GET",
|
20
|
+
headers: { "Content-Type": "application/json" },
|
21
|
+
}).then((res) => res.json());
|
12
22
|
},
|
13
23
|
edit(api: string, data: any) {
|
14
|
-
return
|
24
|
+
return fetch(`${api}/${data.id}`, {
|
25
|
+
method: "PUT",
|
26
|
+
headers: { "Content-Type": "application/json" },
|
27
|
+
body: JSON.stringify(data),
|
28
|
+
}).then((res) => res.json());
|
15
29
|
},
|
16
30
|
};
|
@@ -4,14 +4,12 @@ import { SideBar } from './SideBar';
|
|
4
4
|
|
5
5
|
export function Layout({
|
6
6
|
children,
|
7
|
-
noSidebar = false,
|
8
7
|
}: {
|
9
8
|
children?: React.ReactNode;
|
10
|
-
noSidebar?: boolean;
|
11
9
|
}) {
|
12
10
|
return (
|
13
11
|
<div className="layout">
|
14
|
-
|
12
|
+
<SideBar />
|
15
13
|
<main className="content">{children || <Outlet />}</main>
|
16
14
|
</div>
|
17
15
|
);
|
package/src/index.ts
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
import "./styles/index.scss"
|
2
1
|
export { createScreens } from "./utils/createScreens";
|
3
2
|
export { getScreenForRoutes } from "./utils/getScreenForRoutes";
|
4
3
|
export { Layout } from "./components/layout/Layout";
|
5
|
-
export { SideBar } from "./components/layout/SideBar";
|
6
4
|
export {Panel} from "./components/Panel"
|
package/dist/bundle.css
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
.sidebar {
|
2
|
-
position: relative;
|
3
|
-
background-color: #f5f5f5;
|
4
|
-
height: 100vh;
|
5
|
-
transition: width 0.3s ease;
|
6
|
-
border-right: 1px solid #e0e0e0; }
|
7
|
-
.sidebar.open {
|
8
|
-
width: 250px; }
|
9
|
-
.sidebar.closed {
|
10
|
-
width: 60px; }
|
11
|
-
.sidebar.closed .nav-links a span {
|
12
|
-
display: none; }
|
13
|
-
.sidebar .toggle-button {
|
14
|
-
position: absolute;
|
15
|
-
top: 10px;
|
16
|
-
right: -12px;
|
17
|
-
width: 24px;
|
18
|
-
height: 24px;
|
19
|
-
border-radius: 50%;
|
20
|
-
background-color: #ffffff;
|
21
|
-
border: 1px solid #e0e0e0;
|
22
|
-
display: flex;
|
23
|
-
align-items: center;
|
24
|
-
justify-content: center;
|
25
|
-
cursor: pointer;
|
26
|
-
z-index: 10; }
|
27
|
-
.sidebar .toggle-button:hover {
|
28
|
-
background-color: #f0f0f0; }
|
29
|
-
.sidebar .nav-links {
|
30
|
-
display: flex;
|
31
|
-
flex-direction: column;
|
32
|
-
padding: 2rem 1rem;
|
33
|
-
height: 100%; }
|
34
|
-
.sidebar .nav-links a {
|
35
|
-
padding: 0.75rem 1rem;
|
36
|
-
margin-bottom: 0.5rem;
|
37
|
-
color: #333;
|
38
|
-
text-decoration: none;
|
39
|
-
border-radius: 4px;
|
40
|
-
font-weight: 500; }
|
41
|
-
.sidebar .nav-links a:hover {
|
42
|
-
background-color: rgba(0, 0, 0, 0.05); }
|
43
|
-
.sidebar .nav-links a.active {
|
44
|
-
background-color: rgba(0, 0, 0, 0.1); }
|
45
|
-
.sidebar .nav-links .bottom-link {
|
46
|
-
margin-top: auto; }
|
47
|
-
.sidebar .nav-links .bottom-link a {
|
48
|
-
color: #666;
|
49
|
-
font-weight: 400; }
|
50
|
-
|
51
|
-
.form-wrapper {
|
52
|
-
max-width: 400px;
|
53
|
-
padding: 20px;
|
54
|
-
background-color: #f9f9f9;
|
55
|
-
border-radius: 10px;
|
56
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
|
57
|
-
.form-wrapper form {
|
58
|
-
display: flex;
|
59
|
-
flex-direction: column; }
|
60
|
-
.form-wrapper .form-field {
|
61
|
-
margin-bottom: 16px; }
|
62
|
-
.form-wrapper .form-field label {
|
63
|
-
font-weight: bold;
|
64
|
-
margin-bottom: 6px;
|
65
|
-
display: block;
|
66
|
-
color: #333; }
|
67
|
-
.form-wrapper .form-field input[type='text'] {
|
68
|
-
padding: 10px;
|
69
|
-
font-size: 16px;
|
70
|
-
border: 1px solid #ccc;
|
71
|
-
border-radius: 5px;
|
72
|
-
width: 100%;
|
73
|
-
transition: border-color 0.2s; }
|
74
|
-
.form-wrapper .form-field input[type='text']:focus {
|
75
|
-
border-color: #007bff;
|
76
|
-
outline: none; }
|
77
|
-
.form-wrapper .form-field .error-message {
|
78
|
-
margin-top: 4px;
|
79
|
-
font-size: 14px;
|
80
|
-
color: #ff4d4f; }
|
81
|
-
.form-wrapper .submit-button {
|
82
|
-
padding: 12px;
|
83
|
-
font-size: 18px;
|
84
|
-
background-color: #007bff;
|
85
|
-
color: white;
|
86
|
-
border: none;
|
87
|
-
border-radius: 5px;
|
88
|
-
cursor: pointer;
|
89
|
-
transition: background-color 0.2s; }
|
90
|
-
.form-wrapper .submit-button:hover {
|
91
|
-
background-color: #0056b3; }
|
92
|
-
|
93
|
-
.layout {
|
94
|
-
display: flex;
|
95
|
-
min-height: 100vh;
|
96
|
-
width: 100%; }
|
97
|
-
.layout .content {
|
98
|
-
flex: 1;
|
99
|
-
padding: 1rem;
|
100
|
-
overflow-y: auto;
|
101
|
-
transition: margin-left 0.3s ease; }
|
102
|
-
|
103
|
-
.list-wrapper {
|
104
|
-
width: 100%;
|
105
|
-
padding: 16px;
|
106
|
-
background-color: #ffffff;
|
107
|
-
border-radius: 8px;
|
108
|
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }
|
109
|
-
.list-wrapper .header {
|
110
|
-
font-size: 24px;
|
111
|
-
font-weight: bold;
|
112
|
-
text-align: center;
|
113
|
-
margin-bottom: 20px; }
|
114
|
-
.list-wrapper .list-table {
|
115
|
-
width: 100%;
|
116
|
-
border-collapse: collapse; }
|
117
|
-
.list-wrapper .list-table th,
|
118
|
-
.list-wrapper .list-table td {
|
119
|
-
padding: 12px 16px;
|
120
|
-
text-align: left;
|
121
|
-
border-bottom: 1px solid #ddd; }
|
122
|
-
.list-wrapper .list-table th {
|
123
|
-
background-color: #007bff;
|
124
|
-
color: white; }
|
125
|
-
.list-wrapper .list-table tr:nth-child(even) {
|
126
|
-
background-color: #f9f9f9; }
|
127
|
-
.list-wrapper .list-table tr:hover {
|
128
|
-
background-color: #e8f4ff; }
|
@@ -1,147 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
|
3
|
-
const fs = require('fs');
|
4
|
-
const path = require('path');
|
5
|
-
const { execSync } = require('child_process');
|
6
|
-
const { program } = require('commander');
|
7
|
-
|
8
|
-
// Define command line parameters
|
9
|
-
program
|
10
|
-
.option('--src <path>', 'Source path containing NestJS entity files')
|
11
|
-
.option('--to <path>', 'Destination path for generated entity files')
|
12
|
-
.parse(process.argv);
|
13
|
-
|
14
|
-
const options = program.opts();
|
15
|
-
|
16
|
-
// Check if required parameters are provided
|
17
|
-
if (!options.src || !options.to) {
|
18
|
-
console.error('Error: Both --src and --to parameters are required');
|
19
|
-
process.exit(1);
|
20
|
-
}
|
21
|
-
|
22
|
-
// Resolve paths
|
23
|
-
const srcPath = path.resolve(process.cwd(), options.src);
|
24
|
-
const destPath = path.resolve(process.cwd(), options.to);
|
25
|
-
|
26
|
-
// Ensure destination directory exists
|
27
|
-
if (!fs.existsSync(destPath)) {
|
28
|
-
fs.mkdirSync(destPath, { recursive: true });
|
29
|
-
}
|
30
|
-
|
31
|
-
// Find all entity files in the source directory recursively
|
32
|
-
function findEntityFiles(dir) {
|
33
|
-
let results = [];
|
34
|
-
|
35
|
-
const files = fs.readdirSync(dir, { withFileTypes: true });
|
36
|
-
|
37
|
-
for (const file of files) {
|
38
|
-
const fullPath = path.join(dir, file.name);
|
39
|
-
|
40
|
-
if (file.isDirectory()) {
|
41
|
-
results = results.concat(findEntityFiles(fullPath));
|
42
|
-
} else if (file.name.endsWith('.entity.ts')) {
|
43
|
-
results.push(fullPath);
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
return results;
|
48
|
-
}
|
49
|
-
|
50
|
-
// Extract interfaces ending with *Entity and class-validator decorators
|
51
|
-
function processEntityFile(filePath) {
|
52
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
53
|
-
const fileName = path.basename(filePath);
|
54
|
-
|
55
|
-
// Regular expression to find interfaces ending with Entity
|
56
|
-
const interfaceRegex = /export\s+interface\s+(\w+Entity)\s*{([^}]*)}/gs;
|
57
|
-
const interfaceMatches = Array.from(content.matchAll(interfaceRegex));
|
58
|
-
|
59
|
-
const results = [];
|
60
|
-
|
61
|
-
for (const match of interfaceMatches) {
|
62
|
-
const interfaceName = match[1];
|
63
|
-
const interfaceContent = match[2];
|
64
|
-
|
65
|
-
// Create a new file with only the interface and class-validator imports
|
66
|
-
let newContent = `import { ${getClassValidatorImports(content)} } from 'class-validator';\n\n`;
|
67
|
-
newContent += `export interface ${interfaceName} {\n${extractPropertiesWithDecorators(interfaceContent, content)}\n}`;
|
68
|
-
|
69
|
-
results.push({
|
70
|
-
name: interfaceName,
|
71
|
-
content: newContent
|
72
|
-
});
|
73
|
-
}
|
74
|
-
|
75
|
-
return results;
|
76
|
-
}
|
77
|
-
|
78
|
-
// Extract class-validator imports from the original file
|
79
|
-
function getClassValidatorImports(content) {
|
80
|
-
const importRegex = /import\s+{([^}]*?)}\s+from\s+['"]class-validator['"]/;
|
81
|
-
const match = content.match(importRegex);
|
82
|
-
|
83
|
-
if (match && match[1]) {
|
84
|
-
return match[1].split(',')
|
85
|
-
.map(imp => imp.trim())
|
86
|
-
.filter(imp => imp !== '')
|
87
|
-
.join(', ');
|
88
|
-
}
|
89
|
-
|
90
|
-
return '';
|
91
|
-
}
|
92
|
-
|
93
|
-
// Extract properties with class-validator decorators
|
94
|
-
function extractPropertiesWithDecorators(interfaceContent, fullContent) {
|
95
|
-
const lines = interfaceContent.split('\n');
|
96
|
-
let result = '';
|
97
|
-
|
98
|
-
for (const line of lines) {
|
99
|
-
const propertyMatch = line.match(/^\s*(\w+)[\?:].*$/);
|
100
|
-
|
101
|
-
if (propertyMatch) {
|
102
|
-
const propName = propertyMatch[1];
|
103
|
-
const decoratorRegex = new RegExp(`@\\w+\\([^)]*\\)\\s*${propName}`, 'g');
|
104
|
-
const decoratorMatches = Array.from(fullContent.matchAll(decoratorRegex));
|
105
|
-
|
106
|
-
// Add all decorators for this property
|
107
|
-
if (decoratorMatches.length > 0) {
|
108
|
-
for (const dMatch of decoratorMatches) {
|
109
|
-
const decorator = dMatch[0].split(propName)[0].trim();
|
110
|
-
result += ` ${decorator}\n`;
|
111
|
-
}
|
112
|
-
}
|
113
|
-
|
114
|
-
result += ` ${line.trim()}\n\n`;
|
115
|
-
}
|
116
|
-
}
|
117
|
-
|
118
|
-
return result;
|
119
|
-
}
|
120
|
-
|
121
|
-
// Main function
|
122
|
-
function main() {
|
123
|
-
try {
|
124
|
-
console.log(`Searching for entity files in ${srcPath}...`);
|
125
|
-
const entityFiles = findEntityFiles(srcPath);
|
126
|
-
|
127
|
-
console.log(`Found ${entityFiles.length} entity files.`);
|
128
|
-
|
129
|
-
for (const file of entityFiles) {
|
130
|
-
console.log(`Processing ${file}...`);
|
131
|
-
const entities = processEntityFile(file);
|
132
|
-
|
133
|
-
for (const entity of entities) {
|
134
|
-
const outputPath = path.join(destPath, `${entity.name}.ts`);
|
135
|
-
fs.writeFileSync(outputPath, entity.content);
|
136
|
-
console.log(`Generated ${outputPath}`);
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
console.log('Done!');
|
141
|
-
} catch (error) {
|
142
|
-
console.error('Error:', error.message);
|
143
|
-
process.exit(1);
|
144
|
-
}
|
145
|
-
}
|
146
|
-
|
147
|
-
main();
|