@accounter/client 0.0.7-alpha-20251020201456-275b6a9424e58d4d2c7e9099986230d087ccd6cd → 0.0.8-alpha-20251021150028-9eb73ba6576d67c75a60786d0e4ab0876fd7a95c

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 (42) hide show
  1. package/CHANGELOG.md +102 -105
  2. package/dist/assets/index-0eCf1BcD.css +1 -0
  3. package/dist/assets/index-DHTbHvtz.js +1188 -0
  4. package/dist/assets/{index.es-DldZjCMz.js → index.es-DHwHzag1.js} +1 -1
  5. package/dist/index.html +2 -2
  6. package/package.json +1 -2
  7. package/src/app.tsx +4 -8
  8. package/src/components/business-transactions/business-extended-info.tsx +13 -9
  9. package/src/components/charges/charge-extended-info-menu.tsx +21 -27
  10. package/src/components/charges/charges-row.tsx +10 -12
  11. package/src/components/charges/charges-table.tsx +9 -15
  12. package/src/components/common/documents/issue-document/recent-client-docs.tsx +3 -5
  13. package/src/components/common/forms/business-card.tsx +0 -1
  14. package/src/components/common/forms/modify-business-fields.tsx +19 -2
  15. package/src/components/common/inputs/combo-box.tsx +1 -1
  16. package/src/components/reports/trial-balance-report/trial-balance-report-group.tsx +6 -4
  17. package/src/components/reports/trial-balance-report/trial-balance-report-sort-code.tsx +11 -8
  18. package/src/gql/gql.ts +6 -72
  19. package/src/gql/graphql.ts +14 -193
  20. package/src/helpers/currency.ts +0 -5
  21. package/src/helpers/index.ts +0 -2
  22. package/dist/assets/index-BSNI6g4T.js +0 -1224
  23. package/dist/assets/index-CzRRUK04.css +0 -1
  24. package/src/components/business/business-header.tsx +0 -65
  25. package/src/components/business/charges-section.tsx +0 -82
  26. package/src/components/business/charts-section.tsx +0 -115
  27. package/src/components/business/configurations-section.tsx +0 -835
  28. package/src/components/business/contact-info-section.tsx +0 -544
  29. package/src/components/business/contracts-section.tsx +0 -195
  30. package/src/components/business/documents-section.tsx +0 -26
  31. package/src/components/business/index.tsx +0 -171
  32. package/src/components/business/integrations-section.tsx +0 -479
  33. package/src/components/business/transactions-section.tsx +0 -26
  34. package/src/components/clients/contracts/modify-contract-dialog.tsx +0 -426
  35. package/src/components/clients/modify-client-dialog.tsx +0 -276
  36. package/src/components/screens/businesses/business.tsx +0 -50
  37. package/src/components/ui/progress.tsx +0 -25
  38. package/src/components/ui/skeleton.tsx +0 -12
  39. package/src/helpers/contracts.ts +0 -22
  40. package/src/helpers/pcn874.ts +0 -17
  41. package/src/hooks/use-insert-client.ts +0 -80
  42. package/src/hooks/use-update-client.ts +0 -75
