fix: cancel button on form, edit customer, show installed/total count

This commit is contained in:
2026-03-26 08:20:51 +00:00
parent 72c3087dd0
commit eea011d68a
2 changed files with 49 additions and 24 deletions
+48 -24
View File
@@ -119,7 +119,7 @@ function CustomersTab() {
<span>חדש</span>
</button>
</div>
{showForm && <CustomerForm onDone={() => { setShowForm(false); reload() }} />}
{showForm && <CustomerForm onDone={() => { setShowForm(false); reload() }} onCancel={() => setShowForm(false)} />}
<div className="space-y-2">
{customers.map(c => (
<div key={c.id} onClick={() => setSelected(c.id)}
@@ -134,7 +134,7 @@ function CustomersTab() {
</div>
</div>
<div className="flex items-center gap-3 mt-3 text-xs text-slate-400">
<span>{c.extension_count} הרחבות</span>
<span>{c.installed_count || 0}/{c.extension_count} מותקנות</span>
<span></span>
<span className={c.is_active ? 'text-emerald-600' : 'text-red-500'}>{c.is_active ? 'פעיל' : 'לא פעיל'}</span>
</div>
@@ -154,29 +154,43 @@ function CustomersTab() {
)
}
function CustomerForm({ onDone }) {
const [form, setForm] = useState({ name: '', email: '', espocrm_url: '', espocrm_api_key: '' })
function CustomerForm({ onDone, onCancel, customer }) {
const isEdit = !!customer
const [form, setForm] = useState({
name: customer?.name || '', email: customer?.email || '',
espocrm_url: customer?.espocrm_url || '', espocrm_api_key: ''
})
const submit = async () => {
await fetch(`${API}/customers`, {
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(form)
const url = isEdit ? `${API}/customers/${customer.id}` : `${API}/customers`
await fetch(url, {
method: isEdit ? 'PUT' : 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(form)
})
onDone()
}
const inputClass = "w-full bg-slate-50 border-none rounded-xl px-4 py-2.5 text-sm focus:ring-2 focus:ring-blue-500"
return (
<div className="bg-white rounded-xl p-5 mb-4 space-y-3">
<input placeholder="שם לקוח" value={form.name} onChange={e => setForm({ ...form, name: e.target.value })}
className="w-full bg-slate-50 border-none rounded-xl px-4 py-2.5 text-sm focus:ring-2 focus:ring-blue-500 text-right" />
className={`${inputClass} text-right`} />
<input placeholder="אימייל" value={form.email} onChange={e => setForm({ ...form, email: e.target.value })}
className="w-full bg-slate-50 border-none rounded-xl px-4 py-2.5 text-sm focus:ring-2 focus:ring-blue-500" dir="ltr" />
className={inputClass} dir="ltr" />
<input placeholder="EspoCRM URL" value={form.espocrm_url} onChange={e => setForm({ ...form, espocrm_url: e.target.value })}
className="w-full bg-slate-50 border-none rounded-xl px-4 py-2.5 text-sm focus:ring-2 focus:ring-blue-500" dir="ltr" />
<input placeholder="Espo-Authorization (base64)" value={form.espocrm_api_key}
onChange={e => setForm({ ...form, espocrm_api_key: e.target.value })}
className="w-full bg-slate-50 border-none rounded-xl px-4 py-2.5 text-sm font-mono focus:ring-2 focus:ring-blue-500" dir="ltr" />
<button onClick={submit}
className="deep-action-gradient text-white px-4 py-2.5 rounded-xl font-bold w-full shadow-lg shadow-blue-500/20 active:scale-95 transition-all">
שמור
</button>
className={inputClass} dir="ltr" />
<input placeholder={isEdit ? "Espo-Authorization (השאר ריק אם לא משתנה)" : "Espo-Authorization (base64)"}
value={form.espocrm_api_key} onChange={e => setForm({ ...form, espocrm_api_key: e.target.value })}
className={`${inputClass} font-mono`} dir="ltr" />
<div className="flex gap-2">
<button onClick={submit}
className="deep-action-gradient text-white px-4 py-2.5 rounded-xl font-bold flex-1 shadow-lg shadow-blue-500/20 active:scale-95 transition-all">
{isEdit ? 'עדכון' : 'שמור'}
</button>
<button onClick={onCancel}
className="px-4 py-2.5 rounded-xl font-bold text-slate-500 hover:bg-slate-100 transition-all">
ביטול
</button>
</div>
</div>
)
}
@@ -186,6 +200,7 @@ function CustomerDetail({ customerId }) {
const { data: allExtensions } = useFetch(`${API}/extensions`)
const [deploying, setDeploying] = useState(null)
const [deployResult, setDeployResult] = useState(null)
const [editing, setEditing] = useState(false)
if (!customer) return <Loader />
@@ -224,15 +239,24 @@ function CustomerDetail({ customerId }) {
return (
<div>
<div className="flex items-center gap-4 mb-6">
<div className="w-12 h-12 rounded-xl bg-blue-100 flex items-center justify-center text-blue-700">
<Icon name="domain" className="text-2xl" />
{editing ? (
<CustomerForm customer={customer} onDone={() => { setEditing(false); reload() }} onCancel={() => setEditing(false)} />
) : (
<div className="flex items-center gap-4 mb-6">
<div className="w-12 h-12 rounded-xl bg-blue-100 flex items-center justify-center text-blue-700">
<Icon name="domain" className="text-2xl" />
</div>
<div className="text-right flex-1">
<h3 className="text-xl font-black text-slate-900">{customer.name}</h3>
<p className="text-sm text-slate-500" dir="ltr">{customer.espocrm_url}</p>
</div>
<button onClick={() => setEditing(true)}
className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
title="עריכת לקוח">
<Icon name="edit" className="text-lg" />
</button>
</div>
<div className="text-right">
<h3 className="text-xl font-black text-slate-900">{customer.name}</h3>
<p className="text-sm text-slate-500" dir="ltr">{customer.espocrm_url}</p>
</div>
</div>
)}
{deployResult && (
<div className={`p-4 rounded-xl mb-6 text-sm font-medium flex items-center gap-3 ${deployResult.status === 'ok' ? 'bg-emerald-50 text-emerald-800' : 'bg-red-50 text-red-800'}`}>