Compare commits
1 Commits
deploy-202
...
deploy-202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cff73c1381 |
@@ -370,10 +370,24 @@ export default function ColorsManagement() {
|
|||||||
|
|
||||||
{/* Edit Modal */}
|
{/* Edit Modal */}
|
||||||
{editingColor && (
|
{editingColor && (
|
||||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
|
<div
|
||||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-md w-full max-h-[90vh] overflow-auto">
|
className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 p-4"
|
||||||
|
onClick={() => setEditingColor(null)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-700 max-w-md w-full max-h-[90vh] overflow-auto"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-center p-6 pb-0">
|
||||||
|
<h3 className="text-xl font-bold text-gray-900 dark:text-white">Izmeni boju</h3>
|
||||||
|
<button
|
||||||
|
onClick={() => setEditingColor(null)}
|
||||||
|
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-2xl leading-none"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<h3 className="text-xl font-bold mb-4 text-gray-900 dark:text-white">Izmeni boju</h3>
|
|
||||||
<ColorForm
|
<ColorForm
|
||||||
color={editingColor}
|
color={editingColor}
|
||||||
onSave={(color) => {
|
onSave={(color) => {
|
||||||
@@ -477,7 +491,7 @@ function ColorForm({
|
|||||||
readOnly={isBambuLabColor}
|
readOnly={isBambuLabColor}
|
||||||
pattern="^#[0-9A-Fa-f]{6}$"
|
pattern="^#[0-9A-Fa-f]{6}$"
|
||||||
placeholder="#000000"
|
placeholder="#000000"
|
||||||
className={`flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 ${isBambuLabColor ? 'bg-gray-100 dark:bg-gray-900 cursor-not-allowed' : ''}`}
|
className={`flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 ${isBambuLabColor ? 'bg-gray-100 dark:bg-gray-900 cursor-not-allowed' : 'bg-white dark:bg-gray-700'}`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{isBambuLabColor && (
|
{isBambuLabColor && (
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ export default function CustomersManagement() {
|
|||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const [darkMode, setDarkMode] = useState(false);
|
const [darkMode, setDarkMode] = useState(false);
|
||||||
const [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
|
const [showAddModal, setShowAddModal] = useState(false);
|
||||||
|
const [addForm, setAddForm] = useState({ name: '', phone: '', city: '', notes: '' });
|
||||||
|
const [addError, setAddError] = useState('');
|
||||||
|
const [addSaving, setAddSaving] = useState(false);
|
||||||
|
|
||||||
// Initialize dark mode
|
// Initialize dark mode
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -139,6 +143,35 @@ export default function CustomersManagement() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleAddCustomer = async () => {
|
||||||
|
if (!addForm.name.trim()) {
|
||||||
|
setAddError('Ime je obavezno');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setAddSaving(true);
|
||||||
|
setAddError('');
|
||||||
|
try {
|
||||||
|
await customerService.create({
|
||||||
|
name: addForm.name.trim(),
|
||||||
|
phone: addForm.phone.trim() || undefined,
|
||||||
|
city: addForm.city.trim() || undefined,
|
||||||
|
notes: addForm.notes.trim() || undefined,
|
||||||
|
});
|
||||||
|
setShowAddModal(false);
|
||||||
|
setAddForm({ name: '', phone: '', city: '', notes: '' });
|
||||||
|
await fetchCustomers();
|
||||||
|
} catch (err: unknown) {
|
||||||
|
const error = err as { response?: { data?: { code?: string } } };
|
||||||
|
if (error.response?.data?.code === '23505') {
|
||||||
|
setAddError('Kupac sa ovim brojem telefona vec postoji');
|
||||||
|
} else {
|
||||||
|
setAddError('Greska pri dodavanju kupca');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setAddSaving(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
localStorage.removeItem('authToken');
|
localStorage.removeItem('authToken');
|
||||||
localStorage.removeItem('tokenExpiry');
|
localStorage.removeItem('tokenExpiry');
|
||||||
@@ -230,8 +263,8 @@ export default function CustomersManagement() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Search bar */}
|
{/* Search bar + Add button */}
|
||||||
<div className="mb-6">
|
<div className="mb-6 flex items-center gap-4">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Pretrazi kupce..."
|
placeholder="Pretrazi kupce..."
|
||||||
@@ -239,6 +272,12 @@ export default function CustomersManagement() {
|
|||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
className="w-full max-w-md px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full max-w-md px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
/>
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowAddModal(true)}
|
||||||
|
className="px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 whitespace-nowrap font-medium"
|
||||||
|
>
|
||||||
|
+ Dodaj kupca
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Customer count */}
|
{/* Customer count */}
|
||||||
@@ -488,6 +527,108 @@ export default function CustomersManagement() {
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Add Customer Modal */}
|
||||||
|
{showAddModal && (
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
|
||||||
|
onClick={() => setShowAddModal(false)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-md mx-4 p-6"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-center mb-4">
|
||||||
|
<h2 className="text-xl font-bold text-gray-900 dark:text-white">
|
||||||
|
Dodaj kupca
|
||||||
|
</h2>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowAddModal(false)}
|
||||||
|
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-2xl leading-none"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{addError && (
|
||||||
|
<div className="mb-4 p-3 bg-red-50 dark:bg-red-900/20 text-red-800 dark:text-red-400 rounded text-sm">
|
||||||
|
{addError}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Ime *
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={addForm.name}
|
||||||
|
onChange={(e) => setAddForm({ ...addForm, name: e.target.value })}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
||||||
|
placeholder="Ime i prezime"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Telefon
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={addForm.phone}
|
||||||
|
onChange={(e) => setAddForm({ ...addForm, phone: e.target.value })}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
||||||
|
placeholder="Broj telefona"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Grad
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={addForm.city}
|
||||||
|
onChange={(e) => setAddForm({ ...addForm, city: e.target.value })}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
||||||
|
placeholder="Grad"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||||
|
Napomena
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
value={addForm.notes}
|
||||||
|
onChange={(e) => setAddForm({ ...addForm, notes: e.target.value })}
|
||||||
|
rows={3}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-green-500 focus:border-transparent"
|
||||||
|
placeholder="npr. stampa figurice, obicno crna..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-end gap-3 mt-6">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowAddModal(false)}
|
||||||
|
className="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600"
|
||||||
|
>
|
||||||
|
Otkazi
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleAddCustomer}
|
||||||
|
disabled={addSaving}
|
||||||
|
className="px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 disabled:opacity-50 font-medium"
|
||||||
|
>
|
||||||
|
{addSaving ? 'Cuvanje...' : 'Dodaj'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user