@@ -1,426 +0,0 @@
1
- import { useCallback, useEffect, useState } from 'react';
2
- import { Plus } from 'lucide-react';
3
- import { useForm } from 'react-hook-form';
4
- import { z } from 'zod';
5
- import { Button } from '@/components/ui/button.js';
6
- import {
7
- Dialog,
8
- DialogContent,
9
- DialogDescription,
10
- DialogFooter,
11
- DialogHeader,
12
- DialogTitle,
13
- DialogTrigger,
14
- } from '@/components/ui/dialog.js';
15
- import {
16
- Form,
17
- FormControl,
18
- FormField,
19
- FormItem,
20
- FormLabel,
21
- FormMessage,
22
- } from '@/components/ui/form.js';
23
- import { Input } from '@/components/ui/input.js';
24
- import {
25
- Select,
26
- SelectContent,
27
- SelectItem,
28
- SelectTrigger,
29
- SelectValue,
30
- } from '@/components/ui/select.js';
31
- import { Switch } from '@/components/ui/switch.js';
32
- import { Textarea } from '@/components/ui/textarea.js';
33
- import { BillingCycle, Currency, DocumentType, Product, SubscriptionPlan } from '@/gql/graphql.js';
34
- import { getDocumentNameFromType, standardBillingCycle, standardPlan } from '@/helpers/index.js';
35
- import { zodResolver } from '@hookform/resolvers/zod';
36
-
37
- const contractFormSchema = z.object({
38
- id: z.uuid().optional(),
39
- operationsLimit: z.number().min(1, 'Operations limit must be at least 1'),
40
- startDate: z.iso.datetime('Start date is required'),
41
- endDate: z.iso.datetime('End date is required'),
42
- po: z.string().optional(),
43
- paymentAmount: z.number().min(0, 'Payment amount must be non-negative'),
44
- paymentCurrency: z.enum(Object.values(Currency), 'Currency is required'),
45
- productType: z.enum(Object.values(Product)).optional(),
46
- signedAgreementLink: z.url().optional().or(z.literal('')),
47
- msCloudLink: z.url().optional().or(z.literal('')),
48
- billingCycle: z.enum(Object.values(BillingCycle)).optional(),
49
- subscriptionPlan: z.enum(Object.values(SubscriptionPlan)).optional(),
50
- isActive: z.boolean(),
51
- defaultRemark: z.string().optional(),
52
- defaultDocumentType: z.enum(Object.values(DocumentType)),
53
- });
54
-
55
- export type ContractFormValues = z.infer<typeof contractFormSchema>;
56
-
57
- const newContractDefaultValues: ContractFormValues = {
58
- operationsLimit: 0,
59
- startDate: '',
60
- endDate: '',
61
- po: '',
62
- paymentAmount: 0,
63
- paymentCurrency: Currency.Usd,
64
- productType: Product.Hive,
65
- signedAgreementLink: '',
66
- msCloudLink: '',
67
- billingCycle: BillingCycle.Monthly,
68
- subscriptionPlan: undefined,
69
- isActive: true,
70
- defaultRemark: undefined,
71
- defaultDocumentType: DocumentType.Proforma,
72
- };
73
-
74
- interface Props {
75
- contract?: ContractFormValues | null;
76
- onDone?: () => void;
77
- }
78
-
79
- export function ModifyContractDialog({ contract, onDone }: Props) {
80
- const [isDialogOpen, setIsDialogOpen] = useState(false);
81
- const [editingContract, setEditingContract] = useState<ContractFormValues | null>(null);
82
-
83
- const form = useForm<ContractFormValues>({
84
- resolver: zodResolver(contractFormSchema),
85
- defaultValues: contract || newContractDefaultValues,
86
- });
87
-
88
- useEffect(() => {
89
- if (contract) {
90
- setEditingContract(contract);
91
- form.reset({
92
- operationsLimit: contract.operationsLimit,
93
- startDate: contract.startDate,
94
- endDate: contract.endDate,
95
- po: contract.po,
96
- paymentAmount: contract.paymentAmount,
97
- paymentCurrency: contract.paymentCurrency,
98
- productType: contract.productType,
99
- signedAgreementLink: contract.signedAgreementLink,
100
- msCloudLink: contract.msCloudLink,
101
- billingCycle: contract.billingCycle,
102
- subscriptionPlan: contract.subscriptionPlan,
103
- isActive: contract.isActive,
104
- defaultRemark: contract.defaultRemark,
105
- defaultDocumentType: contract.defaultDocumentType,
106
- });
107
- setIsDialogOpen(true);
108
- }
109
- }, [contract, form]);
110
-
111
- const handleNew = () => {
112
- setEditingContract(null);
113
- form.reset(newContractDefaultValues);
114
- setIsDialogOpen(true);
115
- };
116
-
117
- const onSubmit = useCallback(
118
- async (values: ContractFormValues) => {
119
- if (editingContract) {
120
- console.log('[v0] Updating contract:', editingContract.id, values);
121
- // TODO: Handle contract update
122
- } else {
123
- console.log('[v0] Creating new contract:', values);
124
- // TODO: Handle contract creation
125
- }
126
- setIsDialogOpen(false);
127
- setEditingContract(null);
128
- onDone?.();
129
- },
130
- [editingContract, onDone],
131
- );
132
-
133
- return (
134
- <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
135
- <DialogTrigger asChild>
136
- <Button size="sm" onClick={handleNew}>
137
- <Plus className="h-4 w-4 mr-2" />
138
- New Contract
139
- </Button>
140
- </DialogTrigger>
141
- <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
142
- <DialogHeader>
143
- <DialogTitle>{editingContract ? 'Edit Contract' : 'Create New Contract'}</DialogTitle>
144
- <DialogDescription>
145
- {editingContract
146
- ? 'Update contract details'
147
- : 'Add a new contract with all required details'}
148
- </DialogDescription>
149
- </DialogHeader>
150
- <Form {...form}>
151
- <form onSubmit={form.handleSubmit(onSubmit)}>
152
- <div className="grid gap-4 py-4">
153
- <div className="grid gap-4 md:grid-cols-2">
154
- <FormField
155
- control={form.control}
156
- name="operationsLimit"
157
- render={({ field }) => (
158
- <FormItem>
159
- <FormLabel>Operations Limit</FormLabel>
160
- <FormControl>
161
- <Input type="number" placeholder="500" {...field} />
162
- </FormControl>
163
- <FormMessage />
164
- </FormItem>
165
- )}
166
- />
167
- <FormField
168
- control={form.control}
169
- name="po"
170
- render={({ field }) => (
171
- <FormItem>
172
- <FormLabel>PO Number</FormLabel>
173
- <FormControl>
174
- <Input placeholder="PO-2024-001" {...field} />
175
- </FormControl>
176
- <FormMessage />
177
- </FormItem>
178
- )}
179
- />
180
- </div>
181
-
182
- <div className="grid gap-4 md:grid-cols-2">
183
- <FormField
184
- control={form.control}
185
- name="startDate"
186
- render={({ field }) => (
187
- <FormItem>
188
- <FormLabel>Start Date</FormLabel>
189
- <FormControl>
190
- <Input type="date" {...field} />
191
- </FormControl>
192
- <FormMessage />
193
- </FormItem>
194
- )}
195
- />
196
- <FormField
197
- control={form.control}
198
- name="endDate"
199
- render={({ field }) => (
200
- <FormItem>
201
- <FormLabel>End Date</FormLabel>
202
- <FormControl>
203
- <Input type="date" {...field} />
204
- </FormControl>
205
- <FormMessage />
206
- </FormItem>
207
- )}
208
- />
209
- </div>
210
-
211
- <div className="grid gap-4 md:grid-cols-3">
212
- <FormField
213
- control={form.control}
214
- name="paymentAmount"
215
- render={({ field }) => (
216
- <FormItem className="md:col-span-2">
217
- <FormLabel>Payment Amount</FormLabel>
218
- <FormControl>
219
- <Input type="number" placeholder="24000" {...field} />
220
- </FormControl>
221
- <FormMessage />
222
- </FormItem>
223
- )}
224
- />
225
- <FormField
226
- control={form.control}
227
- name="paymentCurrency"
228
- render={({ field }) => (
229
- <FormItem>
230
- <FormLabel>Currency</FormLabel>
231
- <Select onValueChange={field.onChange} defaultValue={field.value}>
232
- <FormControl>
233
- <SelectTrigger>
234
- <SelectValue />
235
- </SelectTrigger>
236
- </FormControl>
237
- <SelectContent>
238
- {Object.values(Currency).map(currency => (
239
- <SelectItem key={currency} value={currency}>
240
- {currency}
241
- </SelectItem>
242
- ))}
243
- </SelectContent>
244
- </Select>
245
- <FormMessage />
246
- </FormItem>
247
- )}
248
- />
249
- </div>
250
-
251
- <div className="grid gap-4 md:grid-cols-2">
252
- <FormField
253
- control={form.control}
254
- name="productType"
255
- render={({ field }) => (
256
- <FormItem>
257
- <FormLabel>Product Type</FormLabel>
258
- <FormControl>
259
- <Input placeholder="Cloud Services" {...field} />
260
- </FormControl>
261
- <FormMessage />
262
- </FormItem>
263
- )}
264
- />
265
- <FormField
266
- control={form.control}
267
- name="billingCycle"
268
- render={({ field }) => (
269
- <FormItem>
270
- <FormLabel>Billing Cycle</FormLabel>
271
- <Select onValueChange={field.onChange} defaultValue={field.value}>
272
- <FormControl>
273
- <SelectTrigger>
274
- <SelectValue />
275
- </SelectTrigger>
276
- </FormControl>
277
- <SelectContent>
278
- {Object.values(BillingCycle).map(cycle => (
279
- <SelectItem key={cycle} value={cycle}>
280
- {standardBillingCycle(cycle)}
281
- </SelectItem>
282
- ))}
283
- </SelectContent>
284
- </Select>
285
- <FormMessage />
286
- </FormItem>
287
- )}
288
- />
289
- </div>
290
-
291
- <div className="grid gap-4 md:grid-cols-2">
292
- <FormField
293
- control={form.control}
294
- name="subscriptionPlan"
295
- render={({ field }) => (
296
- <FormItem>
297
- <FormLabel>Subscription Plan</FormLabel>
298
- <FormControl>
299
- <Select onValueChange={field.onChange} defaultValue={field.value}>
300
- <FormControl>
301
- <SelectTrigger>
302
- <SelectValue />
303
- </SelectTrigger>
304
- </FormControl>
305
- <SelectContent>
306
- {Object.values(SubscriptionPlan).map(plan => (
307
- <SelectItem key={plan} value={plan}>
308
- {standardPlan(plan)}
309
- </SelectItem>
310
- ))}
311
- </SelectContent>
312
- </Select>
313
- </FormControl>
314
- <FormMessage />
315
- </FormItem>
316
- )}
317
- />
318
- <FormField
319
- control={form.control}
320
- name="isActive"
321
- render={({ field }) => (
322
- <FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
323
- <div className="space-y-0.5">
324
- <FormLabel className="text-base">Active Status</FormLabel>
325
- </div>
326
- <FormControl>
327
- <Switch checked={field.value} onCheckedChange={field.onChange} />
328
- </FormControl>
329
- </FormItem>
330
- )}
331
- />
332
- </div>
333
-
334
- <FormField
335
- control={form.control}
336
- name="signedAgreementLink"
337
- render={({ field }) => (
338
- <FormItem>
339
- <FormLabel>Signed Agreement Link</FormLabel>
340
- <FormControl>
341
- <Input
342
- type="url"
343
- placeholder="https://example.com/agreements/contract.pdf"
344
- {...field}
345
- />
346
- </FormControl>
347
- <FormMessage />
348
- </FormItem>
349
- )}
350
- />
351
-
352
- <FormField
353
- control={form.control}
354
- name="msCloudLink"
355
- render={({ field }) => (
356
- <FormItem>
357
- <FormLabel>MS Cloud Link</FormLabel>
358
- <FormControl>
359
- <Input
360
- type="url"
361
- placeholder="https://portal.azure.com/contract-id"
362
- {...field}
363
- />
364
- </FormControl>
365
- <FormMessage />
366
- </FormItem>
367
- )}
368
- />
369
-
370
- <FormField
371
- control={form.control}
372
- name="defaultDocumentType"
373
- render={({ field }) => (
374
- <FormItem>
375
- <FormLabel>Default Document Type</FormLabel>
376
- <Select onValueChange={field.onChange} defaultValue={field.value}>
377
- <FormControl>
378
- <SelectTrigger>
379
- <SelectValue />
380
- </SelectTrigger>
381
- </FormControl>
382
- <SelectContent>
383
- {Object.values(DocumentType).map(type => (
384
- <SelectItem key={type} value={type}>
385
- {getDocumentNameFromType(type)}
386
- </SelectItem>
387
- ))}
388
- </SelectContent>
389
- </Select>
390
- <FormMessage />
391
- </FormItem>
392
- )}
393
- />
394
-
395
- <FormField
396
- control={form.control}
397
- name="defaultRemark"
398
- render={({ field }) => (
399
- <FormItem>
400
- <FormLabel>Default Remark</FormLabel>
401
- <FormControl>
402
- <Textarea
403
- placeholder="Enter default remark for this contract..."
404
- rows={3}
405
- {...field}
406
- />
407
- </FormControl>
408
- <FormMessage />
409
- </FormItem>
410
- )}
411
- />
412
- </div>
413
- <DialogFooter>
414
- <Button type="button" variant="outline" onClick={() => setIsDialogOpen(false)}>
415
- Cancel
416
- </Button>
417
- <Button type="submit">
418
- {editingContract ? 'Update Contract' : 'Create Contract'}
419
- </Button>
420
- </DialogFooter>
421
- </form>
422
- </Form>
423
- </DialogContent>
424
- </Dialog>
425
- );
426
- }
@@ -1,276 +0,0 @@
1
- import { useCallback, useEffect, useState } from 'react';
2
- import { Plus, X } from 'lucide-react';
3
- import { useForm } from 'react-hook-form';
4
- import { z } from 'zod';
5
- import { Button } from '@/components/ui/button.js';
6
- import {
7
- Dialog,
8
- DialogContent,
9
- DialogDescription,
10
- DialogFooter,
11
- DialogHeader,
12
- DialogTitle,
13
- DialogTrigger,
14
- } from '@/components/ui/dialog.js';
15
- import {
16
- Form,
17
- FormControl,
18
- FormField,
19
- FormItem,
20
- FormLabel,
21
- FormMessage,
22
- } from '@/components/ui/form.js';
23
- import { Input } from '@/components/ui/input.js';
24
- import {
25
- Select,
26
- SelectContent,
27
- SelectItem,
28
- SelectTrigger,
29
- SelectValue,
30
- } from '@/components/ui/select.js';
31
- import { DocumentType } from '@/gql/graphql.js';
32
- import { getDocumentNameFromType } from '@/helpers/index.js';
33
- import { useInsertClient } from '@/hooks/use-insert-client.js';
34
- import { useUpdateClient } from '@/hooks/use-update-client.js';
35
- import { zodResolver } from '@hookform/resolvers/zod';
36
- import { Badge } from '../ui/badge';
37
-
38
- const clientFormSchema = z.object({
39
- id: z.uuid().optional(),
40
- emails: z.array(z.email()).optional(),
41
- generatedDocumentType: z.enum(Object.values(DocumentType)),
42
- greenInvoiceId: z.uuid().optional(),
43
- hiveId: z.string().optional(),
44
- });
45
-
46
- export type ClientFormValues = z.infer<typeof clientFormSchema>;
47
-
48
- interface Props {
49
- businessId: string;
50
- client?: ClientFormValues | null;
51
- onDone?: () => void;
52
- }
53
-
54
- export function ModifyClientDialog({ client, businessId, onDone }: Props) {
55
- const [isDialogOpen, setIsDialogOpen] = useState(false);
56
- const [editingClient, setEditingClient] = useState<ClientFormValues | null>(null);
57
-
58
- const { updateClient } = useUpdateClient();
59
- const { insertClient } = useInsertClient();
60
-
61
- const [newEmail, setNewEmail] = useState('');
62
-
63
- const newClientDefaultValues: ClientFormValues = {
64
- id: businessId,
65
- generatedDocumentType: DocumentType.Proforma,
66
- emails: [],
67
- };
68
-
69
- const form = useForm<ClientFormValues>({
70
- resolver: zodResolver(clientFormSchema),
71
- defaultValues: client || newClientDefaultValues,
72
- });
73
-
74
- useEffect(() => {
75
- if (client) {
76
- setEditingClient(client);
77
- form.reset({
78
- emails: client.emails,
79
- greenInvoiceId: client.greenInvoiceId,
80
- hiveId: client.hiveId,
81
- generatedDocumentType: client.generatedDocumentType,
82
- id: client.id,
83
- });
84
- setIsDialogOpen(true);
85
- }
86
- }, [client, form]);
87
-
88
- const handleNew = () => {
89
- setEditingClient(null);
90
- form.reset(newClientDefaultValues);
91
- setIsDialogOpen(true);
92
- };
93
-
94
- const addEmail = () => {
95
- if (newEmail.trim()) {
96
- const currentEmails = form.getValues('emails');
97
- form.setValue('emails', [...(currentEmails ?? []), newEmail.trim()], { shouldDirty: true });
98
- setNewEmail('');
99
- }
100
- };
101
-
102
- const removeEmail = (index: number) => {
103
- const currentEmails = form.getValues('emails');
104
- form.setValue(
105
- 'emails',
106
- (currentEmails ?? []).filter((_, i) => i !== index),
107
- { shouldDirty: true },
108
- );
109
- };
110
-
111
- const onSubmit = useCallback(
112
- async (values: ClientFormValues) => {
113
- if (editingClient) {
114
- console.log('[v0] Updating client:', editingClient.id, values);
115
- updateClient({
116
- businessId,
117
- fields: values,
118
- });
119
- } else {
120
- if (!values.greenInvoiceId) {
121
- form.setError('greenInvoiceId', { message: 'Green Invoice ID is required' });
122
- return;
123
- }
124
- console.log('[v0] Creating new client:', values);
125
- insertClient({
126
- fields: {
127
- ...values,
128
- greenInvoiceId: values.greenInvoiceId!,
129
- businessId,
130
- },
131
- });
132
- }
133
- setIsDialogOpen(false);
134
- setEditingClient(null);
135
- onDone?.();
136
- },
137
- [editingClient, onDone, updateClient, businessId, insertClient, form],
138
- );
139
-
140
- return (
141
- <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
142
- <DialogTrigger asChild>
143
- <Button size="sm" onClick={handleNew}>
144
- <Plus className="h-4 w-4 mr-2" />
145
- New Client
146
- </Button>
147
- </DialogTrigger>
148
- <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
149
- <DialogHeader>
150
- <DialogTitle>{editingClient ? 'Edit Client' : 'Create New Client'}</DialogTitle>
151
- <DialogDescription>
152
- {editingClient ? 'Update client details' : 'Add a new client with all required details'}
153
- </DialogDescription>
154
- </DialogHeader>
155
- <Form {...form}>
156
- <form onSubmit={form.handleSubmit(onSubmit)}>
157
- <div className="grid gap-4 py-4">
158
- <div className="grid gap-4 md:grid-cols-2">
159
- <FormField
160
- control={form.control}
161
- name="emails"
162
- render={({ field }) => (
163
- <FormItem>
164
- <FormLabel>Emails</FormLabel>
165
- <div className="flex gap-2">
166
- <Input
167
- placeholder="Add email..."
168
- value={newEmail}
169
- onChange={e => setNewEmail(e.target.value)}
170
- onKeyDown={e => {
171
- if (e.key === 'Enter') {
172
- e.preventDefault();
173
- addEmail();
174
- }
175
- }}
176
- />
177
- <Button type="button" size="sm" onClick={addEmail}>
178
- <Plus className="h-4 w-4" />
179
- </Button>
180
- </div>
181
- <div className="flex flex-wrap gap-2">
182
- {field.value?.map((email, index) => (
183
- <Badge key={index} variant="secondary" className="gap-1">
184
- {email}
185
- <Button
186
- variant="ghost"
187
- size="icon"
188
- className="p-0 size-3"
189
- onClick={() => removeEmail(index)}
190
- >
191
- <X className="size-3 cursor-pointer" />
192
- </Button>
193
- </Badge>
194
- ))}
195
- </div>
196
- <FormMessage />
197
- </FormItem>
198
- )}
199
- />
200
-
201
- <FormField
202
- control={form.control}
203
- name="generatedDocumentType"
204
- render={({ field }) => (
205
- <FormItem>
206
- <FormLabel>Default Document Type</FormLabel>
207
- <Select onValueChange={field.onChange} defaultValue={field.value}>
208
- <FormControl>
209
- <SelectTrigger>
210
- <SelectValue />
211
- </SelectTrigger>
212
- </FormControl>
213
- <SelectContent>
214
- {Object.values(DocumentType).map(type => (
215
- <SelectItem key={type} value={type}>
216
- {getDocumentNameFromType(type)}
217
- </SelectItem>
218
- ))}
219
- </SelectContent>
220
- </Select>
221
- <FormMessage />
222
- </FormItem>
223
- )}
224
- />
225
-
226
- <FormField
227
- control={form.control}
228
- name="greenInvoiceId"
229
- render={({ field }) => (
230
- <FormItem>
231
- <FormLabel>Green Invoice ID</FormLabel>
232
- <FormControl>
233
- <Input
234
- type="text"
235
- placeholder="Enter Green Invoice ID"
236
- {...field}
237
- required={!editingClient}
238
- />
239
- </FormControl>
240
- <FormMessage />
241
- </FormItem>
242
- )}
243
- />
244
-
245
- <FormField
246
- control={form.control}
247
- name="hiveId"
248
- render={({ field }) => (
249
- <FormItem>
250
- <FormLabel>Hive ID</FormLabel>
251
- <FormControl>
252
- <Input
253
- type="text"
254
- placeholder="Enter Hive ID"
255
- {...field}
256
- required={!editingClient}
257
- />
258
- </FormControl>
259
- <FormMessage />
260
- </FormItem>
261
- )}
262
- />
263
- </div>
264
- </div>
265
- <DialogFooter>
266
- <Button type="button" variant="outline" onClick={() => setIsDialogOpen(false)}>
267
- Cancel
268
- </Button>
269
- <Button type="submit">{editingClient ? 'Update Client' : 'Create Client'}</Button>
270
- </DialogFooter>
271
- </form>
272
- </Form>
273
- </DialogContent>
274
- </Dialog>
275
- );
276
- }