sms-tps 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/backend-project/.env +1 -1
- package/backend-project/Controller/ProductController.js +43 -0
- package/backend-project/Controller/StockTransactionController.js +89 -0
- package/backend-project/Controller/WarehouseController.js +20 -0
- package/backend-project/Models/ProductModel.js +17 -0
- package/backend-project/Models/StockTransactionModel.js +16 -0
- package/backend-project/Models/WarehouseModel.js +12 -0
- package/backend-project/Router/ProductRouter.js +7 -0
- package/backend-project/Router/StockTransactionRouter.js +10 -0
- package/backend-project/Router/WarehouseRouter.js +8 -0
- package/backend-project/package.json +2 -1
- package/backend-project/server.js +7 -2
- package/frontend-project/package-lock.json +65 -20
- package/frontend-project/package.json +2 -2
- package/frontend-project/src/App.jsx +36 -0
- package/frontend-project/src/Component/Product.jsx +388 -0
- package/frontend-project/src/Component/Report.jsx +162 -0
- package/frontend-project/src/Component/Transfer.jsx +442 -0
- package/frontend-project/src/Component/Warehouse.jsx +238 -0
- package/frontend-project/src/Layout/Pannel.jsx +40 -75
- package/frontend-project/src/index.css +1 -0
- package/frontend-project/src/main.jsx +12 -0
- package/frontend-project/vite.config.js +2 -1
- package/package.json +2 -2
- package/frontend-project/src/App.css +0 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
FaClosedCaptioning,
|
|
4
|
+
FaPlus,
|
|
5
|
+
FaTimes,
|
|
6
|
+
FaTimesCircle,
|
|
7
|
+
} from "react-icons/fa";
|
|
8
|
+
import { MdDelete, MdEdit } from "react-icons/md";
|
|
9
|
+
import axios from "axios";
|
|
10
|
+
import toast from "react-hot-toast";
|
|
11
|
+
|
|
12
|
+
const Transfer = () => {
|
|
13
|
+
const port = 3400;
|
|
14
|
+
// Api to use here replace yours
|
|
15
|
+
const API_URL = `http://localhost:${port}/api/warehouse`;
|
|
16
|
+
const API_URL_L = `http://localhost:${port}/api/product`;
|
|
17
|
+
const API_URL_T = `http://localhost:${port}/api/transfer`;
|
|
18
|
+
// End
|
|
19
|
+
// set Data in State From backend
|
|
20
|
+
const [data, setData] = useState([]);
|
|
21
|
+
const [transferData, setTransferData] = useState([]);
|
|
22
|
+
const [landData, setLandData] = useState([]);
|
|
23
|
+
// End
|
|
24
|
+
// Model Show And Needed here
|
|
25
|
+
const [model, setModel] = useState(false);
|
|
26
|
+
const [edit, setEdit] = useState(null);
|
|
27
|
+
// End
|
|
28
|
+
// About Form
|
|
29
|
+
const [formData, setFormData] = useState({
|
|
30
|
+
warehouse_id: "",
|
|
31
|
+
product_id: "",
|
|
32
|
+
transactionDate: "",
|
|
33
|
+
quantityMoved: "",
|
|
34
|
+
transactionType:""
|
|
35
|
+
});
|
|
36
|
+
const handleFormData = async (e) => {
|
|
37
|
+
const { name, value } = e.target;
|
|
38
|
+
setFormData({ ...formData, [name]: value });
|
|
39
|
+
};
|
|
40
|
+
// End
|
|
41
|
+
// About Tables
|
|
42
|
+
const fecthDataL = async () => {
|
|
43
|
+
try {
|
|
44
|
+
const res = await axios.get(`${API_URL_L}/get`);
|
|
45
|
+
if (!res.data.success) {
|
|
46
|
+
return toast.error(res.data.message);
|
|
47
|
+
}
|
|
48
|
+
setLandData(res.data.product);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
alert(error.message);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
const fecthData = async () => {
|
|
56
|
+
try {
|
|
57
|
+
const res = await axios.get(`${API_URL}/get`);
|
|
58
|
+
if (!res.data.success) {
|
|
59
|
+
return toast.error(res.data.message);
|
|
60
|
+
}
|
|
61
|
+
setData(res.data.warehouse);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
alert(error.message);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const fecthDataT = async () => {
|
|
68
|
+
try {
|
|
69
|
+
const res = await axios.get(`${API_URL_T}/get`);
|
|
70
|
+
if (!res.data.success) {
|
|
71
|
+
return toast.error(res.data.message);
|
|
72
|
+
}
|
|
73
|
+
setTransferData(res.data.transfer);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
toast.error(error.message);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
// End
|
|
79
|
+
// About Form
|
|
80
|
+
const handleSubmit = async (e) => {
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
console.log(formData)
|
|
83
|
+
try {
|
|
84
|
+
if (
|
|
85
|
+
!formData.warehouse_id ||
|
|
86
|
+
!formData.product_id ||
|
|
87
|
+
!formData.quantityMoved ||
|
|
88
|
+
!formData.transactionDate ||
|
|
89
|
+
!formData.transactionType
|
|
90
|
+
) {
|
|
91
|
+
return toast.error("You Must Fill all Field");
|
|
92
|
+
}
|
|
93
|
+
// About Edit/Update
|
|
94
|
+
if (edit) {
|
|
95
|
+
const res = await axios.put(`${API_URL_T}/update/${edit}`, formData);
|
|
96
|
+
if (!res) {
|
|
97
|
+
return toast.error(res.data.message);
|
|
98
|
+
}
|
|
99
|
+
setModel(false)
|
|
100
|
+
toast.success(res.data.message);
|
|
101
|
+
setFormData({
|
|
102
|
+
warehouse_id: "",
|
|
103
|
+
product_id: "",
|
|
104
|
+
transactionDate: "",
|
|
105
|
+
quantityMoved: "",
|
|
106
|
+
transactionType: "",
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// End
|
|
111
|
+
|
|
112
|
+
const res = await axios.post(`${API_URL_T}/add`, formData);
|
|
113
|
+
if (!res.data.success) {
|
|
114
|
+
return toast.error(res.data.message);
|
|
115
|
+
}
|
|
116
|
+
toast.success(res.data.message);
|
|
117
|
+
setFormData({
|
|
118
|
+
warehouse_id: "",
|
|
119
|
+
product_id: "",
|
|
120
|
+
transactionDate: "",
|
|
121
|
+
quantityMoved: "",
|
|
122
|
+
transactionType: "",
|
|
123
|
+
});
|
|
124
|
+
} catch (error) {
|
|
125
|
+
toast.error(error.message);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// End
|
|
130
|
+
|
|
131
|
+
// About Table
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
fecthDataT();
|
|
136
|
+
fecthData();
|
|
137
|
+
fecthDataL();
|
|
138
|
+
}, [formData]);
|
|
139
|
+
// End
|
|
140
|
+
|
|
141
|
+
// About Edit / Update
|
|
142
|
+
|
|
143
|
+
const handleUpdate = (o) => {
|
|
144
|
+
setModel(true);
|
|
145
|
+
setFormData({
|
|
146
|
+
warehouse_id: o.warehouse_id?._id,
|
|
147
|
+
product_id: o.product_id?._id,
|
|
148
|
+
transactionDate: o.transactionDate,
|
|
149
|
+
quantityMoved: o.quantityMoved,
|
|
150
|
+
transactionType: o.transactionType,
|
|
151
|
+
});
|
|
152
|
+
setEdit(o._id);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// End
|
|
156
|
+
|
|
157
|
+
// About Delete
|
|
158
|
+
const handleRemove = async(id)=>{
|
|
159
|
+
try {
|
|
160
|
+
if(!confirm("Are You Sure You want To Delete Tranfer Record")) return;
|
|
161
|
+
const res =await axios.delete(`${API_URL_T}/delete/${id}`)
|
|
162
|
+
if(!res.data.success){
|
|
163
|
+
return toast.error(res.data.message)
|
|
164
|
+
}
|
|
165
|
+
fecthDataT()
|
|
166
|
+
return toast.success(res.data.message)
|
|
167
|
+
} catch (error) {
|
|
168
|
+
toast.error(error.message)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// End
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
const filterData = landData.filter((p)=>p.warehouse_id?._id === formData.warehouse_id)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// End
|
|
178
|
+
return (
|
|
179
|
+
<div className="p-1 flex flex-col gap-2 w-full ">
|
|
180
|
+
<div className="bg-white/50 rounded-md px-4 py-2 flex justify-between items-center">
|
|
181
|
+
<h1 className="md:text-xl font-bold text-indigo-500 text-md">
|
|
182
|
+
Transaction
|
|
183
|
+
</h1>
|
|
184
|
+
<div
|
|
185
|
+
className="p-2 text-white/90 rounded-lg bg-green-500 flex items-center gap-2 cursor-pointer"
|
|
186
|
+
onClick={() => {
|
|
187
|
+
setModel(true);
|
|
188
|
+
setEdit(null)
|
|
189
|
+
setFormData({
|
|
190
|
+
warehouse_id: "",
|
|
191
|
+
product_id: "",
|
|
192
|
+
transactionDate: "",
|
|
193
|
+
quantityMoved: "",
|
|
194
|
+
transactionType: "",
|
|
195
|
+
});
|
|
196
|
+
}}
|
|
197
|
+
>
|
|
198
|
+
<FaPlus /> <p className="md:block hidden">Declare Transfer</p>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<div className="bg-white/50 p-4 rounded-lg block md:hidden">
|
|
202
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
|
|
203
|
+
{transferData.map((o, i) => (
|
|
204
|
+
<div className="w-full bg-white p-2 rounded-lg" key={i}>
|
|
205
|
+
<h1 className="text-gray-500">{i + 1}</h1>
|
|
206
|
+
<div className="flex justify-between">
|
|
207
|
+
<h1 className="font-semibold text-indigo-500">
|
|
208
|
+
Warehouse Name:
|
|
209
|
+
</h1>
|
|
210
|
+
<p className="text-gray-800">
|
|
211
|
+
<b>{o.warehouse_id?.warehouseName}</b>
|
|
212
|
+
</p>
|
|
213
|
+
</div>
|
|
214
|
+
<div className="flex justify-between">
|
|
215
|
+
<h1 className="font-semibold text-indigo-500">Product Name:</h1>
|
|
216
|
+
<p className="text-gray-800 capitalize">
|
|
217
|
+
{o.product_id?.productName}
|
|
218
|
+
</p>
|
|
219
|
+
</div>
|
|
220
|
+
<div className="flex justify-between">
|
|
221
|
+
<h1 className="font-semibold text-indigo-500 capitalize">
|
|
222
|
+
Transaction Date:
|
|
223
|
+
</h1>
|
|
224
|
+
<p className="text-gray-800">
|
|
225
|
+
{new Date(o.transactionDate).toLocaleString()}
|
|
226
|
+
</p>
|
|
227
|
+
</div>
|
|
228
|
+
<div className="flex justify-between">
|
|
229
|
+
<h1 className="font-semibold text-indigo-500 capitalize">
|
|
230
|
+
Quantity Moved:
|
|
231
|
+
</h1>
|
|
232
|
+
<p className="text-gray-800 capitalize">{o.quantityMoved}</p>
|
|
233
|
+
</div>
|
|
234
|
+
<div className="flex justify-between">
|
|
235
|
+
<h1 className="font-semibold text-indigo-500">
|
|
236
|
+
Transaction Type:
|
|
237
|
+
</h1>
|
|
238
|
+
<p className="text-gray-800 capitalize">{o.transactionType}</p>
|
|
239
|
+
</div>
|
|
240
|
+
<div className="flex gap-2 items-center justify-evenly py-2">
|
|
241
|
+
<button
|
|
242
|
+
onClick={() => handleUpdate(o)}
|
|
243
|
+
className="w-50 py-1 bg-blue-500 rounded-lg text-md font-semibold text-white/90"
|
|
244
|
+
>
|
|
245
|
+
Update
|
|
246
|
+
</button>
|
|
247
|
+
<button
|
|
248
|
+
onClick={() => handleRemove(o._id)}
|
|
249
|
+
className="w-50 py-1 bg-red-500 rounded-lg text-white/90 font-semibold text-md"
|
|
250
|
+
>
|
|
251
|
+
Delete
|
|
252
|
+
</button>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
))}
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
<div className="bg-white/50 p-4 md:flex flex-col gap-2 rounded-lg hidden ">
|
|
259
|
+
<div className="bg-white p-2 rounded-lg">
|
|
260
|
+
<table className="w-full">
|
|
261
|
+
<thead>
|
|
262
|
+
<tr className="text-sm text-indigo-500">
|
|
263
|
+
<th>No</th>
|
|
264
|
+
<th>Warehouse Name</th>
|
|
265
|
+
<th>Product Name</th>
|
|
266
|
+
<th>Transaction Date</th>
|
|
267
|
+
<th>Quantity Moved</th>
|
|
268
|
+
<th>Transaction Type</th>
|
|
269
|
+
<th>Action</th>
|
|
270
|
+
</tr>
|
|
271
|
+
</thead>
|
|
272
|
+
<tbody>
|
|
273
|
+
{transferData.map((o, i) => (
|
|
274
|
+
<tr key={i} className="text-sm text-center capitalize">
|
|
275
|
+
<td className="px-2 p-2">{i + 1}</td>
|
|
276
|
+
<td className="px-2">{o.warehouse_id?.warehouseName}</td>
|
|
277
|
+
|
|
278
|
+
<td className="px-2 capitalize">
|
|
279
|
+
{o.product_id?.productName}
|
|
280
|
+
</td>
|
|
281
|
+
<td className="px-2">
|
|
282
|
+
{new Date(o.transactionDate).toLocaleString()}
|
|
283
|
+
</td>
|
|
284
|
+
<td className="px-2 capitalize">{o.quantityMoved}</td>
|
|
285
|
+
<td className="px-2 capitalize">{o.transactionType}</td>
|
|
286
|
+
<td>
|
|
287
|
+
<div className="flex gap-2 items-center justify-center py-2 text-lg">
|
|
288
|
+
<MdEdit
|
|
289
|
+
onClick={() => handleUpdate(o)}
|
|
290
|
+
className="hover:bg-gray-200 text-2xl p-1 rounded-full cursor-pointer text-blue-500"
|
|
291
|
+
/>
|
|
292
|
+
<MdDelete
|
|
293
|
+
onClick={() => handleRemove(o._id)}
|
|
294
|
+
className="hover:bg-gray-200 text-2xl p-1 rounded-full cursor-pointer text-red-500"
|
|
295
|
+
/>
|
|
296
|
+
</div>
|
|
297
|
+
</td>
|
|
298
|
+
</tr>
|
|
299
|
+
))}
|
|
300
|
+
</tbody>
|
|
301
|
+
</table>
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
{model && (
|
|
305
|
+
<div
|
|
306
|
+
className="fixed flex items-center justify-center bg-indigo-500/35 w-full inset-0"
|
|
307
|
+
onClick={() => {
|
|
308
|
+
setModel(false);
|
|
309
|
+
}}
|
|
310
|
+
>
|
|
311
|
+
<div
|
|
312
|
+
className="bg-white/95 w-120 p-4 rounded-2xl"
|
|
313
|
+
onClick={(e) => {
|
|
314
|
+
e.stopPropagation();
|
|
315
|
+
}}
|
|
316
|
+
>
|
|
317
|
+
<form
|
|
318
|
+
onSubmit={handleSubmit}
|
|
319
|
+
className="flex
|
|
320
|
+
flex-col gap-4 w-full"
|
|
321
|
+
>
|
|
322
|
+
<div className="flex items-center justify-between p-4">
|
|
323
|
+
<h1 className="text-xl font-semibold text-green-500">
|
|
324
|
+
Transfer Application Form
|
|
325
|
+
</h1>
|
|
326
|
+
<div
|
|
327
|
+
className=""
|
|
328
|
+
onClick={() => {
|
|
329
|
+
setModel(false);
|
|
330
|
+
}}
|
|
331
|
+
>
|
|
332
|
+
<FaTimesCircle className="text-3xl text-indigo-500" />
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
|
|
336
|
+
<div className="flex flex-col gap-1">
|
|
337
|
+
<label
|
|
338
|
+
htmlFor="parcelId"
|
|
339
|
+
className="font-semibold text-md text-blue-400"
|
|
340
|
+
>
|
|
341
|
+
Warehouse Name
|
|
342
|
+
</label>
|
|
343
|
+
<select
|
|
344
|
+
value={formData.warehouse_id}
|
|
345
|
+
onChange={handleFormData}
|
|
346
|
+
name="warehouse_id"
|
|
347
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
348
|
+
>
|
|
349
|
+
<option value="">Select Warehouse</option>
|
|
350
|
+
{data.map((o, i) => (
|
|
351
|
+
<option key={i} value={o._id}>
|
|
352
|
+
{o.warehouseName}
|
|
353
|
+
</option>
|
|
354
|
+
))}
|
|
355
|
+
</select>
|
|
356
|
+
</div>
|
|
357
|
+
<div className="flex flex-col gap-1">
|
|
358
|
+
<label
|
|
359
|
+
htmlFor="parcelId"
|
|
360
|
+
className="font-semibold text-md text-blue-400"
|
|
361
|
+
>
|
|
362
|
+
Product Name
|
|
363
|
+
</label>
|
|
364
|
+
<select
|
|
365
|
+
value={formData.product_id}
|
|
366
|
+
onChange={handleFormData}
|
|
367
|
+
name="product_id"
|
|
368
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
369
|
+
>
|
|
370
|
+
<option value="">Select Product</option>
|
|
371
|
+
{filterData.map((o, i) => (
|
|
372
|
+
<option key={i} value={o._id}>
|
|
373
|
+
{o.productName}
|
|
374
|
+
</option>
|
|
375
|
+
))}
|
|
376
|
+
</select>
|
|
377
|
+
</div>
|
|
378
|
+
<div className="flex flex-col gap-1">
|
|
379
|
+
<label
|
|
380
|
+
htmlFor="transfer_date"
|
|
381
|
+
className="font-semibold text-md text-blue-400"
|
|
382
|
+
>
|
|
383
|
+
Quantity Moved
|
|
384
|
+
</label>
|
|
385
|
+
<input
|
|
386
|
+
value={formData.quantityMoved}
|
|
387
|
+
onChange={handleFormData}
|
|
388
|
+
type="number"
|
|
389
|
+
name="quantityMoved"
|
|
390
|
+
placeholder="quantityMoved"
|
|
391
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
392
|
+
/>
|
|
393
|
+
</div>
|
|
394
|
+
|
|
395
|
+
<div className="flex flex-col gap-1">
|
|
396
|
+
<label
|
|
397
|
+
htmlFor="transfer_date"
|
|
398
|
+
className="font-semibold text-md text-blue-400"
|
|
399
|
+
>
|
|
400
|
+
Transaction Date
|
|
401
|
+
</label>
|
|
402
|
+
<input
|
|
403
|
+
value={formData.transactionDate}
|
|
404
|
+
onChange={handleFormData}
|
|
405
|
+
type="datetime-local"
|
|
406
|
+
name="transactionDate"
|
|
407
|
+
placeholder="KtransactionDate"
|
|
408
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
409
|
+
/>
|
|
410
|
+
</div>
|
|
411
|
+
<div className="flex flex-col gap-1">
|
|
412
|
+
<label
|
|
413
|
+
htmlFor="transfer_date"
|
|
414
|
+
className="font-semibold text-md text-blue-400"
|
|
415
|
+
>
|
|
416
|
+
Transaction Type
|
|
417
|
+
</label>
|
|
418
|
+
<input
|
|
419
|
+
value={formData.transactionType}
|
|
420
|
+
onChange={handleFormData}
|
|
421
|
+
type="text"
|
|
422
|
+
name="transactionType"
|
|
423
|
+
placeholder="transactionType"
|
|
424
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
425
|
+
/>
|
|
426
|
+
</div>
|
|
427
|
+
</div>
|
|
428
|
+
<button
|
|
429
|
+
type="submit"
|
|
430
|
+
className="bg-green-500 p-2 text-white/90 font-semibold rounded-md hover:rounded-2xl"
|
|
431
|
+
>
|
|
432
|
+
Register Transfer
|
|
433
|
+
</button>
|
|
434
|
+
</form>
|
|
435
|
+
</div>
|
|
436
|
+
</div>
|
|
437
|
+
)}
|
|
438
|
+
</div>
|
|
439
|
+
);
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
export default Transfer;
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
FaClosedCaptioning,
|
|
4
|
+
FaPlus,
|
|
5
|
+
FaTimes,
|
|
6
|
+
FaTimesCircle,
|
|
7
|
+
} from "react-icons/fa";
|
|
8
|
+
import axios from "axios";
|
|
9
|
+
import toast from "react-hot-toast";
|
|
10
|
+
|
|
11
|
+
const Warehouse = () => {
|
|
12
|
+
const port = 3400
|
|
13
|
+
const API_URL = `http://localhost:${port}/api/warehouse`;
|
|
14
|
+
const [data, setData] = useState([]);
|
|
15
|
+
const [model, setModel] = useState(false);
|
|
16
|
+
// About Form
|
|
17
|
+
const [formData, setFormData] = useState({
|
|
18
|
+
warehouseCode: "",
|
|
19
|
+
warehouseName: "",
|
|
20
|
+
warehouseLocation:""
|
|
21
|
+
});
|
|
22
|
+
// About Form
|
|
23
|
+
|
|
24
|
+
// About Table
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const fecthData = async () => {
|
|
28
|
+
try {
|
|
29
|
+
const res = await axios.get(`${API_URL}/get`);
|
|
30
|
+
if (!res.data.success) {
|
|
31
|
+
return toast.error(res.data.message);
|
|
32
|
+
}
|
|
33
|
+
setData(res.data.warehouse);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
alert(error.message);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
fecthData();
|
|
39
|
+
}, [formData]);
|
|
40
|
+
|
|
41
|
+
// About Table
|
|
42
|
+
|
|
43
|
+
// About Form
|
|
44
|
+
|
|
45
|
+
const handleFormData = async (e) => {
|
|
46
|
+
const { name, value } = e.target;
|
|
47
|
+
setFormData({ ...formData, [name]: value });
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handleSubmit = async (e) => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
try {
|
|
53
|
+
if (
|
|
54
|
+
!formData.warehouseCode ||
|
|
55
|
+
!formData.warehouseName ||
|
|
56
|
+
!formData.warehouseLocation
|
|
57
|
+
|
|
58
|
+
) {
|
|
59
|
+
return toast.error("You Must Fill all Field");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const res = await axios.post(`${API_URL}/add`, formData);
|
|
63
|
+
if (!res.data.success) {
|
|
64
|
+
return toast.error(res.data.message);
|
|
65
|
+
}
|
|
66
|
+
toast.success(res.data.message);
|
|
67
|
+
setFormData({
|
|
68
|
+
warehouseCode: "",
|
|
69
|
+
warehouseName: "",
|
|
70
|
+
warehouseLocation: "",
|
|
71
|
+
});
|
|
72
|
+
} catch (error) {
|
|
73
|
+
toast.error(error.message);
|
|
74
|
+
}
|
|
75
|
+
// About Form
|
|
76
|
+
};
|
|
77
|
+
return (
|
|
78
|
+
<div className="p-1 flex flex-col gap-2 w-full ">
|
|
79
|
+
<div className="bg-white/50 rounded-md px-4 py-2 flex justify-between items-center">
|
|
80
|
+
<h1 className="md:text-xl font-bold text-indigo-500 text-md">
|
|
81
|
+
Warehouse
|
|
82
|
+
</h1>
|
|
83
|
+
<div
|
|
84
|
+
className="p-2 text-white/90 rounded-lg bg-green-500 flex items-center gap-2"
|
|
85
|
+
onClick={() => {
|
|
86
|
+
setModel(true);
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<FaPlus /> <p className="md:block hidden">Add warehouse</p>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
<div className="bg-white/50 p-4 rounded-lg block md:hidden">
|
|
93
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
|
|
94
|
+
{data.map((o, i) => (
|
|
95
|
+
<div className="w-full bg-white p-2 rounded-lg" key={i}>
|
|
96
|
+
<h1 className="text-gray-500">{i + 1}</h1>
|
|
97
|
+
<div className="flex justify-between">
|
|
98
|
+
<h1 className="font-semibold text-indigo-500">
|
|
99
|
+
Warehouse Code:
|
|
100
|
+
</h1>
|
|
101
|
+
<p className="text-gray-800">{o.warehouseCode}</p>
|
|
102
|
+
</div>
|
|
103
|
+
<div className="flex justify-between">
|
|
104
|
+
<h1 className="font-semibold text-indigo-500">
|
|
105
|
+
Warehouse Name:
|
|
106
|
+
</h1>
|
|
107
|
+
<p className="text-gray-800">{o.warehouseName}</p>
|
|
108
|
+
</div>
|
|
109
|
+
<div className="flex justify-between">
|
|
110
|
+
<h1 className="font-semibold text-indigo-500">
|
|
111
|
+
Warehouse Location:
|
|
112
|
+
</h1>
|
|
113
|
+
<p className="text-gray-800">{o.warehouseLocation}</p>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
))}
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
<div className="bg-white/50 p-4 md:flex flex-col gap-2 rounded-lg hidden ">
|
|
120
|
+
<div className="bg-white p-2 rounded-lg">
|
|
121
|
+
<table className="w-full">
|
|
122
|
+
<thead>
|
|
123
|
+
<tr className="text-sm text-indigo-500">
|
|
124
|
+
<th>No</th>
|
|
125
|
+
<th>Warehouse Code</th>
|
|
126
|
+
<th>Warehouse Name</th>
|
|
127
|
+
<th>Warehouse Location</th>
|
|
128
|
+
</tr>
|
|
129
|
+
</thead>
|
|
130
|
+
<tbody>
|
|
131
|
+
{data.map((o, i) => (
|
|
132
|
+
<tr key={i} className="text-sm text-center">
|
|
133
|
+
<td className="px-2 p-2">{i + 1}</td>
|
|
134
|
+
<td className="px-2">{o.warehouseCode} </td>
|
|
135
|
+
<td className="px-2">{o.warehouseName}</td>
|
|
136
|
+
<td className="px-2">{o.warehouseLocation}</td>
|
|
137
|
+
</tr>
|
|
138
|
+
))}
|
|
139
|
+
</tbody>
|
|
140
|
+
</table>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
{model && (
|
|
144
|
+
<div
|
|
145
|
+
className="fixed flex items-center justify-center bg-indigo-500/35 w-full inset-0"
|
|
146
|
+
onClick={() => {
|
|
147
|
+
setModel(false);
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
<div
|
|
151
|
+
className="bg-white/95 w-120 p-4 rounded-2xl"
|
|
152
|
+
onClick={(e) => {
|
|
153
|
+
e.stopPropagation();
|
|
154
|
+
}}
|
|
155
|
+
>
|
|
156
|
+
<form
|
|
157
|
+
onSubmit={handleSubmit}
|
|
158
|
+
className="flex
|
|
159
|
+
flex-col gap-4 w-full"
|
|
160
|
+
>
|
|
161
|
+
<div className="flex items-center justify-between p-4">
|
|
162
|
+
<h1 className="text-xl font-semibold text-green-500">
|
|
163
|
+
Add Warehouse
|
|
164
|
+
</h1>
|
|
165
|
+
<div
|
|
166
|
+
className=""
|
|
167
|
+
onClick={() => {
|
|
168
|
+
setModel(false);
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
<FaTimesCircle className="text-3xl text-indigo-500" />
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
|
|
175
|
+
<div className="flex flex-col gap-1">
|
|
176
|
+
<label
|
|
177
|
+
htmlFor="nationalId"
|
|
178
|
+
className="font-semibold text-md text-blue-400"
|
|
179
|
+
>
|
|
180
|
+
Warehouse Code
|
|
181
|
+
</label>
|
|
182
|
+
<input
|
|
183
|
+
value={formData.warehouseCode}
|
|
184
|
+
name="warehouseCode"
|
|
185
|
+
onChange={handleFormData}
|
|
186
|
+
type="text"
|
|
187
|
+
placeholder="warehouseCode"
|
|
188
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
189
|
+
/>
|
|
190
|
+
</div>
|
|
191
|
+
<div className="flex flex-col gap-1">
|
|
192
|
+
<label
|
|
193
|
+
htmlFor="first_name"
|
|
194
|
+
className="font-semibold text-md text-blue-400"
|
|
195
|
+
>
|
|
196
|
+
Warehouse Name
|
|
197
|
+
</label>
|
|
198
|
+
<input
|
|
199
|
+
value={formData.warehouseName}
|
|
200
|
+
onChange={handleFormData}
|
|
201
|
+
type="text"
|
|
202
|
+
name="warehouseName"
|
|
203
|
+
placeholder="warehouseName"
|
|
204
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
205
|
+
/>
|
|
206
|
+
</div>
|
|
207
|
+
<div className="flex flex-col gap-1">
|
|
208
|
+
<label
|
|
209
|
+
htmlFor="last_name"
|
|
210
|
+
className="font-semibold text-md text-blue-400"
|
|
211
|
+
>
|
|
212
|
+
Warehouse Location
|
|
213
|
+
</label>
|
|
214
|
+
<input
|
|
215
|
+
value={formData.warehouseLocation}
|
|
216
|
+
onChange={handleFormData}
|
|
217
|
+
type="text"
|
|
218
|
+
name="warehouseLocation"
|
|
219
|
+
placeholder="warehouseLocation"
|
|
220
|
+
className="px-3 py-1 rounded-md border border-blue-500 focus:outline-blue-300"
|
|
221
|
+
/>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
<button
|
|
225
|
+
type="submit"
|
|
226
|
+
className="bg-green-500 p-2 text-white/90 font-semibold rounded-md hover:rounded-2xl"
|
|
227
|
+
>
|
|
228
|
+
Register Warehouse
|
|
229
|
+
</button>
|
|
230
|
+
</form>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
)}
|
|
234
|
+
</div>
|
|
235
|
+
);
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export default Warehouse;
|