Add JoFotara linking modal and fix company limit
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user