Skip to content

Commit c3ab651

Browse files
authored
Merge pull request #212 from samad13/features/wallet-disconection
wallet dic
2 parents 1ada1be + b7b3d8c commit c3ab651

20 files changed

Lines changed: 387 additions & 102 deletions

File tree

components/escrow/DisputeForm.tsx

Lines changed: 112 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
'use client';
22

3-
import { useState, useRef } from 'react';
3+
import { useState, useRef, type ReactElement, type ChangeEvent } from 'react';
44
import { AlertCircle, Upload, X, CheckCircle2 } from 'lucide-react';
55
import { toast } from 'sonner';
6-
import { useDisputeForm, DisputeFormData, OpenDisputeResponse } from '@/hooks/useDisputeForm';
6+
import {
7+
useDisputeForm,
8+
DisputeFormData,
9+
OpenDisputeResponse,
10+
} from '@/hooks/useDisputeForm';
711

812
interface DisputeFormProps {
913
deliveryId: string;
@@ -15,10 +19,26 @@ interface DisputeFormProps {
1519
type FormStep = 'dispute_reason' | 'evidence' | 'confirmation' | 'success';
1620

1721
const DISPUTE_REASONS = [
18-
{ value: 'damaged_items', label: 'Items Damaged', description: 'Items arrived damaged or broken' },
19-
{ value: 'non_delivery', label: 'Non-Delivery', description: 'Items were not delivered' },
20-
{ value: 'incorrect_items', label: 'Incorrect Items', description: 'Wrong items were delivered' },
21-
{ value: 'other', label: 'Other Issue', description: 'Something else went wrong' },
22+
{
23+
value: 'damaged_items',
24+
label: 'Items Damaged',
25+
description: 'Items arrived damaged or broken',
26+
},
27+
{
28+
value: 'non_delivery',
29+
label: 'Non-Delivery',
30+
description: 'Items were not delivered',
31+
},
32+
{
33+
value: 'incorrect_items',
34+
label: 'Incorrect Items',
35+
description: 'Wrong items were delivered',
36+
},
37+
{
38+
value: 'other',
39+
label: 'Other Issue',
40+
description: 'Something else went wrong',
41+
},
2242
] as const;
2343

2444
/**
@@ -36,14 +56,15 @@ function ConfirmationDialog({
3656
onConfirm: () => void;
3757
onCancel: () => void;
3858
isSubmitting: boolean;
39-
}): JSX.Element {
59+
}): ReactElement {
4060
const overlayRef = useRef<HTMLDivElement>(null);
4161

4262
const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {
4363
if (e.target === overlayRef.current && !isSubmitting) onCancel();
4464
};
4565

46-
const reasonLabel = DISPUTE_REASONS.find(r => r.value === reason)?.label || reason;
66+
const reasonLabel =
67+
DISPUTE_REASONS.find((r) => r.value === reason)?.label || reason;
4768

4869
return (
4970
<div
@@ -59,27 +80,41 @@ function ConfirmationDialog({
5980
<AlertCircle className="h-8 w-8 text-amber-600" />
6081
</div>
6182

62-
<h2 id="confirmation-modal-title" className="text-center text-lg font-semibold text-gray-900 mb-2">
83+
<h2
84+
id="confirmation-modal-title"
85+
className="text-center text-lg font-semibold text-gray-900 mb-2"
86+
>
6387
Confirm Dispute
6488
</h2>
6589
<p className="text-center text-sm text-gray-600 mb-6">
66-
Opening a dispute will freeze the escrow funds during arbitration. Confirm your dispute details below.
90+
Opening a dispute will freeze the escrow funds during arbitration.
91+
Confirm your dispute details below.
6792
</p>
6893

6994
<div className="rounded-xl border border-amber-100 bg-amber-50 p-4 mb-6 space-y-3">
7095
<div>
71-
<p className="text-xs font-semibold text-gray-700 uppercase tracking-wide">Dispute Reason</p>
72-
<p className="text-sm font-medium text-gray-900 mt-1">{reasonLabel}</p>
96+
<p className="text-xs font-semibold text-gray-700 uppercase tracking-wide">
97+
Dispute Reason
98+
</p>
99+
<p className="text-sm font-medium text-gray-900 mt-1">
100+
{reasonLabel}
101+
</p>
73102
</div>
74103
<div>
75-
<p className="text-xs font-semibold text-gray-700 uppercase tracking-wide">Description</p>
76-
<p className="text-sm text-gray-700 mt-1 break-words">{description}</p>
104+
<p className="text-xs font-semibold text-gray-700 uppercase tracking-wide">
105+
Description
106+
</p>
107+
<p className="text-sm text-gray-700 mt-1 break-words">
108+
{description}
109+
</p>
77110
</div>
78111
</div>
79112

80113
<div className="rounded-lg border border-red-200 bg-red-50 p-4 mb-6">
81114
<p className="text-sm text-red-800">
82-
<strong>⚠️ Important:</strong> Your funds will be locked in escrow during arbitration. You will not be able to withdraw them until the dispute is resolved.
115+
<strong>⚠️ Important:</strong> Your funds will be locked in escrow
116+
during arbitration. You will not be able to withdraw them until the
117+
dispute is resolved.
83118
</p>
84119
</div>
85120

@@ -122,27 +157,32 @@ function SuccessView({
122157
}: {
123158
disputeId?: string;
124159
transactionHash?: string;
125-
}): JSX.Element {
160+
}): ReactElement {
126161
return (
127162
<div className="text-center py-12">
128163
<div className="flex h-16 w-16 items-center justify-center rounded-full bg-green-100 mx-auto mb-4">
129164
<CheckCircle2 className="h-8 w-8 text-green-600" />
130165
</div>
131-
<h2 className="text-2xl font-bold text-gray-900 mb-2">Dispute Submitted</h2>
166+
<h2 className="text-2xl font-bold text-gray-900 mb-2">
167+
Dispute Submitted
168+
</h2>
132169
<p className="text-gray-600 mb-6">
133-
Your dispute has been successfully opened. The escrow funds are now frozen.
170+
Your dispute has been successfully opened. The escrow funds are now
171+
frozen.
134172
</p>
135173
{disputeId && (
136174
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4">
137175
<p className="text-sm text-blue-900">
138-
<strong>Dispute ID:</strong> <code className="font-mono">{disputeId}</code>
176+
<strong>Dispute ID:</strong>{' '}
177+
<code className="font-mono">{disputeId}</code>
139178
</p>
140179
</div>
141180
)}
142181
{transactionHash && (
143182
<div className="bg-gray-50 border border-gray-200 rounded-lg p-4">
144183
<p className="text-sm text-gray-700 break-all">
145-
<strong>Transaction:</strong> <code className="font-mono text-xs">{transactionHash}</code>
184+
<strong>Transaction:</strong>{' '}
185+
<code className="font-mono text-xs">{transactionHash}</code>
146186
</p>
147187
</div>
148188
)}
@@ -152,7 +192,7 @@ function SuccessView({
152192

153193
/**
154194
* DisputeForm Component - Multi-step form for opening a delivery dispute
155-
*
195+
*
156196
* Flow:
157197
* 1. Select dispute reason
158198
* 2. Upload evidence files
@@ -164,7 +204,7 @@ export default function DisputeForm({
164204
walletAddress,
165205
onSuccess,
166206
onError,
167-
}: DisputeFormProps): JSX.Element {
207+
}: DisputeFormProps): ReactElement | null {
168208
const {
169209
register,
170210
handleSubmit,
@@ -176,7 +216,9 @@ export default function DisputeForm({
176216

177217
const [currentStep, setCurrentStep] = useState<FormStep>('dispute_reason');
178218
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);
179-
const [successData, setSuccessData] = useState<OpenDisputeResponse | null>(null);
219+
const [successData, setSuccessData] = useState<OpenDisputeResponse | null>(
220+
null
221+
);
180222
const fileInputRef = useRef<HTMLInputElement>(null);
181223

182224
const selectedReason = watch('reason');
@@ -192,9 +234,11 @@ export default function DisputeForm({
192234
return;
193235
}
194236

195-
const validFiles = files.filter(file => {
237+
const validFiles = files.filter((file) => {
196238
if (!file.type.startsWith('image/') && file.type !== 'application/pdf') {
197-
toast.error(`${file.name} is not a supported format. Use images or PDF.`);
239+
toast.error(
240+
`${file.name} is not a supported format. Use images or PDF.`
241+
);
198242
return false;
199243
}
200244
if (file.size > 10 * 1024 * 1024) {
@@ -255,14 +299,21 @@ export default function DisputeForm({
255299
return (
256300
<div className="w-full max-w-2xl mx-auto p-6">
257301
<div className="mb-8">
258-
<h1 className="text-3xl font-bold text-gray-900 mb-2">Open a Dispute</h1>
259-
<p className="text-gray-600">Step 1 of 3: Select the reason for your dispute</p>
302+
<h1 className="text-3xl font-bold text-gray-900 mb-2">
303+
Open a Dispute
304+
</h1>
305+
<p className="text-gray-600">
306+
Step 1 of 3: Select the reason for your dispute
307+
</p>
260308
</div>
261309

262310
<form onSubmit={onSubmit} className="space-y-6">
263311
{/* Transaction ID */}
264312
<div>
265-
<label htmlFor="transactionId" className="block text-sm font-medium text-gray-700 mb-2">
313+
<label
314+
htmlFor="transactionId"
315+
className="block text-sm font-medium text-gray-700 mb-2"
316+
>
266317
Transaction ID <span className="text-red-500">*</span>
267318
</label>
268319
<input
@@ -278,7 +329,9 @@ export default function DisputeForm({
278329
aria-invalid={!!errors.transactionId}
279330
/>
280331
{errors.transactionId && (
281-
<p className="mt-1 text-sm text-red-600" role="alert">{errors.transactionId.message}</p>
332+
<p className="mt-1 text-sm text-red-600" role="alert">
333+
{errors.transactionId.message}
334+
</p>
282335
)}
283336
</div>
284337

@@ -305,19 +358,26 @@ export default function DisputeForm({
305358
/>
306359
<div className="ml-3">
307360
<p className="font-medium text-gray-900">{reason.label}</p>
308-
<p className="text-sm text-gray-600">{reason.description}</p>
361+
<p className="text-sm text-gray-600">
362+
{reason.description}
363+
</p>
309364
</div>
310365
</label>
311366
))}
312367
</div>
313368
{errors.reason && (
314-
<p className="mt-2 text-sm text-red-600" role="alert">{errors.reason.message}</p>
369+
<p className="mt-2 text-sm text-red-600" role="alert">
370+
{errors.reason.message}
371+
</p>
315372
)}
316373
</div>
317374

318375
{/* Description */}
319376
<div>
320-
<label htmlFor="description" className="block text-sm font-medium text-gray-700 mb-2">
377+
<label
378+
htmlFor="description"
379+
className="block text-sm font-medium text-gray-700 mb-2"
380+
>
321381
Description <span className="text-red-500">*</span>
322382
</label>
323383
<textarea
@@ -334,9 +394,13 @@ export default function DisputeForm({
334394
/>
335395
<div className="mt-2 flex justify-between">
336396
{errors.description && (
337-
<p className="text-sm text-red-600" role="alert">{errors.description.message}</p>
397+
<p className="text-sm text-red-600" role="alert">
398+
{errors.description.message}
399+
</p>
338400
)}
339-
<p className="text-xs text-gray-500">{description?.length || 0}/500</p>
401+
<p className="text-xs text-gray-500">
402+
{description?.length || 0}/500
403+
</p>
340404
</div>
341405
</div>
342406

@@ -367,15 +431,20 @@ export default function DisputeForm({
367431
return (
368432
<div className="w-full max-w-2xl mx-auto p-6">
369433
<div className="mb-8">
370-
<h1 className="text-3xl font-bold text-gray-900 mb-2">Upload Evidence</h1>
371-
<p className="text-gray-600">Step 2 of 3: Attach photo evidence to support your dispute</p>
434+
<h1 className="text-3xl font-bold text-gray-900 mb-2">
435+
Upload Evidence
436+
</h1>
437+
<p className="text-gray-600">
438+
Step 2 of 3: Attach photo evidence to support your dispute
439+
</p>
372440
</div>
373441

374442
<form onSubmit={onSubmit} className="space-y-6">
375443
{/* File Upload */}
376444
<div>
377445
<label className="block text-sm font-medium text-gray-700 mb-3">
378-
Evidence Files <span className="text-gray-500">(optional, max 5 files)</span>
446+
Evidence Files{' '}
447+
<span className="text-gray-500">(optional, max 5 files)</span>
379448
</label>
380449

381450
<div className="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center hover:border-blue-500 transition">
@@ -406,14 +475,18 @@ export default function DisputeForm({
406475
{/* Uploaded Files List */}
407476
{uploadedFiles.length > 0 && (
408477
<div className="mt-4 space-y-2">
409-
<p className="text-sm font-medium text-gray-900">Uploaded Files ({uploadedFiles.length})</p>
478+
<p className="text-sm font-medium text-gray-900">
479+
Uploaded Files ({uploadedFiles.length})
480+
</p>
410481
{uploadedFiles.map((file, index) => (
411482
<div
412483
key={`${file.name}-${index}`}
413484
className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200"
414485
>
415486
<div className="flex-1 min-w-0">
416-
<p className="text-sm font-medium text-gray-900 truncate">{file.name}</p>
487+
<p className="text-sm font-medium text-gray-900 truncate">
488+
{file.name}
489+
</p>
417490
<p className="text-xs text-gray-500">
418491
{(file.size / 1024 / 1024).toFixed(2)} MB
419492
</p>

0 commit comments

Comments
 (0)