@portalduct/react-sdk-factorcloud-legacy 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +271 -0
  3. package/dist/api/connectionSync.d.ts +51 -0
  4. package/dist/api/factorcloud.d.ts +13 -0
  5. package/dist/api/portalduct.d.ts +33 -0
  6. package/dist/components/ClientSelectionModal.d.ts +10 -0
  7. package/dist/components/ConfigModal.d.ts +10 -0
  8. package/dist/components/ConnectDebtorModal.d.ts +16 -0
  9. package/dist/components/InterestSyncModal.d.ts +5 -0
  10. package/dist/components/PortalIntegration.d.ts +8 -0
  11. package/dist/components/RequestPortalModal.d.ts +8 -0
  12. package/dist/components/SyncBanner.d.ts +16 -0
  13. package/dist/components/SyncProgressModal.d.ts +31 -0
  14. package/dist/components/SyncWorkflow.d.ts +15 -0
  15. package/dist/components/UpdateCredentialsModal.d.ts +11 -0
  16. package/dist/components/ui/accordion.d.ts +7 -0
  17. package/dist/components/ui/alert-dialog.d.ts +20 -0
  18. package/dist/components/ui/alert.d.ts +8 -0
  19. package/dist/components/ui/aspect-ratio.d.ts +3 -0
  20. package/dist/components/ui/avatar.d.ts +6 -0
  21. package/dist/components/ui/badge.d.ts +9 -0
  22. package/dist/components/ui/breadcrumb.d.ts +19 -0
  23. package/dist/components/ui/button.d.ts +11 -0
  24. package/dist/components/ui/calendar.d.ts +8 -0
  25. package/dist/components/ui/card.d.ts +8 -0
  26. package/dist/components/ui/carousel.d.ts +18 -0
  27. package/dist/components/ui/chart.d.ts +61 -0
  28. package/dist/components/ui/checkbox.d.ts +4 -0
  29. package/dist/components/ui/collapsible.d.ts +5 -0
  30. package/dist/components/ui/command.d.ts +82 -0
  31. package/dist/components/ui/context-menu.d.ts +27 -0
  32. package/dist/components/ui/dialog.d.ts +19 -0
  33. package/dist/components/ui/drawer.d.ts +22 -0
  34. package/dist/components/ui/dropdown-menu.d.ts +27 -0
  35. package/dist/components/ui/form.d.ts +23 -0
  36. package/dist/components/ui/hover-card.d.ts +6 -0
  37. package/dist/components/ui/input-otp.d.ts +34 -0
  38. package/dist/components/ui/input.d.ts +3 -0
  39. package/dist/components/ui/label.d.ts +5 -0
  40. package/dist/components/ui/menubar.d.ts +33 -0
  41. package/dist/components/ui/navigation-menu.d.ts +12 -0
  42. package/dist/components/ui/pagination.d.ts +28 -0
  43. package/dist/components/ui/popover.d.ts +6 -0
  44. package/dist/components/ui/progress.d.ts +4 -0
  45. package/dist/components/ui/radio-group.d.ts +5 -0
  46. package/dist/components/ui/resizable.d.ts +23 -0
  47. package/dist/components/ui/scroll-area.d.ts +5 -0
  48. package/dist/components/ui/select.d.ts +13 -0
  49. package/dist/components/ui/separator.d.ts +4 -0
  50. package/dist/components/ui/sheet.d.ts +25 -0
  51. package/dist/components/ui/sidebar.d.ts +66 -0
  52. package/dist/components/ui/skeleton.d.ts +2 -0
  53. package/dist/components/ui/slider.d.ts +4 -0
  54. package/dist/components/ui/sonner.d.ts +5 -0
  55. package/dist/components/ui/switch.d.ts +4 -0
  56. package/dist/components/ui/table.d.ts +10 -0
  57. package/dist/components/ui/tabs.d.ts +7 -0
  58. package/dist/components/ui/textarea.d.ts +5 -0
  59. package/dist/components/ui/toast.d.ts +15 -0
  60. package/dist/components/ui/toaster.d.ts +1 -0
  61. package/dist/components/ui/toggle-group.d.ts +12 -0
  62. package/dist/components/ui/toggle.d.ts +12 -0
  63. package/dist/components/ui/tooltip.d.ts +7 -0
  64. package/dist/components/ui/use-toast.d.ts +3 -0
  65. package/dist/hooks/use-customer-status.d.ts +15 -0
  66. package/dist/hooks/use-mobile.d.ts +1 -0
  67. package/dist/hooks/use-toast.d.ts +44 -0
  68. package/dist/index.cjs +113 -0
  69. package/dist/index.cjs.map +1 -0
  70. package/dist/index.d.ts +1 -0
  71. package/dist/index.js +6874 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/lib/utils.d.ts +4 -0
  74. package/dist/pages/Index.d.ts +2 -0
  75. package/dist/pages/NotFound.d.ts +2 -0
  76. package/dist/placeholder.svg +1 -0
  77. package/dist/sdk/index.d.ts +66 -0
  78. package/dist/services/orchestration.d.ts +26 -0
  79. package/dist/types/config.d.ts +47 -0
  80. package/dist/types/factorcloud.d.ts +98 -0
  81. package/dist/types/merged.d.ts +16 -0
  82. package/dist/types/portalduct.d.ts +139 -0
  83. package/package.json +122 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 PortalDuct
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,271 @@
1
+ # @portalduct/react-sdk-factorcloud-legacy
2
+
3
+ React SDK for connecting FactorCloud debtors to carrier portals and syncing invoice data through an embedded modal workflow.
4
+
5
+ > **Auto-managed credentials**
6
+ >
7
+ > The SDK bootstraps its runtime configuration from the `check-customer-status` webhook. Supply your FactorCloud factor ID and the PortalDuct webhook bearer token and the SDK will fetch the latest FactorCloud and PortalDuct API tokens, API base URLs, and PortalDuct customer UUID for you.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @portalduct/react-sdk-factorcloud-legacy
13
+ ```
14
+
15
+ **Required peer dependencies** (install if you don't have them):
16
+
17
+ ```bash
18
+ npm install react react-dom @tanstack/react-query react-hook-form @hookform/resolvers lucide-react
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Drop in the prebuilt Sync banner (no manual CSS import needed)
24
+
25
+ The bundle ships with its own stylesheet, so you can simply import the banner component and start collecting connections. Only two required inputs are needed up front: the PortalDuct webhook bearer token (to call the Supabase webhooks) and your FactorCloud factor ID. Everything else is populated automatically after the first customer status check.
26
+
27
+ ```tsx
28
+ import { SyncBanner, type SDKConfig } from '@portalduct/react-sdk-factorcloud-legacy';
29
+
30
+ const baseConfig = {
31
+ portalduct: {
32
+ webhook_bearer_token: 'fc_webhook_token',
33
+ // Optional overrides if you are not using the default Supabase functions
34
+ sync_webhook_url: 'https://example.supabase.co/functions/v1/webhook-sync-connection',
35
+ verify_webhook_url: 'https://example.supabase.co/functions/v1/webhook-verify-connection',
36
+ environment: 'sandbox', // Optional: force the environment sent to Supabase
37
+ },
38
+ factorcloud: {
39
+ factorId: 'your_factor_id',
40
+ client_id: 'optional_client_id', // Optional: pre-select a client
41
+ },
42
+ } satisfies Partial<SDKConfig>;
43
+
44
+ function MyApp() {
45
+ return (
46
+ <SyncBanner
47
+ config={baseConfig as SDKConfig} // Remaining fields are hydrated by the SDK
48
+ onSyncComplete={() => console.log('Sync complete')}
49
+ onSyncError={(error) => console.error('Sync failed', error)}
50
+ />
51
+ );
52
+ }
53
+ ```
54
+
55
+ > **TypeScript tip:** When you only provide the minimal fields above, cast the object to `SDKConfig` at the callsite (as shown). The SDK fills in the missing properties after the status check resolves.
56
+
57
+ ### 2. Prefer manual control? Wrap your app with `QueryClientProvider`
58
+
59
+ If you need custom layout control, render `SyncWorkflow` directly. The banner example above auto-creates a React Query client, but for full control create your own instance and wrap your app:
60
+
61
+ ```tsx
62
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
63
+ import { SyncWorkflow, type SDKConfig } from '@portalduct/react-sdk-factorcloud-legacy';
64
+
65
+ const baseConfig = {
66
+ portalduct: { webhook_bearer_token: 'fc_webhook_token' },
67
+ factorcloud: { factorId: 'your_factor_id' },
68
+ } satisfies Partial<SDKConfig>;
69
+
70
+ const queryClient = new QueryClient();
71
+
72
+ function App() {
73
+ return (
74
+ <QueryClientProvider client={queryClient}>
75
+ {/* Your app content */}
76
+ <SyncWorkflow
77
+ config={baseConfig as SDKConfig}
78
+ trigger={<button>Sync Invoices</button>}
79
+ />
80
+ </QueryClientProvider>
81
+ );
82
+ }
83
+ ```
84
+
85
+ That's it! Clicking the "Sync Invoices" button opens a modal workflow that handles:
86
+ - Client selection (if no `client_id` provided)
87
+ - Debtor selection
88
+ - Portal connection setup
89
+ - Credential management (tokens are refreshed automatically)
90
+ - Invoice synchronization
91
+
92
+ ## Configuration
93
+
94
+ ### Minimal configuration inputs
95
+
96
+ Only two fields are required at initialization time:
97
+
98
+ | Field | Required? | Description |
99
+ |-------|-----------|-------------|
100
+ | `portalduct.webhook_bearer_token` | ✅ | Authenticates requests to the Supabase webhooks (`check-customer-status`, `webhook-sync-connection`, `webhook-verify-connection`). |
101
+ | `factorcloud.factorId` | ✅ | Identifies which FactorCloud account should be synced. |
102
+
103
+ Optional overrides you can provide:
104
+
105
+ | Field | When to set it |
106
+ |-------|----------------|
107
+ | `portalduct.sync_webhook_url` / `portalduct.verify_webhook_url` | Override the default Supabase function URLs. |
108
+ | `portalduct.environment` | Force a specific environment string to be sent to the webhook payload. The SDK auto-detects `sandbox` vs `production`, so most integrations can omit this. |
109
+ | `factorcloud.client_id` | Skip the client-selection step during syncing. |
110
+
111
+ Everything else—PortalDuct API bearer token, FactorCloud API bearer token, API base URLs, and the PortalDuct customer UUID—is hydrated automatically from the customer status response.
112
+
113
+ ### Runtime configuration shape
114
+
115
+ Internally the SDK works with a fully populated configuration object:
116
+
117
+ ```ts
118
+ import type { SDKConfig } from '@portalduct/react-sdk-factorcloud-legacy';
119
+
120
+ // After the first status check completes the SDK produces an object like this:
121
+ const resolvedConfig: SDKConfig = {
122
+ portalduct: {
123
+ bearer_token: 'pd_token',
124
+ env_url: 'https://sandbox.portalduct.com',
125
+ customer_id: '896ec608-373f-4fde-82e5-00b1f427dba5',
126
+ webhook_bearer_token: 'fc_webhook_token',
127
+ environment: 'sandbox',
128
+ sync_webhook_url: 'https://example.supabase.co/functions/v1/webhook-sync-connection',
129
+ verify_webhook_url: 'https://example.supabase.co/functions/v1/webhook-verify-connection',
130
+ },
131
+ factorcloud: {
132
+ bearer_token: 'fc_token',
133
+ factorId: 'your_factor_id',
134
+ env_url: 'https://api.int.factorcloud.com',
135
+ client_id: 'optional_client_id',
136
+ },
137
+ };
138
+ ```
139
+
140
+ Use the `useCustomerStatus` hook to observe and reuse the merged configuration:
141
+
142
+ ```tsx
143
+ import { useCustomerStatus, type SDKConfig } from '@portalduct/react-sdk-factorcloud-legacy';
144
+
145
+ const baseConfig = {
146
+ portalduct: { webhook_bearer_token: 'fc_webhook_token' },
147
+ factorcloud: { factorId: 'your_factor_id' },
148
+ } satisfies Partial<SDKConfig>;
149
+
150
+ function DebugConfig() {
151
+ const { resolvedConfig, loading } = useCustomerStatus(baseConfig as SDKConfig);
152
+
153
+ if (loading || !resolvedConfig) return <p>Loading…</p>;
154
+ return <pre>{JSON.stringify(resolvedConfig, null, 2)}</pre>;
155
+ }
156
+ ```
157
+
158
+ ### Standalone Modal Components
159
+
160
+ Import individual modals for custom workflows:
161
+
162
+ ```tsx
163
+ import { useState } from 'react';
164
+ import {
165
+ ConfigModal,
166
+ ConnectDebtorModal,
167
+ RequestPortalModal,
168
+ UpdateCredentialsModal,
169
+ SyncProgressModal,
170
+ ClientSelectionModal,
171
+ type SDKConfig,
172
+ } from '@portalduct/react-sdk-factorcloud-legacy';
173
+
174
+ function CustomWorkflow() {
175
+ const [open, setOpen] = useState(false);
176
+ const [config, setConfig] = useState<Partial<SDKConfig>>({
177
+ portalduct: { webhook_bearer_token: 'fc_webhook_token' },
178
+ factorcloud: { factorId: 'your_factor_id' },
179
+ });
180
+
181
+ return (
182
+ <ConfigModal
183
+ open={open}
184
+ onOpenChange={setOpen}
185
+ onSave={(next) => setConfig(next)}
186
+ currentConfig={config as SDKConfig}
187
+ />
188
+ );
189
+ }
190
+ ```
191
+
192
+ ### Direct API Access
193
+
194
+ Need to orchestrate data yourself? Pull the resolved config from `useCustomerStatus` first, then hand it to the lower-level API clients:
195
+
196
+ ```tsx
197
+ import { useCustomerStatus, type SDKConfig } from '@portalduct/react-sdk-factorcloud-legacy';
198
+ import {
199
+ PortalDuctAPI,
200
+ FactorCloudAPI,
201
+ ConnectionSyncAPI,
202
+ } from '@portalduct/react-sdk-factorcloud-legacy';
203
+
204
+ const baseConfig = {
205
+ portalduct: { webhook_bearer_token: 'fc_webhook_token' },
206
+ factorcloud: { factorId: 'your_factor_id' },
207
+ } satisfies Partial<SDKConfig>;
208
+
209
+ function CustomDataFlow() {
210
+ const { resolvedConfig } = useCustomerStatus(baseConfig as SDKConfig);
211
+
212
+ if (!resolvedConfig) {
213
+ return <p>Loading credentials…</p>;
214
+ }
215
+
216
+ const portalductApi = new PortalDuctAPI(
217
+ resolvedConfig.portalduct.env_url,
218
+ resolvedConfig.portalduct.bearer_token,
219
+ );
220
+
221
+ const factorcloudApi = new FactorCloudAPI(
222
+ resolvedConfig.factorcloud.env_url,
223
+ resolvedConfig.factorcloud.factorId,
224
+ resolvedConfig.factorcloud.bearer_token,
225
+ );
226
+
227
+ const connectionSync = new ConnectionSyncAPI({
228
+ webhookToken: resolvedConfig.portalduct.webhook_bearer_token,
229
+ customerId: resolvedConfig.portalduct.customer_id,
230
+ environment: resolvedConfig.portalduct.environment,
231
+ webhookUrl: resolvedConfig.portalduct.sync_webhook_url,
232
+ verifyWebhookUrl: resolvedConfig.portalduct.verify_webhook_url,
233
+ portalductBaseUrl: resolvedConfig.portalduct.env_url,
234
+ });
235
+
236
+ // ...custom logic using the clients above
237
+ }
238
+ ```
239
+
240
+ ### Data Orchestration Service
241
+
242
+ For complex data synchronization workflows you can instantiate the orchestration service once the config has been resolved:
243
+
244
+ ```tsx
245
+ import { useEffect } from 'react';
246
+ import { useCustomerStatus, DataOrchestrationService, type SDKConfig } from '@portalduct/react-sdk-factorcloud-legacy';
247
+
248
+ const baseConfig = {
249
+ portalduct: { webhook_bearer_token: 'fc_webhook_token' },
250
+ factorcloud: { factorId: 'your_factor_id' },
251
+ } satisfies Partial<SDKConfig>;
252
+
253
+ function SyncAllDebtors() {
254
+ const { resolvedConfig } = useCustomerStatus(baseConfig as SDKConfig);
255
+
256
+ useEffect(() => {
257
+ if (!resolvedConfig) return;
258
+
259
+ const orchestration = new DataOrchestrationService(resolvedConfig);
260
+ orchestration.getFactorCloudClients().then(console.log);
261
+ }, [resolvedConfig]);
262
+
263
+ return null;
264
+ }
265
+ ```
266
+
267
+ ## Security
268
+
269
+ ⚠️ **Never expose API tokens in client-side code in production!**
270
+
271
+ Even though the SDK auto-fetches credentials, the webhook you call still needs to run on a trusted backend (the provided Supabase functions or your own infrastructure). Store the webhook bearer token securely (environment variables, secret manager, etc.) and never hard-code it in publicly distributed builds.
@@ -0,0 +1,51 @@
1
+ import { CustomerStatusPayload } from '../types/config';
2
+ import { ResyncResponse } from '../types/portalduct';
3
+
4
+ type Environment = "sandbox" | "production" | string;
5
+ interface ConnectionSyncOptions {
6
+ webhookToken?: string;
7
+ customerId?: string;
8
+ /**
9
+ * Optional override for the sync webhook URL. Defaults to the Supabase function.
10
+ */
11
+ webhookUrl?: string;
12
+ /**
13
+ * Optional override for the verification webhook URL. Defaults to the Supabase function.
14
+ */
15
+ verifyWebhookUrl?: string;
16
+ /**
17
+ * Explicit environment identifier to send to the webhook.
18
+ */
19
+ environment?: Environment;
20
+ /**
21
+ * PortalDuct environment URL, used for automatic environment detection when
22
+ * an explicit environment value isn't provided.
23
+ */
24
+ portalductBaseUrl?: string;
25
+ /**
26
+ * Optional override for the customer status webhook URL. Defaults to the Supabase function.
27
+ */
28
+ customerStatusUrl?: string;
29
+ }
30
+ export declare class ConnectionSyncAPI {
31
+ private syncWebhookUrl;
32
+ private verifyWebhookUrl;
33
+ private webhookToken?;
34
+ private customerId?;
35
+ private environment;
36
+ private customerStatusUrl;
37
+ constructor({ webhookToken, customerId, webhookUrl, verifyWebhookUrl, environment, portalductBaseUrl, customerStatusUrl, }: ConnectionSyncOptions);
38
+ setWebhookToken(token: string): void;
39
+ setCustomerId(customerId: string): void;
40
+ setEnvironment(environment: Environment): void;
41
+ setWebhookUrl(webhookUrl: string): void;
42
+ setVerifyWebhookUrl(webhookUrl: string): void;
43
+ setCustomerStatusUrl(webhookUrl: string): void;
44
+ triggerConnectionSync(connectionId: string): Promise<ResyncResponse>;
45
+ triggerConnectionVerification(connectionId: string): Promise<ResyncResponse>;
46
+ private callWebhook;
47
+ private deriveEnvironmentFromBaseUrl;
48
+ fetchCustomerStatus(factorId: string): Promise<CustomerStatusPayload>;
49
+ isCustomerActive(factorId: string): Promise<boolean>;
50
+ }
51
+ export {};
@@ -0,0 +1,13 @@
1
+ import { FactorCloudClient, FactorCloudClientDetail, FactorCloudDebtor } from '../types/factorcloud';
2
+
3
+ export declare class FactorCloudAPI {
4
+ private baseUrl;
5
+ private factorId;
6
+ private token;
7
+ constructor(baseUrl: string, factorId: string, bearerToken: string);
8
+ getClients(limit?: number, page?: number): Promise<FactorCloudClient[]>;
9
+ getClientById(clientId: string): Promise<FactorCloudClientDetail>;
10
+ getDebtors(clientId: string, limit?: number, page?: number): Promise<FactorCloudDebtor[]>;
11
+ setToken(token: string): void;
12
+ getToken(): string;
13
+ }
@@ -0,0 +1,33 @@
1
+ import { PortalDuctCompany, PortalDuctConnection, CreateCompanyRequest, CreateConnectionRequest, UpdateConnectionRequest, PortalMapping, CreatePortalMappingRequest } from '../types/portalduct';
2
+
3
+ export declare class PortalDuctAPIError extends Error {
4
+ status: number;
5
+ code?: string;
6
+ type?: string;
7
+ requestId?: string;
8
+ constructor({ message, status, code, type, requestId, }: {
9
+ message: string;
10
+ status: number;
11
+ code?: string;
12
+ type?: string;
13
+ requestId?: string;
14
+ });
15
+ }
16
+ export declare class PortalDuctAPI {
17
+ private baseUrl;
18
+ private token;
19
+ constructor(baseUrl: string, bearerToken: string);
20
+ private buildError;
21
+ getCompanies(customerId: string): Promise<PortalDuctCompany[]>;
22
+ createCompany(request: CreateCompanyRequest): Promise<PortalDuctCompany>;
23
+ getConnections(companyId: string): Promise<PortalDuctConnection[]>;
24
+ createConnection(request: CreateConnectionRequest): Promise<PortalDuctConnection>;
25
+ updateConnection(connectionId: string, request: UpdateConnectionRequest): Promise<PortalDuctConnection>;
26
+ activateConnection(connectionId: string): Promise<PortalDuctConnection>;
27
+ deactivateConnection(connectionId: string): Promise<PortalDuctConnection>;
28
+ private updateActivationStatus;
29
+ setToken(token: string): void;
30
+ getToken(): string;
31
+ getPortalMappings(): Promise<PortalMapping[]>;
32
+ createPortalMapping(request: CreatePortalMappingRequest): Promise<PortalMapping>;
33
+ }
@@ -0,0 +1,10 @@
1
+ import { FactorCloudClient } from '../types/factorcloud';
2
+
3
+ interface ClientSelectionModalProps {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ clients: FactorCloudClient[];
7
+ onSelect: (client: FactorCloudClient) => void;
8
+ }
9
+ export declare function ClientSelectionModal({ open, onOpenChange, clients, onSelect, }: ClientSelectionModalProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,10 @@
1
+ import { SDKConfig } from '../types/config';
2
+
3
+ interface ConfigModalProps {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ onSave: (config: SDKConfig) => void;
7
+ currentConfig?: Partial<SDKConfig>;
8
+ }
9
+ export declare const ConfigModal: ({ open, onOpenChange, onSave, currentConfig, }: ConfigModalProps) => import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,16 @@
1
+ import { MergedDebtor } from '../types/merged';
2
+ import { PortalMapping } from '../types/portalduct';
3
+
4
+ interface ConnectDebtorModalProps {
5
+ open: boolean;
6
+ onOpenChange: (open: boolean) => void;
7
+ debtor: MergedDebtor | null;
8
+ availablePortals: PortalMapping[];
9
+ loadingPortals?: boolean;
10
+ loading?: boolean;
11
+ isChangingPortal?: boolean;
12
+ onConnect: (portalId: string, username: string, password: string) => void;
13
+ onRequestNewPortal: () => void;
14
+ }
15
+ export declare function ConnectDebtorModal({ open, onOpenChange, debtor, availablePortals, loadingPortals, loading, isChangingPortal, onConnect, onRequestNewPortal }: ConnectDebtorModalProps): import("react/jsx-runtime").JSX.Element;
16
+ export {};
@@ -0,0 +1,5 @@
1
+ export interface InterestSyncModalProps {
2
+ open: boolean;
3
+ onOpenChange: (open: boolean) => void;
4
+ }
5
+ export declare function InterestSyncModal({ open, onOpenChange }: InterestSyncModalProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { SDKConfig } from '../types/config';
2
+
3
+ interface PortalIntegrationProps {
4
+ config: SDKConfig;
5
+ onTokenExpired?: (service: 'factorcloud' | 'portalduct') => void;
6
+ }
7
+ export declare const PortalIntegration: ({ config, onTokenExpired }: PortalIntegrationProps) => import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,8 @@
1
+ interface RequestPortalModalProps {
2
+ open: boolean;
3
+ onOpenChange: (open: boolean) => void;
4
+ loading?: boolean;
5
+ onSubmit: (name: string, host: string) => void;
6
+ }
7
+ export declare function RequestPortalModal({ open, onOpenChange, loading, onSubmit }: RequestPortalModalProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { QueryClient } from '@tanstack/react-query';
3
+ import { SyncWorkflowProps } from './SyncWorkflow';
4
+
5
+ type SyncWorkflowPropKeys = "config" | "onTokenExpired" | "onSyncComplete" | "onSyncError" | "autoStart";
6
+ export interface SyncBannerProps extends Pick<SyncWorkflowProps, SyncWorkflowPropKeys> {
7
+ queryClient?: QueryClient;
8
+ title?: ReactNode;
9
+ badge?: ReactNode;
10
+ ctaLabel?: ReactNode;
11
+ icon?: ReactNode;
12
+ variant?: "full" | "compact";
13
+ theme?: "light" | "dark" | "auto";
14
+ }
15
+ export declare const SyncBanner: ({ config, queryClient, variant, theme, title, badge, ctaLabel, icon, onTokenExpired, onSyncComplete, onSyncError, autoStart, }: SyncBannerProps) => import("react/jsx-runtime").JSX.Element;
16
+ export {};
@@ -0,0 +1,31 @@
1
+ import { FactorCloudClient } from '../types/factorcloud';
2
+ import { MergedDebtor } from '../types/merged';
3
+
4
+ export type SyncStep = "idle" | "checking-config" | "authenticating" | "loading-clients" | "selecting-client" | "selecting-debtor" | "loading-data" | "review" | "complete" | "error";
5
+ interface SyncProgressModalProps {
6
+ open: boolean;
7
+ onOpenChange: (open: boolean) => void;
8
+ currentStep: SyncStep;
9
+ error?: string;
10
+ clients?: FactorCloudClient[];
11
+ debtors?: MergedDebtor[];
12
+ selectedDebtor?: MergedDebtor | null;
13
+ selectedClient?: FactorCloudClient | null;
14
+ onSelectClient?: (client: FactorCloudClient) => void;
15
+ onSelectDebtor?: (debtor: MergedDebtor) => void;
16
+ onConnectDebtor?: (debtor: MergedDebtor) => void;
17
+ onEditCredentials?: (debtor: MergedDebtor) => void;
18
+ onChangePortal?: (debtor: MergedDebtor) => void;
19
+ onToggleActivation?: (debtor: MergedDebtor) => void;
20
+ onSyncDebtor?: (debtor: MergedDebtor) => void;
21
+ onVerifyDebtor?: (debtor: MergedDebtor) => void;
22
+ togglingDebtorId?: string | null;
23
+ syncingDebtorId?: string | null;
24
+ verifyingDebtorId?: string | null;
25
+ allowBackToClientSelection?: boolean;
26
+ onBackToClientSelection?: () => void;
27
+ activeTab?: MergedDebtor["status"];
28
+ onActiveTabChange?: (tab: MergedDebtor["status"]) => void;
29
+ }
30
+ export declare function SyncProgressModal({ open, onOpenChange, currentStep, error, clients, debtors, selectedDebtor, selectedClient, onSelectClient, onSelectDebtor, onConnectDebtor, onEditCredentials, onChangePortal, onToggleActivation, onSyncDebtor, onVerifyDebtor, togglingDebtorId, syncingDebtorId, verifyingDebtorId, allowBackToClientSelection, onBackToClientSelection, activeTab, onActiveTabChange, }: SyncProgressModalProps): import("react/jsx-runtime").JSX.Element;
31
+ export {};
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+ import { SDKConfig } from '../types/config';
3
+ import { MergedDebtor } from '../types/merged';
4
+ import { CustomerStatusState } from '../hooks/use-customer-status';
5
+
6
+ export interface SyncWorkflowProps {
7
+ config: SDKConfig;
8
+ onTokenExpired?: (service: 'factorcloud' | 'portalduct') => void;
9
+ trigger?: ReactNode;
10
+ onSyncComplete?: (debtors: MergedDebtor[]) => void;
11
+ onSyncError?: (error: Error) => void;
12
+ autoStart?: boolean;
13
+ customerStatus?: CustomerStatusState;
14
+ }
15
+ export declare const SyncWorkflow: ({ config, onTokenExpired, trigger, onSyncComplete, onSyncError, autoStart, customerStatus, }: SyncWorkflowProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { MergedDebtor } from '../types/merged';
2
+
3
+ interface UpdateCredentialsModalProps {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ debtor: MergedDebtor | null;
7
+ onUpdate: (username: string, password: string) => void;
8
+ loading?: boolean;
9
+ }
10
+ export declare function UpdateCredentialsModal({ open, onOpenChange, debtor, onUpdate, loading, }: UpdateCredentialsModalProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
3
+ declare const Accordion: React.ForwardRefExoticComponent<(AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps) & React.RefAttributes<HTMLDivElement>>;
4
+ declare const AccordionItem: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
5
+ declare const AccordionTrigger: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const AccordionContent: React.ForwardRefExoticComponent<Omit<AccordionPrimitive.AccordionContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
3
+ declare const AlertDialog: React.FC<AlertDialogPrimitive.AlertDialogProps>;
4
+ declare const AlertDialogTrigger: React.ForwardRefExoticComponent<AlertDialogPrimitive.AlertDialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
5
+ declare const AlertDialogPortal: React.FC<AlertDialogPrimitive.AlertDialogPortalProps>;
6
+ declare const AlertDialogOverlay: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ declare const AlertDialogContent: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
8
+ declare const AlertDialogHeader: {
9
+ ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
10
+ displayName: string;
11
+ };
12
+ declare const AlertDialogFooter: {
13
+ ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
14
+ displayName: string;
15
+ };
16
+ declare const AlertDialogTitle: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
17
+ declare const AlertDialogDescription: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
18
+ declare const AlertDialogAction: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogActionProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
19
+ declare const AlertDialogCancel: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogCancelProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
20
+ export { AlertDialog, AlertDialogPortal, AlertDialogOverlay, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, };
@@ -0,0 +1,8 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import * as React from "react";
3
+ declare const Alert: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: {
4
+ variant?: "default" | "destructive";
5
+ } & import('class-variance-authority/types').ClassProp) => string> & React.RefAttributes<HTMLDivElement>>;
6
+ declare const AlertTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
7
+ declare const AlertDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
8
+ export { Alert, AlertTitle, AlertDescription };
@@ -0,0 +1,3 @@
1
+ import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
2
+ declare const AspectRatio: import('react').ForwardRefExoticComponent<AspectRatioPrimitive.AspectRatioProps & import('react').RefAttributes<HTMLDivElement>>;
3
+ export { AspectRatio };
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ import * as AvatarPrimitive from "@radix-ui/react-avatar";
3
+ declare const Avatar: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
4
+ declare const AvatarImage: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React.RefAttributes<HTMLImageElement>, "ref"> & React.RefAttributes<HTMLImageElement>>;
5
+ declare const AvatarFallback: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
6
+ export { Avatar, AvatarImage, AvatarFallback };
@@ -0,0 +1,9 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import * as React from "react";
3
+ declare const badgeVariants: (props?: {
4
+ variant?: "default" | "destructive" | "outline" | "secondary";
5
+ } & import('class-variance-authority/types').ClassProp) => string;
6
+ export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
7
+ }
8
+ declare function Badge({ className, variant, ...props }: BadgeProps): import("react/jsx-runtime").JSX.Element;
9
+ export { Badge, badgeVariants };
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ declare const Breadcrumb: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & {
3
+ separator?: React.ReactNode;
4
+ } & React.RefAttributes<HTMLElement>>;
5
+ declare const BreadcrumbList: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.OlHTMLAttributes<HTMLOListElement>, HTMLOListElement>, "ref"> & React.RefAttributes<HTMLOListElement>>;
6
+ declare const BreadcrumbItem: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & React.RefAttributes<HTMLLIElement>>;
7
+ declare const BreadcrumbLink: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref"> & {
8
+ asChild?: boolean;
9
+ } & React.RefAttributes<HTMLAnchorElement>>;
10
+ declare const BreadcrumbPage: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
11
+ declare const BreadcrumbSeparator: {
12
+ ({ children, className, ...props }: React.ComponentProps<"li">): import("react/jsx-runtime").JSX.Element;
13
+ displayName: string;
14
+ };
15
+ declare const BreadcrumbEllipsis: {
16
+ ({ className, ...props }: React.ComponentProps<"span">): import("react/jsx-runtime").JSX.Element;
17
+ displayName: string;
18
+ };
19
+ export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis, };
@@ -0,0 +1,11 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import * as React from "react";
3
+ declare const buttonVariants: (props?: {
4
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "factorcloud" | "success" | "tab";
5
+ size?: "default" | "tab" | "sm" | "lg" | "icon";
6
+ } & import('class-variance-authority/types').ClassProp) => string;
7
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
8
+ asChild?: boolean;
9
+ }
10
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
11
+ export { Button, buttonVariants };
@@ -0,0 +1,8 @@
1
+ import { DayPicker } from 'react-day-picker';
2
+ import * as React from "react";
3
+ export type CalendarProps = React.ComponentProps<typeof DayPicker>;
4
+ declare function Calendar({ className, classNames, showOutsideDays, ...props }: CalendarProps): import("react/jsx-runtime").JSX.Element;
5
+ declare namespace Calendar {
6
+ var displayName: string;
7
+ }
8
+ export { Calendar };