import React, { useState } from 'react'; import { User, Building2, CreditCard, Shield, Sliders, Lock, Settings as SettingsIcon, LogOut, Download, AlertTriangle } from 'lucide-react'; import { useUser, UserProfile, SignOutButton, useClerk } from '@clerk/clerk-react'; import { deleteUserAccount, getAccountExport, getSubscriptionStatus, updateAccountSettings, lookupCompany } from '../api/client'; import toast from 'react-hot-toast'; import { useQuery, useMutation } from '@tanstack/react-query'; import PricingModal from '../components/dashboard/PricingModal'; const Settings: React.FC = () => { const [activeTab, setActiveTab] = useState('profile'); const { signOut } = useClerk(); const [showDeleteModal, setShowDeleteModal] = useState(false); const [deleteInput, setDeleteInput] = useState(''); const [isDeleting, setIsDeleting] = useState(false); const [deleteSuccess, setDeleteSuccess] = useState(false); const [isExporting, setIsExporting] = useState(false); // States for Pricing Modal and Companies const [showPricing, setShowPricing] = useState(false); const [companies, setCompanies] = useState(() => { const saved = localStorage.getItem('grantforge_companies'); if (saved) { try { return JSON.parse(saved); } catch (e) { console.error("Błąd parsowania firm z LocalStorage", e); } } return [ { nip: '1234567890', name: 'GrantForge sp. z o.o.', city: 'Warszawa', status: 'Zatwierdzone' } ]; }); const [showCompanyModal, setShowCompanyModal] = useState(false); const [newNip, setNewNip] = useState(''); const [isLookingUp, setIsLookingUp] = useState(false); const [fetchedCompany, setFetchedCompany] = useState(null); const { data: subData, isLoading: subLoading, refetch: refetchSub } = useQuery({ queryKey: ['subscription-status'], queryFn: getSubscriptionStatus }); const updateSettingsMutation = useMutation({ mutationFn: updateAccountSettings, onSuccess: () => { toast.success("Ustawienia zostały zapisane."); refetchSub(); }, onError: () => { toast.error("Wystąpił błąd podczas zapisywania ustawień."); } }); const handleAddCompany = async () => { if (!newNip || newNip.length < 10) { toast.error("Wprowadź prawidłowy NIP (min. 10 cyfr)."); return; } setIsLookingUp(true); try { const data = await lookupCompany(newNip); setFetchedCompany({ nip: data.nip, name: data.name, city: data.voivodeship, address: `PKD: ${data.pkd ? data.pkd.join(', ') : 'Brak'}`, legalForm: `Przychody: ${data.revenue || 'Brak danych'} PLN` }); toast.success("Pobrano dane z bazy GUS."); } catch (err: any) { toast.error(err.response?.data?.detail || "Nie udało się pobrać danych z GUS."); } finally { setIsLookingUp(false); } }; const handleSaveFetchedCompany = () => { if (!fetchedCompany) return; const newCompany = { nip: fetchedCompany.nip, name: fetchedCompany.name, city: fetchedCompany.city, status: 'Zatwierdzone' }; const updatedCompanies = [...companies, newCompany]; setCompanies(updatedCompanies); localStorage.setItem('grantforge_companies', JSON.stringify(updatedCompanies)); setShowCompanyModal(false); setNewNip(''); setFetchedCompany(null); toast.success("Podmiot dodany pomyślnie."); }; const handleRemoveCompany = (nipToRemove: string) => { const updatedCompanies = companies.filter((c: any) => c.nip !== nipToRemove); setCompanies(updatedCompanies); localStorage.setItem('grantforge_companies', JSON.stringify(updatedCompanies)); toast.success("Podmiot został usunięty."); }; const handleExportData = async () => { setIsExporting(true); try { const data = await getAccountExport(); const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.setAttribute('download', `dotacje_ai_export_${new Date().toISOString().split('T')[0]}.json`); document.body.appendChild(link); link.click(); link.remove(); toast.success("Dane zostały wyeksportowane."); } catch (error) { toast.error("Wystąpił błąd podczas eksportu."); } finally { setIsExporting(false); } }; const handleDeleteAccount = async () => { if (deleteInput !== 'USUŃ') return; setIsDeleting(true); try { await deleteUserAccount(); setDeleteSuccess(true); setShowDeleteModal(false); toast.success( "Twoje dane w Dotacje AI zostały trwale usunięte. Za chwilę zostaniesz wylogowany.", { duration: 8000 } ); // Sign out after a short delay so they can read the toast or internal message setTimeout(() => { signOut(); }, 6000); } catch (error) { toast.error("Wystąpił błąd podczas usuwania danych."); } finally { setIsDeleting(false); } }; const tabs = [ { id: 'profile', label: 'Profil i Konto', icon: }, { id: 'companies', label: 'Moje Firmy', icon: }, { id: 'billing', label: 'Subskrypcja', icon: }, { id: 'security', label: 'Bezpieczeństwo', icon: }, { id: 'preferences', label: 'Preferencje', icon: }, { id: 'privacy', label: 'Dane i Prywatność', icon: }, ]; const renderContent = () => { switch (activeTab) { case 'profile': return (

Twój Profil

{/* We use Clerk's pre-built profile component embedded here */}
); case 'companies': return (

Zarządzanie podmiotami (Moje Firmy)

{companies.map((c, i) => (

{c.name}

NIP: {c.nip} • {c.city} • {c.status}

))}
); case 'billing': return (

Subskrypcja i Rozliczenia

Aktywny Plan

{subLoading ? '...' : (subData?.tier || 'FREE').toUpperCase()}

Dostęp do wszystkich sekcji i nielimitowane analizy RAG.

Historia Płatności

Nie posiadasz jeszcze historii faktur dla tego konta.

); case 'security': return (

Bezpieczeństwo

Weryfikacja dwuetapowa (2FA)

Zarządzaj zabezpieczeniami w panelu Profilu (Clerk).

Aktywne Sesje

Windows 11 / Chrome • Aktualna sesja

Konto i dostęp

); case 'preferences': const aiDisclaimer = subData?.settings?.ai_disclaimer_enabled ?? true; const gdprConsent = subData?.settings?.gdpr_consent_accepted ?? false; return (

Preferencje Aplikacji

updateSettingsMutation.mutate({ gdpr_consent_accepted: e.target.checked })} disabled={updateSettingsMutation.isPending} />
updateSettingsMutation.mutate({ ai_disclaimer_enabled: e.target.checked })} disabled={updateSettingsMutation.isPending} />
); case 'privacy': return (

Dane i Prywatność

Pobierz moje dane

Weksportuj paczkę ze wszystkimi Twoimi wnioskami i projektami w czytelnym formacie maszynowym (JSON).


Usuń konto

Usunięcie konta jest nieodwracalne i obejmuje wszystkie Twoje projekty oraz dane w systemie.

{deleteSuccess && (

Twoje dane w Dotacje AI zostały trwale usunięte.

Jeśli chcesz całkowicie usunąć konto logowania, przejdź do swojego profilu w Clerk → Manage Account → Delete Account.

)} {showDeleteModal && (

Potwierdź usunięcie

Ta operacja jest niemożliwa do cofnięcia. Kasujemy wszystkie projekty, logi i dane o zużyciu.

Aby potwierdzić, wpisz słowo USUŃ poniżej:

setDeleteInput(e.target.value)} placeholder="Wpisz USUŃ" style={{ width: '100%', marginBottom: '1.5rem', marginTop: '0.5rem', boxSizing: 'border-box' }} />
)}
); default: return null; } }; return (
{/* Lewy nawigator */}

Ustawienia

{tabs.map((tab) => ( ))}
{/* Prawy panel zwartości */}
{renderContent()}
{showPricing && setShowPricing(false)} />} {showCompanyModal && (

Dodaj firmę z GUS

{!fetchedCompany ? ( <>

Podaj NIP podmiotu. System pobierze dane z Głównego Urzędu Statystycznego i zweryfikuje powiązania KRS.

setNewNip(e.target.value)} placeholder="Wpisz 10-cyfrowy NIP" style={{ width: '100%', marginBottom: '1.5rem', boxSizing: 'border-box' }} />
) : ( <>

Znaleziono podmiot

Nazwa:
{fetchedCompany.name}
NIP:
{fetchedCompany.nip}
Adres:
{fetchedCompany.address}
Miejscowość:
{fetchedCompany.city}
Forma prawna:
{fetchedCompany.legalForm}
✓ Zweryfikowano w bazie REGON
✓ Brak powiązań kapitałowych wykluczających MŚP
)}
)}
); }; export default Settings;