himanshu-toolkit 1.0.4 → 1.0.5
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/App3.jsx +226 -0
- package/database3.sql +10 -0
- package/package.json +5 -2
- package/server4.js +107 -0
package/App3.jsx
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import 'bootstrap/dist/css/bootstrap.min.css';
|
|
3
|
+
|
|
4
|
+
const API = 'http://localhost:5000/students';
|
|
5
|
+
|
|
6
|
+
export default function App() {
|
|
7
|
+
const [students, setStudents] = useState([]);
|
|
8
|
+
const [form, setForm] = useState({ sid: '', sname: '', course: '' });
|
|
9
|
+
const [editId, setEditId] = useState(null);
|
|
10
|
+
const [showForm, setShowForm] = useState(false);
|
|
11
|
+
const [message, setMessage] = useState('');
|
|
12
|
+
const [error, setError] = useState('');
|
|
13
|
+
|
|
14
|
+
const loadStudents = async () => {
|
|
15
|
+
try {
|
|
16
|
+
const res = await fetch(API);
|
|
17
|
+
const data = await res.json();
|
|
18
|
+
if (!res.ok) throw new Error(data.error || 'Failed to load students');
|
|
19
|
+
setStudents(data);
|
|
20
|
+
} catch (e) {
|
|
21
|
+
setError(e.message);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
loadStudents();
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
const handleChange = e =>
|
|
30
|
+
setForm({ ...form, [e.target.name]: e.target.value });
|
|
31
|
+
|
|
32
|
+
const handleSubmit = async e => {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
setMessage('');
|
|
35
|
+
setError('');
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const res = await fetch(
|
|
39
|
+
editId ? `${API}/${editId}` : API,
|
|
40
|
+
{
|
|
41
|
+
method: editId ? 'PUT' : 'POST',
|
|
42
|
+
headers: { 'Content-Type': 'application/json' },
|
|
43
|
+
body: JSON.stringify({
|
|
44
|
+
...form,
|
|
45
|
+
sid: Number(form.sid),
|
|
46
|
+
sname: form.sname.trim(),
|
|
47
|
+
course: form.course.trim()
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const data = await res.json();
|
|
53
|
+
if (!res.ok) throw new Error(data.error || 'Operation failed');
|
|
54
|
+
|
|
55
|
+
setMessage(data.message);
|
|
56
|
+
setForm({ sid: '', sname: '', course: '' });
|
|
57
|
+
setEditId(null);
|
|
58
|
+
setShowForm(false);
|
|
59
|
+
await loadStudents();
|
|
60
|
+
} catch (e) {
|
|
61
|
+
setError(e.message);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const editStudent = student => {
|
|
66
|
+
setForm({
|
|
67
|
+
sid: student.sid,
|
|
68
|
+
sname: student.sname,
|
|
69
|
+
course: student.course
|
|
70
|
+
});
|
|
71
|
+
setEditId(student.sid);
|
|
72
|
+
setShowForm(true);
|
|
73
|
+
setMessage('');
|
|
74
|
+
setError('');
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const deleteStudent = async sid => {
|
|
78
|
+
if (!window.confirm('Delete this student?')) return;
|
|
79
|
+
|
|
80
|
+
setMessage('');
|
|
81
|
+
setError('');
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const res = await fetch(`${API}/${sid}`, { method: 'DELETE' });
|
|
85
|
+
const data = await res.json();
|
|
86
|
+
if (!res.ok) throw new Error(data.error || 'Delete failed');
|
|
87
|
+
|
|
88
|
+
setMessage(data.message);
|
|
89
|
+
if (editId === sid) {
|
|
90
|
+
setEditId(null);
|
|
91
|
+
setShowForm(false);
|
|
92
|
+
setForm({ sid: '', sname: '', course: '' });
|
|
93
|
+
}
|
|
94
|
+
await loadStudents();
|
|
95
|
+
} catch (e) {
|
|
96
|
+
setError(e.message);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div className="container py-5">
|
|
102
|
+
<div className="card shadow">
|
|
103
|
+
<div className="card-header bg-primary text-white text-center">
|
|
104
|
+
<h2>Student Management System</h2>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div className="card-body">
|
|
108
|
+
{message && <div className="alert alert-success">{message}</div>}
|
|
109
|
+
{error && <div className="alert alert-danger">{error}</div>}
|
|
110
|
+
|
|
111
|
+
<button
|
|
112
|
+
className="btn btn-success mb-3"
|
|
113
|
+
onClick={() => {
|
|
114
|
+
setForm({ sid: '', sname: '', course: '' });
|
|
115
|
+
setEditId(null);
|
|
116
|
+
setShowForm(true);
|
|
117
|
+
setMessage('');
|
|
118
|
+
setError('');
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
Add New Student
|
|
122
|
+
</button>
|
|
123
|
+
|
|
124
|
+
{showForm && (
|
|
125
|
+
<form onSubmit={handleSubmit} className="border rounded p-3 mb-4">
|
|
126
|
+
<h5>{editId ? 'Edit Student' : 'Add Student'}</h5>
|
|
127
|
+
|
|
128
|
+
<input
|
|
129
|
+
className="form-control mb-3"
|
|
130
|
+
type="number"
|
|
131
|
+
name="sid"
|
|
132
|
+
placeholder="Student ID"
|
|
133
|
+
value={form.sid}
|
|
134
|
+
onChange={handleChange}
|
|
135
|
+
disabled={editId !== null}
|
|
136
|
+
min="1"
|
|
137
|
+
required
|
|
138
|
+
/>
|
|
139
|
+
|
|
140
|
+
<input
|
|
141
|
+
className="form-control mb-3"
|
|
142
|
+
name="sname"
|
|
143
|
+
placeholder="Student Name"
|
|
144
|
+
value={form.sname}
|
|
145
|
+
onChange={handleChange}
|
|
146
|
+
required
|
|
147
|
+
/>
|
|
148
|
+
|
|
149
|
+
<input
|
|
150
|
+
className="form-control mb-3"
|
|
151
|
+
name="course"
|
|
152
|
+
placeholder="Course"
|
|
153
|
+
value={form.course}
|
|
154
|
+
onChange={handleChange}
|
|
155
|
+
required
|
|
156
|
+
/>
|
|
157
|
+
|
|
158
|
+
<button className="btn btn-primary me-2" type="submit">
|
|
159
|
+
{editId ? 'Update Student' : 'Submit Student'}
|
|
160
|
+
</button>
|
|
161
|
+
|
|
162
|
+
<button
|
|
163
|
+
className="btn btn-secondary"
|
|
164
|
+
type="button"
|
|
165
|
+
onClick={() => {
|
|
166
|
+
setShowForm(false);
|
|
167
|
+
setEditId(null);
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
Cancel
|
|
171
|
+
</button>
|
|
172
|
+
</form>
|
|
173
|
+
)}
|
|
174
|
+
|
|
175
|
+
<h4>Student Records</h4>
|
|
176
|
+
|
|
177
|
+
<div className="table-responsive">
|
|
178
|
+
<table className="table table-bordered table-striped table-hover">
|
|
179
|
+
<thead className="table-dark">
|
|
180
|
+
<tr>
|
|
181
|
+
<th>Student ID</th>
|
|
182
|
+
<th>Student Name</th>
|
|
183
|
+
<th>Course</th>
|
|
184
|
+
<th>Actions</th>
|
|
185
|
+
</tr>
|
|
186
|
+
</thead>
|
|
187
|
+
|
|
188
|
+
<tbody>
|
|
189
|
+
{students.map(student => (
|
|
190
|
+
<tr key={student.sid}>
|
|
191
|
+
<td>{student.sid}</td>
|
|
192
|
+
<td>{student.sname}</td>
|
|
193
|
+
<td>{student.course}</td>
|
|
194
|
+
<td>
|
|
195
|
+
<button
|
|
196
|
+
className="btn btn-warning btn-sm me-2"
|
|
197
|
+
onClick={() => editStudent(student)}
|
|
198
|
+
>
|
|
199
|
+
Edit
|
|
200
|
+
</button>
|
|
201
|
+
|
|
202
|
+
<button
|
|
203
|
+
className="btn btn-danger btn-sm"
|
|
204
|
+
onClick={() => deleteStudent(student.sid)}
|
|
205
|
+
>
|
|
206
|
+
Delete
|
|
207
|
+
</button>
|
|
208
|
+
</td>
|
|
209
|
+
</tr>
|
|
210
|
+
))}
|
|
211
|
+
|
|
212
|
+
{students.length === 0 && (
|
|
213
|
+
<tr>
|
|
214
|
+
<td colSpan="4" className="text-center">
|
|
215
|
+
No students found.
|
|
216
|
+
</td>
|
|
217
|
+
</tr>
|
|
218
|
+
)}
|
|
219
|
+
</tbody>
|
|
220
|
+
</table>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
);
|
|
226
|
+
}
|
package/database3.sql
ADDED
package/package.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "himanshu-toolkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "My reusable full-stack application toolkit",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"App.jsx",
|
|
8
8
|
"App1.jsx",
|
|
9
9
|
"App2.jsx",
|
|
10
|
+
"App3.jsx",
|
|
10
11
|
"database.sql",
|
|
11
12
|
"database1.sql",
|
|
12
13
|
"database2.sql",
|
|
14
|
+
"database3.sql",
|
|
13
15
|
"server.js",
|
|
14
16
|
"server1.js",
|
|
15
|
-
"server3.js"
|
|
17
|
+
"server3.js",
|
|
18
|
+
"server4.js"
|
|
16
19
|
],
|
|
17
20
|
"keywords": [
|
|
18
21
|
"react",
|
package/server4.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const mysql = require('mysql2/promise');
|
|
4
|
+
const cors = require('cors');
|
|
5
|
+
|
|
6
|
+
const app = express();
|
|
7
|
+
app.use(cors());
|
|
8
|
+
app.use(express.json());
|
|
9
|
+
|
|
10
|
+
const db = mysql.createPool({
|
|
11
|
+
host: 'localhost',
|
|
12
|
+
user: 'root',
|
|
13
|
+
password: process.env.DB_PASSWORD || 'Himanshu@0334',
|
|
14
|
+
database: 'student_db',
|
|
15
|
+
waitForConnections: true,
|
|
16
|
+
connectionLimit: 10
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// GET: Display all students
|
|
20
|
+
app.get('/students', async (req, res) => {
|
|
21
|
+
try {
|
|
22
|
+
const [rows] = await db.query('SELECT * FROM students ORDER BY sid');
|
|
23
|
+
res.json(rows);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error(err);
|
|
26
|
+
res.status(500).json({ error: 'Failed to fetch students.' });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// POST: Add a student
|
|
31
|
+
app.post('/students', async (req, res) => {
|
|
32
|
+
const { sid, sname, course } = req.body;
|
|
33
|
+
|
|
34
|
+
if (!Number.isInteger(Number(sid)) || Number(sid) <= 0 ||
|
|
35
|
+
typeof sname !== 'string' || !sname.trim() ||
|
|
36
|
+
typeof course !== 'string' || !course.trim()) {
|
|
37
|
+
return res.status(400).json({ error: 'Enter a valid ID, name and course.' });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
await db.execute(
|
|
42
|
+
'INSERT INTO students (sid, sname, course) VALUES (?, ?, ?)',
|
|
43
|
+
[Number(sid), sname.trim(), course.trim()]
|
|
44
|
+
);
|
|
45
|
+
res.status(201).json({ message: 'Student added successfully.' });
|
|
46
|
+
} catch (err) {
|
|
47
|
+
if (err.code === 'ER_DUP_ENTRY')
|
|
48
|
+
return res.status(409).json({ error: 'Student ID already exists.' });
|
|
49
|
+
|
|
50
|
+
console.error(err);
|
|
51
|
+
res.status(500).json({ error: 'Failed to add student.' });
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// PUT: Update a student
|
|
56
|
+
app.put('/students/:sid', async (req, res) => {
|
|
57
|
+
const { sname, course } = req.body;
|
|
58
|
+
const sid = Number(req.params.sid);
|
|
59
|
+
|
|
60
|
+
if (!Number.isInteger(sid) || sid <= 0 ||
|
|
61
|
+
typeof sname !== 'string' || !sname.trim() ||
|
|
62
|
+
typeof course !== 'string' || !course.trim()) {
|
|
63
|
+
return res.status(400).json({ error: 'Enter a valid name and course.' });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const [result] = await db.execute(
|
|
68
|
+
'UPDATE students SET sname = ?, course = ? WHERE sid = ?',
|
|
69
|
+
[sname.trim(), course.trim(), sid]
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
if (!result.affectedRows) {
|
|
73
|
+
const [rows] = await db.execute(
|
|
74
|
+
'SELECT sid FROM students WHERE sid = ?', [sid]
|
|
75
|
+
);
|
|
76
|
+
if (!rows.length)
|
|
77
|
+
return res.status(404).json({ error: 'Student not found.' });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
res.json({ message: 'Student updated successfully.' });
|
|
81
|
+
} catch (err) {
|
|
82
|
+
console.error(err);
|
|
83
|
+
res.status(500).json({ error: 'Failed to update student.' });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// DELETE: Remove a student
|
|
88
|
+
app.delete('/students/:sid', async (req, res) => {
|
|
89
|
+
try {
|
|
90
|
+
const [result] = await db.execute(
|
|
91
|
+
'DELETE FROM students WHERE sid = ?',
|
|
92
|
+
[Number(req.params.sid)]
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
if (!result.affectedRows)
|
|
96
|
+
return res.status(404).json({ error: 'Student not found.' });
|
|
97
|
+
|
|
98
|
+
res.json({ message: 'Student deleted successfully.' });
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.error(err);
|
|
101
|
+
res.status(500).json({ error: 'Failed to delete student.' });
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
app.listen(5000, () =>
|
|
106
|
+
console.log('Server running at http://localhost:5000')
|
|
107
|
+
);
|