Add JoFotara linking modal and fix company limit

This commit is contained in:
Hamza-Ayed
2026-04-18 00:47:37 +03:00
parent ce7b1fc5d8
commit 77434fa815
3 changed files with 113 additions and 13 deletions

View File

@@ -13,12 +13,18 @@ export const CompaniesPage = () => {
const [isLoading, setIsLoading] = useState(true);
const [searchTerm, setSearchTerm] = useState('');
const [isAddModalOpen, setIsAddModalOpen] = useState(false);
const [isJoFotaraModalOpen, setIsJoFotaraModalOpen] = useState(false);
const [selectedCompany, setSelectedCompany] = useState<any>(null);
// Form State
// Form State (New Company)
const [name, setName] = useState('');
const [tin, setTin] = useState('');
const [address, setAddress] = useState('');
// Form State (JoFotara)
const [clientId, setClientId] = useState('');
const [secretKey, setSecretKey] = useState('');
const fetchCompanies = async () => {
try {
const { data } = await apiClient.get('/companies');
@@ -53,6 +59,29 @@ export const CompaniesPage = () => {
}
};
const handleOpenJoFotara = (company: any) => {
setSelectedCompany(company);
setClientId(''); // We don't fetch existing keys for security, user has to enter new ones if they want to update
setSecretKey('');
setIsJoFotaraModalOpen(true);
};
const handleSubmitJoFotara = async (e: React.FormEvent) => {
e.preventDefault();
try {
await apiClient.put(`/companies/${selectedCompany.id}/jofotara`, {
clientId,
secretKey
});
setIsJoFotaraModalOpen(false);
setSelectedCompany(null);
fetchCompanies(); // Refresh to show "Linked" status
} catch (error) {
console.error('Failed to link JoFotara', error);
alert('حدث خطأ أثناء ربط حساب جو فوترة');
}
};
const filteredCompanies = companies.filter(c =>
c.name.includes(searchTerm) || c.tax_identification_number?.includes(searchTerm)
);
@@ -131,8 +160,11 @@ export const CompaniesPage = () => {
</span>
)}
</div>
<button className="text-primary-600 text-sm font-bold hover:underline">
التفاصيل
<button
onClick={() => handleOpenJoFotara(company)}
className="text-primary-600 text-sm font-bold hover:underline"
>
{company.jofotara_client_id ? 'تحديث الربط' : 'إعداد جو فوترة'}
</button>
</div>
</div>
@@ -196,6 +228,62 @@ export const CompaniesPage = () => {
</div>
</div>
)}
{/* ── JoFotara Link Modal ───────────────────────────────── */}
{isJoFotaraModalOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/50 backdrop-blur-sm animate-in fade-in duration-200">
<div className="bg-white rounded-3xl p-8 w-full max-w-md shadow-2xl animate-in zoom-in-95 duration-200">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 rounded-xl bg-primary-50 text-primary-600 flex items-center justify-center">
<ShieldCheck className="w-6 h-6" />
</div>
<div>
<h3 className="text-xl font-bold text-slate-900">ربط نظام جو فوترة</h3>
<p className="text-sm text-slate-500">{selectedCompany?.name}</p>
</div>
</div>
<form onSubmit={handleSubmitJoFotara} className="space-y-4">
<div>
<label className="block text-sm font-bold text-slate-700 mb-1">Client ID</label>
<input
type="text"
required
value={clientId}
onChange={e => setClientId(e.target.value)}
className="w-full bg-slate-50 border border-slate-200 rounded-xl px-4 py-3 outline-none focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 transition-all font-mono text-sm"
placeholder="أدخل Client ID..."
/>
</div>
<div>
<label className="block text-sm font-bold text-slate-700 mb-1">Secret Key</label>
<input
type="password"
required
value={secretKey}
onChange={e => setSecretKey(e.target.value)}
className="w-full bg-slate-50 border border-slate-200 rounded-xl px-4 py-3 outline-none focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 transition-all font-mono text-sm"
placeholder="أدخل Secret Key..."
/>
</div>
<div className="flex gap-3 pt-4">
<button
type="button"
onClick={() => setIsJoFotaraModalOpen(false)}
className="flex-1 bg-slate-100 text-slate-700 font-bold py-3 rounded-xl hover:bg-slate-200 transition-all"
>
إلغاء
</button>
<button
type="submit"
className="flex-1 btn-primary py-3 rounded-xl"
>
حفظ وتشفير المفاتيح
</button>
</div>
</form>
</div>
</div>
)}
</div>
);
};