Creating UI for Supplier in Inventory.
This commit is contained in:
parent
76abfb5fd3
commit
aff9a14af1
323
src/components/InventoryManagement/AddProductModal.jsx
Normal file
323
src/components/InventoryManagement/AddProductModal.jsx
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import GlobalModel from "../../components/common/GlobalModel";
|
||||||
|
import Label from "../common/Label";
|
||||||
|
|
||||||
|
// A simple Stepper component for visual guidance
|
||||||
|
const Stepper = ({ steps, activeStep }) => (
|
||||||
|
<div className="d-flex justify-content-between align-items-center mb-5">
|
||||||
|
{steps.map((step, index) => (
|
||||||
|
<React.Fragment key={step.key}>
|
||||||
|
<div className={`text-center ${index <= activeStep ? 'text-primary' : 'text-muted'}`}>
|
||||||
|
<div
|
||||||
|
className={`rounded-circle d-inline-flex align-items-center justify-content-center border p-2 mb-2 ${index === activeStep
|
||||||
|
? 'bg-primary text-white border-primary'
|
||||||
|
: index < activeStep
|
||||||
|
? 'bg-success text-white border-success'
|
||||||
|
: 'bg-light text-muted border-secondary'
|
||||||
|
}`}
|
||||||
|
style={{ width: '30px', height: '30px', fontSize: '14px' }}
|
||||||
|
>
|
||||||
|
{index < activeStep ? '✓' : index + 1}
|
||||||
|
</div>
|
||||||
|
<small className="d-block fw-bold">{step.label}</small>
|
||||||
|
</div>
|
||||||
|
{index < steps.length - 1 && (
|
||||||
|
<div
|
||||||
|
className={`flex-grow-1 mx-2 border-top ${index < activeStep ? 'border-primary' : 'border-secondary'}`}
|
||||||
|
style={{ height: '0', marginTop: '-20px' }}
|
||||||
|
></div>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const AddProductModal = ({ isOpen, onClose }) => { // Renamed from AddProductModal
|
||||||
|
const steps = [
|
||||||
|
{ key: "supplierInfo", label: "Supplier Info" },
|
||||||
|
{ key: "bank", label: "Bank" },
|
||||||
|
{ key: "address", label: "Address" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// Use index for active step to make navigation easier
|
||||||
|
const [activeStepIndex, setActiveStepIndex] = useState(0);
|
||||||
|
const activeStepKey = steps[activeStepIndex].key;
|
||||||
|
|
||||||
|
if (!isOpen) return null;
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
if (activeStepIndex < steps.length - 1) {
|
||||||
|
setActiveStepIndex(activeStepIndex + 1);
|
||||||
|
} else {
|
||||||
|
// Last step, submit the form
|
||||||
|
handleSubmit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
if (activeStepIndex > 0) {
|
||||||
|
setActiveStepIndex(activeStepIndex - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
// Add your form submission logic here
|
||||||
|
console.log("Form submitted");
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GlobalModel isOpen size="xl" closeModal={onClose}>
|
||||||
|
<div className="p-4">
|
||||||
|
<h5 className="mb-4">Add New Supplier</h5>
|
||||||
|
|
||||||
|
{/* ================= Stepper Navigation ================= */}
|
||||||
|
<Stepper steps={steps} activeStep={activeStepIndex} />
|
||||||
|
|
||||||
|
{/* ================= Step Content ================= */}
|
||||||
|
<form onSubmit={(e) => e.preventDefault()}>
|
||||||
|
{/* ---------- Step 1: Supplier Info ---------- */}
|
||||||
|
{activeStepKey === "supplierInfo" && (
|
||||||
|
<div className="text-start">
|
||||||
|
<h6 className="fw-bold text-primary mb-3">Supplier Information</h6>
|
||||||
|
<div className="row g-3">
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Supplier Name</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter supplier name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Supplier Status</Label>
|
||||||
|
<select className="form-select form-select-sm">
|
||||||
|
<option value="">Select Status</option>
|
||||||
|
<option>Active</option>
|
||||||
|
<option>In-active</option>
|
||||||
|
<option>Pending Approval</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Supplier Group</Label>
|
||||||
|
<select className="form-select form-select-sm">
|
||||||
|
<option value="">Select Group</option>
|
||||||
|
<option>Domestic</option>
|
||||||
|
<option>International</option>
|
||||||
|
<option>Inter-Company</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Supplier Category</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter category"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>Website URL</Label>
|
||||||
|
<input
|
||||||
|
type="url"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter website URL"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ---------- Step 2: Bank Tab ---------- */}
|
||||||
|
{activeStepKey === "bank" && (
|
||||||
|
<div className="text-start">
|
||||||
|
<h6 className="fw-bold text-primary mb-3">Bank Details</h6>
|
||||||
|
<div className="row g-3">
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Bank Name</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter bank name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Bank Account</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter account number"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>IBAN / IFSC</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter IBAN or IFSC"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>SWIFT / BIC Code</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter SWIFT or BIC"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>Payment Terms</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter payment terms"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ---------- Step 3: Address Tab ---------- */}
|
||||||
|
{activeStepKey === "address" && (
|
||||||
|
<div className="text-start">
|
||||||
|
<h6 className="fw-bold text-primary mb-3">Address Details</h6>
|
||||||
|
<div className="row g-3">
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Address Type</Label>
|
||||||
|
<select className="form-select form-select-sm">
|
||||||
|
<option value="">Select Type</option>
|
||||||
|
<option>Billing</option>
|
||||||
|
<option>Shipping</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Street</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter street"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>City</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter city"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Postal Code</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter postal code"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Country</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter country"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Contact Name</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter contact name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>Contact Email</Label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter email"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>Contact Phone</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter phone"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>Office Phone</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter office phone"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>GSTIN</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter Tax ID or EIN"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label>PAN Number</Label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-select-sm"
|
||||||
|
placeholder="Enter PAN"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label required>Status</Label>
|
||||||
|
<select className="form-select form-select-sm">
|
||||||
|
<option value="">Select Status</option>
|
||||||
|
<option>Active</option>
|
||||||
|
<option>In-active</option>
|
||||||
|
<option>Blocked</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ---------- Buttons ---------- */}
|
||||||
|
<div className="d-flex justify-content-between mt-5 border-top pt-3">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-label-secondary btn-sm"
|
||||||
|
onClick={activeStepIndex > 0 ? handleBack : onClose}
|
||||||
|
>
|
||||||
|
{activeStepIndex > 0 ? '← Back' : 'Cancel'}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{activeStepIndex < steps.length - 1 ? (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm"
|
||||||
|
onClick={handleNext}
|
||||||
|
>
|
||||||
|
Next →
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</GlobalModel>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AddProductModal;
|
||||||
57
src/pages/InventoryManagement/ProductPage.jsx
Normal file
57
src/pages/InventoryManagement/ProductPage.jsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
|
import AddProductModal from "../../components/InventoryManagement/AddProductModal";
|
||||||
|
|
||||||
|
const ProductPage = () => {
|
||||||
|
const [isAddInventoryOpen, setIsAddInventoryOpen] = useState(false);
|
||||||
|
const [viewInventory, setViewInventory] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid">
|
||||||
|
{/* Breadcrumb */}
|
||||||
|
<Breadcrumb data={[{ label: "Home", link: "/" }, { label: "Inventory" }]} />
|
||||||
|
|
||||||
|
{/* Top Bar */}
|
||||||
|
<div className="card my-3 px-sm-4 px-0">
|
||||||
|
<div className="card-body py-2 px-3">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col-6">
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
className="form-control form-control-sm w-auto"
|
||||||
|
placeholder="Search Inventory"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-6 text-end mt-2 mt-sm-0">
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-primary"
|
||||||
|
type="button"
|
||||||
|
onClick={() => setIsAddInventoryOpen(true)}
|
||||||
|
>
|
||||||
|
<i className="bx bx-plus-circle me-2"></i>
|
||||||
|
<span className="d-none d-md-inline-block">Add New Inventory</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Inventory List Placeholder */}
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body text-center text-muted py-5">
|
||||||
|
<p>No inventory data available yet.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Add Inventory Modal */}
|
||||||
|
<AddProductModal
|
||||||
|
isOpen={isAddInventoryOpen}
|
||||||
|
onClose={() => setIsAddInventoryOpen(false)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProductPage;
|
||||||
@ -54,6 +54,7 @@ import ProjectPage from "../pages/project/ProjectPage";
|
|||||||
import { ComingSoonPage } from "../pages/Misc/ComingSoonPage";
|
import { ComingSoonPage } from "../pages/Misc/ComingSoonPage";
|
||||||
import ImageGalleryPage from "../pages/Gallary/ImageGallaryPage";
|
import ImageGalleryPage from "../pages/Gallary/ImageGallaryPage";
|
||||||
import CollectionPage from "../pages/collections/CollectionPage";
|
import CollectionPage from "../pages/collections/CollectionPage";
|
||||||
|
import ProductPage from "../pages/InventoryManagement/ProductPage";
|
||||||
const router = createBrowserRouter(
|
const router = createBrowserRouter(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -89,7 +90,7 @@ const router = createBrowserRouter(
|
|||||||
// { path: "/employee/manage", element: <ManageEmp /> },
|
// { path: "/employee/manage", element: <ManageEmp /> },
|
||||||
// {path: "/employee/manage/:employeeId", element: <ManageEmp />},
|
// {path: "/employee/manage/:employeeId", element: <ManageEmp />},
|
||||||
{ path: "/directory", element: <DirectoryPage /> },
|
{ path: "/directory", element: <DirectoryPage /> },
|
||||||
{ path: "/inventory", element: <Inventory /> },
|
{ path: "/supplier", element: <ProductPage /> },
|
||||||
{ path: "/activities/attendance", element: <AttendancePage /> },
|
{ path: "/activities/attendance", element: <AttendancePage /> },
|
||||||
{ path: "/activities/records/:projectId?", element: <DailyProgrssReport /> },
|
{ path: "/activities/records/:projectId?", element: <DailyProgrssReport /> },
|
||||||
{ path: "/activities/task", element: <TaskPlannng /> },
|
{ path: "/activities/task", element: <TaskPlannng /> },
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user