feat(medical-store): add supplier creation and editing modal in Supplier Directory
This commit is contained in:
parent
758bc4c452
commit
101e0631a8
|
|
@ -1671,6 +1671,7 @@ $routes->group('api/v1', ['namespace' => 'App\Controllers\Api\v1'], static funct
|
|||
$routes->get('medical-store/sales/recent', 'MedicalStoreApi::recentSales');
|
||||
$routes->get('medical-store/suppliers', 'MedicalStoreApi::suppliers');
|
||||
$routes->post('medical-store/suppliers/save', 'MedicalStoreApi::saveSupplier');
|
||||
$routes->post('medical-store/suppliers/delete', 'MedicalStoreApi::deleteSupplier');
|
||||
$routes->post('medical-store/purchase/save', 'MedicalStoreApi::savePurchase');
|
||||
$routes->post('medical-store/purchase/payment', 'MedicalStoreApi::saveSupplierPayment');
|
||||
$routes->post('medical-store/transfer/request', 'MedicalStoreApi::requestTransfer');
|
||||
|
|
|
|||
|
|
@ -1641,6 +1641,25 @@ class MedicalStoreApi extends BaseController
|
|||
return $this->response->setJSON(['status' => 1, 'message' => 'Supplier saved successfully.', 'supplier_id' => $id]);
|
||||
}
|
||||
|
||||
public function deleteSupplier()
|
||||
{
|
||||
$json = $this->request->getJSON(true) ?: $this->request->getPost();
|
||||
$id = (int)($json['supplier_id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
return $this->response->setStatusCode(400)->setJSON(['status' => 0, 'message' => 'Invalid supplier ID.']);
|
||||
}
|
||||
|
||||
// Check if supplier is referenced in purchases
|
||||
$hasPurchases = $this->db->table('mst_purchases')->where('supplier_id', $id)->countAllResults();
|
||||
if ($hasPurchases > 0) {
|
||||
$this->db->table('mst_suppliers')->where('supplier_id', $id)->update(['is_active' => 0]);
|
||||
return $this->response->setJSON(['status' => 1, 'message' => 'Supplier deactivated (cannot delete because purchase bills are linked).']);
|
||||
}
|
||||
|
||||
$this->db->table('mst_suppliers')->where('supplier_id', $id)->delete();
|
||||
return $this->response->setJSON(['status' => 1, 'message' => 'Supplier removed successfully.']);
|
||||
}
|
||||
|
||||
public function savePurchase()
|
||||
{
|
||||
$json = $this->request->getJSON(true) ?: $this->request->getPost();
|
||||
|
|
|
|||
|
|
@ -4021,6 +4021,26 @@ function PurchaseView({ store, notify }) {
|
|||
const [invoiceNo, setInvoiceNo] = useState('');
|
||||
const [invoiceDate, setInvoiceDate] = useState(new Date().toISOString().split('T')[0]);
|
||||
|
||||
// Supplier Add/Edit Modal State
|
||||
const [showSupplierModal, setShowSupplierModal] = useState(false);
|
||||
const [supplierSearch, setSupplierSearch] = useState('');
|
||||
const [isSavingSupplier, setIsSavingSupplier] = useState(false);
|
||||
const [supplierForm, setSupplierForm] = useState({
|
||||
supplier_id: 0,
|
||||
supplier_name: '',
|
||||
contact_person: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
gstin: '',
|
||||
pan_no: '',
|
||||
dl_no_20b: '',
|
||||
dl_no_21b: '',
|
||||
state_code: '07',
|
||||
credit_days: 30,
|
||||
address: '',
|
||||
bank_details: ''
|
||||
});
|
||||
|
||||
const [rows, setRows] = useState([
|
||||
{ item_name: '', generic_name: '', batch_no: '', expiry_date: '', qty_packs: 1, free_qty_packs: 0, units_per_pack: 10, mrp: 0, ptr: 0, discount_pct: 0, gst_rate: 12 }
|
||||
]);
|
||||
|
|
@ -4039,6 +4059,107 @@ function PurchaseView({ store, notify }) {
|
|||
}
|
||||
};
|
||||
|
||||
const openAddSupplier = () => {
|
||||
setSupplierForm({
|
||||
supplier_id: 0,
|
||||
supplier_name: '',
|
||||
contact_person: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
gstin: '',
|
||||
pan_no: '',
|
||||
dl_no_20b: '',
|
||||
dl_no_21b: '',
|
||||
state_code: '07',
|
||||
credit_days: 30,
|
||||
address: '',
|
||||
bank_details: ''
|
||||
});
|
||||
setShowSupplierModal(true);
|
||||
};
|
||||
|
||||
const openEditSupplier = (s) => {
|
||||
setSupplierForm({
|
||||
supplier_id: s.supplier_id,
|
||||
supplier_name: s.supplier_name || '',
|
||||
contact_person: s.contact_person || '',
|
||||
phone: s.phone || '',
|
||||
email: s.email || '',
|
||||
gstin: s.gstin || '',
|
||||
pan_no: s.pan_no || '',
|
||||
dl_no_20b: s.dl_no_20b || '',
|
||||
dl_no_21b: s.dl_no_21b || '',
|
||||
state_code: s.state_code || '07',
|
||||
credit_days: s.credit_days || 30,
|
||||
address: s.address || '',
|
||||
bank_details: s.bank_details || ''
|
||||
});
|
||||
setShowSupplierModal(true);
|
||||
};
|
||||
|
||||
const handleSaveSupplier = async (e) => {
|
||||
if (e) e.preventDefault();
|
||||
if (!supplierForm.supplier_name.trim()) {
|
||||
notify('Supplier / Distributor name is required.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSavingSupplier(true);
|
||||
try {
|
||||
const res = await fetch(API_BASE + 'suppliers/save', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(supplierForm)
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.status) {
|
||||
notify(supplierForm.supplier_id ? 'Supplier updated successfully!' : 'New supplier added successfully!', 'success');
|
||||
setShowSupplierModal(false);
|
||||
await fetchSuppliers();
|
||||
if (data.supplier_id) {
|
||||
setSelectedSupplierId(String(data.supplier_id));
|
||||
}
|
||||
} else {
|
||||
notify(data.message || 'Failed to save supplier.', 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
notify('Network error saving supplier: ' + err.message, 'error');
|
||||
} finally {
|
||||
setIsSavingSupplier(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteSupplier = async (supplierId, supplierName) => {
|
||||
if (!confirm(`Are you sure you want to remove / deactivate supplier "${supplierName}"?`)) return;
|
||||
try {
|
||||
const res = await fetch(API_BASE + 'suppliers/delete', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ supplier_id: supplierId })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.status) {
|
||||
notify(data.message || 'Supplier removed successfully.', 'success');
|
||||
await fetchSuppliers();
|
||||
} else {
|
||||
notify(data.message || 'Failed to remove supplier.', 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
notify('Error: ' + err.message, 'error');
|
||||
}
|
||||
};
|
||||
|
||||
const filteredSuppliers = suppliers.filter(s => {
|
||||
if (!supplierSearch.trim()) return true;
|
||||
const q = supplierSearch.toLowerCase();
|
||||
return (s.supplier_name && s.supplier_name.toLowerCase().includes(q)) ||
|
||||
(s.gstin && s.gstin.toLowerCase().includes(q)) ||
|
||||
(s.dl_no_20b && s.dl_no_20b.toLowerCase().includes(q)) ||
|
||||
(s.dl_no_21b && s.dl_no_21b.toLowerCase().includes(q)) ||
|
||||
(s.phone && s.phone.toLowerCase().includes(q)) ||
|
||||
(s.contact_person && s.contact_person.toLowerCase().includes(q));
|
||||
});
|
||||
|
||||
const addRow = () => {
|
||||
setRows([...rows, { item_name: '', generic_name: '', batch_no: '', expiry_date: '', qty_packs: 1, free_qty_packs: 0, units_per_pack: 10, mrp: 0, ptr: 0, discount_pct: 0, gst_rate: 12 }]);
|
||||
};
|
||||
|
|
@ -4122,7 +4243,7 @@ function PurchaseView({ store, notify }) {
|
|||
<i className="bi bi-file-earmark-spreadsheet me-1"></i> Marg ERP / Excel Import
|
||||
</button>
|
||||
<button className={`btn btn-sm ${subTab === 'suppliers' ? 'btn-primary' : 'btn-outline-secondary'}`} onClick={() => setSubTab('suppliers')}>
|
||||
<i className="bi bi-truck me-1"></i> Supplier Directory
|
||||
<i className="bi bi-truck me-1"></i> Supplier Directory ({suppliers.length})
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -4131,7 +4252,12 @@ function PurchaseView({ store, notify }) {
|
|||
<h5 className="fw-bold mb-3"><i className="bi bi-receipt text-primary me-1"></i> Distributor Purchase Inward (Stock Entry)</h5>
|
||||
<div className="row g-2 mb-3">
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold">Supplier / Distributor</label>
|
||||
<div className="d-flex justify-content-between align-items-center mb-1">
|
||||
<label className="form-label small fw-bold mb-0">Supplier / Distributor</label>
|
||||
<button type="button" className="btn btn-link btn-sm p-0 text-decoration-none fw-semibold" style={{ fontSize: '11px' }} onClick={openAddSupplier}>
|
||||
<i className="bi bi-plus-circle me-1"></i>+ Add New
|
||||
</button>
|
||||
</div>
|
||||
<select className="form-select form-select-sm" value={selectedSupplierId} onChange={(e) => setSelectedSupplierId(e.target.value)}>
|
||||
<option value="">-- Select Supplier --</option>
|
||||
{suppliers.map(s => (
|
||||
|
|
@ -4273,35 +4399,322 @@ function PurchaseView({ store, notify }) {
|
|||
|
||||
{subTab === 'suppliers' && (
|
||||
<div className="counter-card">
|
||||
<h5 className="fw-bold mb-3"><i className="bi bi-truck text-primary me-1"></i> Approved Drug Distributors & Suppliers</h5>
|
||||
<div className="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
|
||||
<div>
|
||||
<h5 className="fw-bold mb-0 text-dark">
|
||||
<i className="bi bi-truck text-primary me-1"></i> Approved Drug Distributors & Suppliers
|
||||
</h5>
|
||||
<small className="text-muted">Manage licensed pharmaceutical distributors, DL Form 20B/21B, GSTIN, and credit terms</small>
|
||||
</div>
|
||||
<div className="d-flex gap-2">
|
||||
<div className="input-group input-group-sm" style={{ width: 250 }}>
|
||||
<span className="input-group-text bg-white border-end-0"><i className="bi bi-search text-muted"></i></span>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control border-start-0"
|
||||
placeholder="Search distributor, GST..."
|
||||
value={supplierSearch}
|
||||
onChange={(e) => setSupplierSearch(e.target.value)}
|
||||
/>
|
||||
{supplierSearch && (
|
||||
<button className="btn btn-outline-secondary" type="button" onClick={() => setSupplierSearch('')}>
|
||||
<i className="bi bi-x"></i>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<button className="btn btn-primary btn-sm px-3" onClick={openAddSupplier}>
|
||||
<i className="bi bi-plus-circle me-1"></i> Add New Supplier
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-responsive">
|
||||
<table className="table table-pos mb-0">
|
||||
<table className="table table-pos align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Supplier Name</th>
|
||||
<th style={{ width: 45 }}>#</th>
|
||||
<th>Distributor Name</th>
|
||||
<th>DL Form 20B / 21B</th>
|
||||
<th>GSTIN</th>
|
||||
<th>GSTIN & PAN</th>
|
||||
<th>Phone / Contact</th>
|
||||
<th>Credit Terms</th>
|
||||
<th>Address / Bank</th>
|
||||
<th style={{ width: 90 }} className="text-end pe-3">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{suppliers.map((s, i) => (
|
||||
<tr key={s.supplier_id}>
|
||||
<td>{i + 1}</td>
|
||||
<td className="fw-bold">{s.supplier_name}</td>
|
||||
<td>{s.dl_no_20b || 'N/A'} / {s.dl_no_21b || 'N/A'}</td>
|
||||
<td><code>{s.gstin}</code></td>
|
||||
<td>{s.phone} ({s.contact_person})</td>
|
||||
<td>{s.credit_days} Days</td>
|
||||
{filteredSuppliers.length === 0 ? (
|
||||
<tr>
|
||||
<td colSpan="8" className="text-center py-4 text-muted">
|
||||
<i className="bi bi-truck fs-2 d-block mb-1 text-secondary"></i>
|
||||
{suppliers.length === 0
|
||||
? 'No distributors registered yet. Click "Add New Supplier" to create one.'
|
||||
: 'No suppliers match your search query.'}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
) : (
|
||||
filteredSuppliers.map((s, i) => (
|
||||
<tr key={s.supplier_id}>
|
||||
<td className="fw-semibold text-secondary">{i + 1}</td>
|
||||
<td>
|
||||
<div className="fw-bold text-dark fs-6">{s.supplier_name}</div>
|
||||
{s.email && <small className="text-muted"><i className="bi bi-envelope me-1"></i>{s.email}</small>}
|
||||
</td>
|
||||
<td>
|
||||
<div className="small"><strong>20B:</strong> {s.dl_no_20b || <span className="text-muted">N/A</span>}</div>
|
||||
<div className="small"><strong>21B:</strong> {s.dl_no_21b || <span className="text-muted">N/A</span>}</div>
|
||||
</td>
|
||||
<td>
|
||||
<div><code className="text-primary fw-bold">{s.gstin || 'N/A'}</code></div>
|
||||
{s.pan_no && <small className="text-muted d-block">PAN: {s.pan_no}</small>}
|
||||
</td>
|
||||
<td>
|
||||
<div className="fw-semibold text-dark">{s.phone || 'N/A'}</div>
|
||||
{s.contact_person && <small className="text-muted"><i className="bi bi-person me-1"></i>{s.contact_person}</small>}
|
||||
</td>
|
||||
<td>
|
||||
<span className="badge bg-light text-dark border px-2 py-1">
|
||||
<i className="bi bi-calendar-check me-1 text-primary"></i>{s.credit_days || 30} Days
|
||||
</span>
|
||||
</td>
|
||||
<td style={{ maxWidth: 220 }}>
|
||||
{s.address && <div className="small text-truncate" title={s.address}><i className="bi bi-geo-alt me-1 text-muted"></i>{s.address}</div>}
|
||||
{s.bank_details && <div className="small text-muted text-truncate" title={s.bank_details}><i className="bi bi-bank me-1"></i>{s.bank_details}</div>}
|
||||
{!s.address && !s.bank_details && <span className="text-muted small">-</span>}
|
||||
</td>
|
||||
<td className="text-end pe-3">
|
||||
<div className="btn-group btn-group-sm">
|
||||
<button
|
||||
className="btn btn-outline-primary py-0.5 px-2"
|
||||
title="Edit Supplier"
|
||||
onClick={() => openEditSupplier(s)}
|
||||
>
|
||||
<i className="bi bi-pencil-square"></i>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-outline-danger py-0.5 px-2"
|
||||
title="Remove Supplier"
|
||||
onClick={() => handleDeleteSupplier(s.supplier_id, s.supplier_name)}
|
||||
>
|
||||
<i className="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Supplier Add / Edit Modal */}
|
||||
{showSupplierModal && (
|
||||
<div className="modal fade show d-block" style={{ backgroundColor: 'rgba(15, 23, 42, 0.75)' }} tabIndex="-1">
|
||||
<div className="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
|
||||
<div className="modal-content border-0 shadow-lg">
|
||||
<div className="modal-header bg-dark text-white py-2.5 px-3 d-flex justify-content-between align-items-center">
|
||||
<div className="d-flex align-items-center gap-2">
|
||||
<div className="bg-primary text-white rounded p-1.5 d-flex align-items-center justify-content-center" style={{ width: 32, height: 32 }}>
|
||||
<i className="bi bi-truck fs-5"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="modal-title mb-0 fw-bold">
|
||||
{supplierForm.supplier_id ? 'Edit Supplier / Distributor Details' : 'Add New Drug Distributor & Supplier'}
|
||||
</h6>
|
||||
<small className="text-light opacity-75">Statutory Drug Licenses, GSTIN, contact & credit terms</small>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" className="btn-close btn-close-white" onClick={() => setShowSupplierModal(false)}></button>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSaveSupplier}>
|
||||
<div className="modal-body p-3 bg-light">
|
||||
<div className="card border-0 shadow-sm p-3 mb-3 bg-white">
|
||||
<h6 className="fw-bold text-primary mb-2" style={{ fontSize: '13px' }}>
|
||||
<i className="bi bi-building me-1"></i> Basic Distributor Information
|
||||
</h6>
|
||||
<div className="row g-2">
|
||||
<div className="col-md-8">
|
||||
<label className="form-label small fw-bold mb-1">Distributor / Agency Name <span className="text-danger">*</span></label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="e.g. Apex Healthcare Distributors Pvt Ltd"
|
||||
value={supplierForm.supplier_name}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, supplier_name: e.target.value })}
|
||||
required
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold mb-1">Contact Person</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="e.g. Ramesh Gupta"
|
||||
value={supplierForm.contact_person}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, contact_person: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold mb-1">Phone / Mobile No.</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="+91 9811002233"
|
||||
value={supplierForm.phone}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, phone: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold mb-1">Email Address</label>
|
||||
<input
|
||||
type="email"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="sales@distributor.com"
|
||||
value={supplierForm.email}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, email: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold mb-1">Credit Terms</label>
|
||||
<div className="input-group input-group-sm">
|
||||
<input
|
||||
type="number"
|
||||
className="form-control form-control-sm"
|
||||
min="0"
|
||||
placeholder="30"
|
||||
value={supplierForm.credit_days}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, credit_days: e.target.value })}
|
||||
/>
|
||||
<span className="input-group-text bg-light">Days</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card border-0 shadow-sm p-3 mb-3 bg-white">
|
||||
<h6 className="fw-bold text-primary mb-2" style={{ fontSize: '13px' }}>
|
||||
<i className="bi bi-shield-check me-1"></i> Indian Statutory Drug Licenses & GSTIN
|
||||
</h6>
|
||||
<div className="row g-2">
|
||||
<div className="col-md-6">
|
||||
<label className="form-label small fw-bold mb-1">Drug License Form 20-B (Allopathic)</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="e.g. DL-20B-DEL-98441"
|
||||
value={supplierForm.dl_no_20b}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, dl_no_20b: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<label className="form-label small fw-bold mb-1">Drug License Form 21-B (Schedule C & C1)</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="e.g. DL-21B-DEL-98442"
|
||||
value={supplierForm.dl_no_21b}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, dl_no_21b: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold mb-1">GSTIN (15-Digit)</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm text-uppercase"
|
||||
maxLength="15"
|
||||
placeholder="07AACCA1234F1Z9"
|
||||
value={supplierForm.gstin}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, gstin: e.target.value.toUpperCase() })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold mb-1">PAN No. (10-Digit)</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm text-uppercase"
|
||||
maxLength="10"
|
||||
placeholder="AACCA1234F"
|
||||
value={supplierForm.pan_no}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, pan_no: e.target.value.toUpperCase() })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-4">
|
||||
<label className="form-label small fw-bold mb-1">State Code (GST)</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control form-control-sm"
|
||||
placeholder="07 (Delhi)"
|
||||
value={supplierForm.state_code}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, state_code: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card border-0 shadow-sm p-3 bg-white">
|
||||
<h6 className="fw-bold text-primary mb-2" style={{ fontSize: '13px' }}>
|
||||
<i className="bi bi-geo-alt me-1"></i> Address & Banking Details
|
||||
</h6>
|
||||
<div className="row g-2">
|
||||
<div className="col-md-6">
|
||||
<label className="form-label small fw-bold mb-1">Full Postal Address</label>
|
||||
<textarea
|
||||
className="form-control form-control-sm"
|
||||
rows="2"
|
||||
placeholder="Shop / Office No, Market, City, Pincode"
|
||||
value={supplierForm.address}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, address: e.target.value })}
|
||||
></textarea>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<label className="form-label small fw-bold mb-1">Bank Account & Settlement Details</label>
|
||||
<textarea
|
||||
className="form-control form-control-sm"
|
||||
rows="2"
|
||||
placeholder="Bank Name, A/c Number, IFSC Code, UPI ID"
|
||||
value={supplierForm.bank_details}
|
||||
onChange={(e) => setSupplierForm({ ...supplierForm, bank_details: e.target.value })}
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="modal-footer py-2 px-3 bg-white d-flex justify-content-between">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-outline-secondary btn-sm"
|
||||
onClick={() => setShowSupplierModal(false)}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-primary btn-sm px-4"
|
||||
disabled={isSavingSupplier}
|
||||
>
|
||||
{isSavingSupplier ? (
|
||||
<>
|
||||
<span className="spinner-border spinner-border-sm me-1" role="status"></span>
|
||||
Saving...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<i className="bi bi-check2-circle me-1"></i>
|
||||
{supplierForm.supplier_id ? 'Update Supplier' : 'Save Supplier'}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user