From 09503543b21bb504693d5337a820991071a05656 Mon Sep 17 00:00:00 2001 From: Barbara Peric Date: Thu, 6 Nov 2025 11:33:17 +0000 Subject: [PATCH 01/31] Update upload steps --- .../upload/car-upload-and-ipni-card.tsx | 6 ++-- .../upload/progress-card-combined.tsx | 30 ------------------- src/hooks/use-first-stage-state.ts | 22 -------------- src/utils/upload/step-utils.ts | 7 ++--- src/utils/upload/upload-progress.ts | 7 +---- 5 files changed, 6 insertions(+), 66 deletions(-) delete mode 100644 src/components/upload/progress-card-combined.tsx delete mode 100644 src/hooks/use-first-stage-state.ts diff --git a/src/components/upload/car-upload-and-ipni-card.tsx b/src/components/upload/car-upload-and-ipni-card.tsx index c7784e4..ed24a52 100644 --- a/src/components/upload/car-upload-and-ipni-card.tsx +++ b/src/components/upload/car-upload-and-ipni-card.tsx @@ -8,7 +8,6 @@ import { Card } from '../ui/card.tsx' import { DownloadButton } from '../ui/download-button.tsx' import { TextWithCopyToClipboard } from '../ui/text-with-copy-to-clipboard.tsx' import { ProgressCard } from './progress-card.tsx' -import { ProgressCardCombined } from './progress-card-combined.tsx' interface CarUploadAndIpniCardProps { stepStates: StepState[] @@ -31,7 +30,7 @@ export const CarUploadAndIpniCard = ({ stepStates, cid, fileName }: CarUploadAnd const { hasIpniAnnounceFailure } = uploadOutcome - const { announcingCidsStep, uploadingCarStep } = useStepStates(stepStates) + const { creatingCarStep, uploadingCarStep, announcingCidsStep } = useStepStates(stepStates) const shouldShowCidCard = uploadingCarStep?.status === 'completed' && @@ -59,7 +58,8 @@ export const CarUploadAndIpniCard = ({ stepStates, cid, fileName }: CarUploadAnd return ( <> - + {creatingCarStep && } + {uploadingCarStep && } {announcingCidsStep && } ) diff --git a/src/components/upload/progress-card-combined.tsx b/src/components/upload/progress-card-combined.tsx deleted file mode 100644 index b8e22ce..0000000 --- a/src/components/upload/progress-card-combined.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { useFirstStageState } from '@/hooks/use-first-stage-state.ts' -import { useStepStates } from '@/hooks/use-step-states.ts' -import type { StepState } from '../../types/upload/step.ts' -import { getStepEstimatedTime, getStepLabel } from '../../utils/upload/step-utils.ts' -import { Card } from '../ui/card.tsx' -import { ProgressBar } from '../ui/progress-bar.tsx' - -interface ProgressCardCombinedProps { - stepStates: Array -} - -function ProgressCardCombined({ stepStates }: ProgressCardCombinedProps) { - const { creatingCarStep } = useStepStates(stepStates) - const { progress, status } = useFirstStageState(stepStates) - - if (!creatingCarStep) return null - - return ( - - - {status === 'in-progress' && } - - ) -} - -export { ProgressCardCombined } diff --git a/src/hooks/use-first-stage-state.ts b/src/hooks/use-first-stage-state.ts deleted file mode 100644 index 4c4f1f5..0000000 --- a/src/hooks/use-first-stage-state.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { useMemo } from 'react' -import type { StepState } from '../types/upload/step.ts' -import { getFirstStageProgress, getFirstStageStatus } from '../utils/upload/upload-progress.ts' - -type FirstStageStateProps = { - progress: StepState['progress'] - status: StepState['status'] -} - -/** - * Hook that calculates the combined progress and status for the first stage. - * Aggregates creating-car, checking-readiness, and uploading-car steps. - */ - -export function useFirstStageState(stepStates: StepState[]): FirstStageStateProps { - return useMemo(() => { - const progress = getFirstStageProgress(stepStates) - const status = getFirstStageStatus(stepStates) - - return { progress, status } - }, [stepStates]) -} diff --git a/src/utils/upload/step-utils.ts b/src/utils/upload/step-utils.ts index 6efe87a..5253d3f 100644 --- a/src/utils/upload/step-utils.ts +++ b/src/utils/upload/step-utils.ts @@ -4,8 +4,9 @@ export function getStepLabel(step: StepState['step']) { switch (step) { case 'creating-car': case 'checking-readiness': + return 'Creating CAR file' case 'uploading-car': - return 'Preparing service, creating CAR file, and uploading to the Filecoin SP' + return 'Uploading to Filecoin SP' case 'announcing-cids': return 'Announcing IPFS CIDs to IPNI' case 'finalizing-transaction': @@ -15,10 +16,6 @@ export function getStepLabel(step: StepState['step']) { export function getStepEstimatedTime(step: StepState['step']) { switch (step) { - case 'creating-car': - case 'checking-readiness': - case 'uploading-car': - return 'Estimated time: ~30 seconds' case 'announcing-cids': return 'Estimated time: ~30 seconds' case 'finalizing-transaction': diff --git a/src/utils/upload/upload-progress.ts b/src/utils/upload/upload-progress.ts index dbfe435..6326bb1 100644 --- a/src/utils/upload/upload-progress.ts +++ b/src/utils/upload/upload-progress.ts @@ -31,12 +31,7 @@ function getFirstStageState(stepStates: StepState[]) { ) } -// Calculate combined progress for the first stage (creating CAR + checking readiness + uploading) -export function getFirstStageProgress(stepStates: StepState[]) { - const { creatingCar, checkingReadiness, uploadingCar } = getFirstStageState(stepStates) - const total = creatingCar.progress + checkingReadiness.progress + uploadingCar.progress - return Math.round(total / 3) -} + export function getFirstStageStatus(stepStates: StepState[]) { const firstStageState = getFirstStageState(stepStates) From d8a690d08ae81d20b2fd54f1ad630ac1317d6b9a Mon Sep 17 00:00:00 2001 From: Barbara Peric Date: Thu, 6 Nov 2025 12:57:32 +0000 Subject: [PATCH 02/31] refactor: remove unused CSS and enhance focus styles across components * Deleted app.css as it was no longer needed. * Updated various components to include focus styles for better accessibility, including DownloadButton, TextLink, and ButtonBase. * Cleaned up console log in PillBalance and improved styling in PillWrapper for focus states. --- src/app.css | 7 ------- src/app.tsx | 1 - src/components/ui/button/button-base.tsx | 2 +- src/components/ui/button/button-link.tsx | 2 +- src/components/ui/download-button.tsx | 2 +- src/components/ui/link.tsx | 2 +- src/components/ui/pill/pill-balance.tsx | 6 ++---- src/components/ui/pill/pill-wrapper.tsx | 4 ++-- src/components/ui/text-with-copy-to-clipboard.tsx | 2 +- 9 files changed, 9 insertions(+), 19 deletions(-) delete mode 100644 src/app.css diff --git a/src/app.css b/src/app.css deleted file mode 100644 index 0834464..0000000 --- a/src/app.css +++ /dev/null @@ -1,7 +0,0 @@ -.card { - padding: var(--spacing-lg); -} - -.read-the-docs { - color: var(--color-text-muted); -} diff --git a/src/app.tsx b/src/app.tsx index f0be3aa..09a9715 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,4 +1,3 @@ -import './app.css' import Content from './components/layout/content.tsx' import { Header } from './components/layout/header.tsx' import { Sidebar } from './components/layout/sidebar.tsx' diff --git a/src/components/ui/button/button-base.tsx b/src/components/ui/button/button-base.tsx index ddb1ab0..7fac67c 100644 --- a/src/components/ui/button/button-base.tsx +++ b/src/components/ui/button/button-base.tsx @@ -2,7 +2,7 @@ import { cva, type VariantProps } from 'class-variance-authority' import { cn } from '@/utils/cn.ts' const buttonVariants = cva( - 'inline-flex items-center justify-center font-medium transition-colors w-full cursor-pointer', + 'inline-flex items-center justify-center font-medium transition-colors w-full cursor-pointer focus:brand-outline', { variants: { variant: { diff --git a/src/components/ui/button/button-link.tsx b/src/components/ui/button/button-link.tsx index ad710f5..b872b23 100644 --- a/src/components/ui/button/button-link.tsx +++ b/src/components/ui/button/button-link.tsx @@ -7,7 +7,7 @@ type ButtonLinkProps = Omit & { function ButtonLink({ href, children, disabled, variant = 'secondary', ...props }: ButtonLinkProps) { return ( - + {children} diff --git a/src/components/ui/download-button.tsx b/src/components/ui/download-button.tsx index 79308ab..4f2840e 100644 --- a/src/components/ui/download-button.tsx +++ b/src/components/ui/download-button.tsx @@ -10,7 +10,7 @@ function DownloadButton({ href, title = 'Download' }: DownloadButtonProps) { return ( diff --git a/src/components/ui/link.tsx b/src/components/ui/link.tsx index 5967a79..fca9170 100644 --- a/src/components/ui/link.tsx +++ b/src/components/ui/link.tsx @@ -4,7 +4,7 @@ type TextLinkProps = { } function TextLink(props: TextLinkProps) { - return + return } type ExternalLinkProps = Omit, 'rel' | 'target'> diff --git a/src/components/ui/pill/pill-balance.tsx b/src/components/ui/pill/pill-balance.tsx index 92de070..9b439f8 100644 --- a/src/components/ui/pill/pill-balance.tsx +++ b/src/components/ui/pill/pill-balance.tsx @@ -1,5 +1,5 @@ -import type { FilLabel, UsdfcLabel } from '../../../types/network.ts' -import { PillWrapper } from './pill-wrapper.tsx' +import type { FilLabel, UsdfcLabel } from '../../../types/network.ts'; +import { PillWrapper } from './pill-wrapper.tsx'; type PillBalanceProps = { balances: Array<{ label: FilLabel | UsdfcLabel; value: string }> @@ -8,8 +8,6 @@ type PillBalanceProps = { function PillBalance({ balances }: PillBalanceProps) { const ariaLabel = `Balances: ${balances.map((balance) => `${balance.value} ${balance.label}`).join(', ')}` - console.log(balances) - return (
diff --git a/src/components/ui/pill/pill-wrapper.tsx b/src/components/ui/pill/pill-wrapper.tsx index 4515420..fb9c08b 100644 --- a/src/components/ui/pill/pill-wrapper.tsx +++ b/src/components/ui/pill/pill-wrapper.tsx @@ -8,12 +8,12 @@ type PillWrapperProps = { function PillWrapper({ children, ariaLabel, href }: PillWrapperProps) { return ( -
+
{children} {href && ( {ariaLabel} diff --git a/src/components/ui/text-with-copy-to-clipboard.tsx b/src/components/ui/text-with-copy-to-clipboard.tsx index 0f470e1..c16a2b3 100644 --- a/src/components/ui/text-with-copy-to-clipboard.tsx +++ b/src/components/ui/text-with-copy-to-clipboard.tsx @@ -22,7 +22,7 @@ function TextWithCopyToClipboard({ text, href }: TextWithCopyToClipboardProps) { {href ? {text} : {text}} + + {error} + + + ) +} From b39282780de1dbbc486b5fa5da2cf81407d1add8 Mon Sep 17 00:00:00 2001 From: Barbara Peric Date: Wed, 5 Nov 2025 14:30:52 +0000 Subject: [PATCH 11/31] refactor: replace hardcoded max file size with constant in DragNDrop and UploadButton components This commit updates the DragNDrop and UploadButton components to use a centralized MAX_FILE_SIZE constant instead of hardcoded values for maximum file size. Additionally, it improves the structure of the UploadButton component by adjusting the layout and error message handling for better user experience. --- src/components/upload/drag-n-drop.tsx | 3 +- src/components/upload/upload-button.tsx | 47 +++++++++++++++---------- src/constants/files.ts | 1 + 3 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 src/constants/files.ts diff --git a/src/components/upload/drag-n-drop.tsx b/src/components/upload/drag-n-drop.tsx index cc9b617..deed756 100644 --- a/src/components/upload/drag-n-drop.tsx +++ b/src/components/upload/drag-n-drop.tsx @@ -1,5 +1,6 @@ import { Root } from '@radix-ui/react-form' import { useState } from 'react' +import { MAX_FILE_SIZE } from '@/constants/files.ts' import { FilePicker } from '../file-picker/index.tsx' import { ButtonBase as Button } from '../ui/button/button-base.tsx' @@ -32,7 +33,7 @@ export default function DragNDrop({ onFileSelected, onUpload, isUploading }: Dra e.preventDefault()}> { setFile(file) if (file && onFileSelected) { diff --git a/src/components/upload/upload-button.tsx b/src/components/upload/upload-button.tsx index 8f2f2c6..99341cd 100644 --- a/src/components/upload/upload-button.tsx +++ b/src/components/upload/upload-button.tsx @@ -1,9 +1,9 @@ -import { Root, FormControl, FormField, FormMessage } from '@radix-ui/react-form' -import { useRef, useState } from 'react' +import { FormControl, FormField, FormMessage, Root } from '@radix-ui/react-form' import { PlusIcon } from 'lucide-react' - -import { ButtonBase as Button } from '../ui/button/button-base.tsx' +import { useRef, useState } from 'react' +import { MAX_FILE_SIZE } from '@/constants/files.ts' import { formatFileSize } from '@/utils/format-file-size.ts' +import { ButtonBase as Button } from '../ui/button/button-base.tsx' interface UploadButtonProps { onUpload: (file: File) => void @@ -16,19 +16,18 @@ export function UploadButton({ onUpload, isUploading = false, accept = ['*'], - maxSize = 200_000_000, + maxSize = MAX_FILE_SIZE, }: UploadButtonProps) { const fileInputRef = useRef(null) const [error, setError] = useState(null) - const handleButtonClick = () => { + function handleButtonClick() { fileInputRef.current?.click() } - const handleFileChange = (e: React.ChangeEvent) => { + function handleFileChange(e: React.ChangeEvent) { const file = e.target.files?.[0] if (file) { - onUpload(file) if (file.size > maxSize) { setError(`File is too large. Maximum size is ${formatFileSize(maxSize)}.`) if (fileInputRef.current) fileInputRef.current.value = '' @@ -42,7 +41,7 @@ export function UploadButton({ } return ( - e.preventDefault()}> + e.preventDefault()}> - - - {error} - +
+ +
+
+ {error && ( + + {error} + + )} +
) } diff --git a/src/constants/files.ts b/src/constants/files.ts new file mode 100644 index 0000000..ee8752a --- /dev/null +++ b/src/constants/files.ts @@ -0,0 +1 @@ +export const MAX_FILE_SIZE = 200_000_000 From 223cc57a565455353a33e7002b93833fd00d78a9 Mon Sep 17 00:00:00 2001 From: Julian Gruber Date: Sat, 8 Nov 2025 16:13:03 +0100 Subject: [PATCH 12/31] chore: fix upload instructions text for clarity (#98) --- src/components/file-picker/upload-instructions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/file-picker/upload-instructions.tsx b/src/components/file-picker/upload-instructions.tsx index 3c27c89..939e585 100644 --- a/src/components/file-picker/upload-instructions.tsx +++ b/src/components/file-picker/upload-instructions.tsx @@ -21,7 +21,7 @@ export function UploadInstructions({ maxSize, ...rest }: UploadInstructionsProps

- Click to upload or drag and drop + Click to upload or drag and drop a file

(Up to {prettyBytes(maxSize)})

From 4f8fb71a7b47a036a3afa6eb0bb3dbded09b5b2e Mon Sep 17 00:00:00 2001 From: Barbara Peric Date: Mon, 10 Nov 2025 10:12:43 +0000 Subject: [PATCH 13/31] style: enhance UI components with improved layout and responsiveness * Updated DashedContainer to include padding for better spacing. * Modified SelectedFile to ensure file name is responsive and breaks words as needed. * Enhanced BadgeStatus with flex-shrink to prevent layout issues. * Adjusted Card and FileInfo components to improve spacing and layout consistency. * Updated TextWithCopyToClipboard to allow truncation of links for better UI handling. * Refactored Spinner to include flex-shrink for consistent sizing across components. * Modified Heading component to accept React nodes for more flexible content rendering. * Updated TextLink to support truncation for long text links. --- .../file-picker/dashed-container.tsx | 2 +- src/components/file-picker/selected-file.tsx | 4 +-- src/components/ui/badge-status.tsx | 31 ++++++++++--------- src/components/ui/card.tsx | 6 ++-- src/components/ui/file-info.tsx | 12 ++++--- src/components/ui/heading.tsx | 2 +- src/components/ui/link.tsx | 14 +++++++-- src/components/ui/spinner.tsx | 2 +- .../ui/text-with-copy-to-clipboard.tsx | 12 +++++-- 9 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/components/file-picker/dashed-container.tsx b/src/components/file-picker/dashed-container.tsx index daa58d0..633c31f 100644 --- a/src/components/file-picker/dashed-container.tsx +++ b/src/components/file-picker/dashed-container.tsx @@ -9,7 +9,7 @@ export function DashedContainer({ className, ...rest }: DashedContainerProps) { {...rest} className={clsx( className, - 'flex h-full w-full items-center justify-center rounded-lg border border-dashed border-zinc-700 bg-zinc-950' + 'flex h-full w-full items-center justify-center rounded-lg border border-dashed border-zinc-700 bg-zinc-950 p-6' )} /> ) diff --git a/src/components/file-picker/selected-file.tsx b/src/components/file-picker/selected-file.tsx index 51734bf..d41c925 100644 --- a/src/components/file-picker/selected-file.tsx +++ b/src/components/file-picker/selected-file.tsx @@ -11,8 +11,8 @@ type SelectedFileProps = { export function SelectedFile({ file, onReset }: SelectedFileProps) { return ( -
-

{file.name}

+
+

{file.name}

+
+ } /> +
+ {/* Sidebar */} {/* Main content */} -
{children}
+
{children}
) } diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index 00d1453..a8edfe1 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -33,19 +33,20 @@ function CardHeader({ title, status, estimatedTime, withSpinner }: CardHeaderPro const showSpinner = isInProgress && withSpinner return ( -
-
- {showSpinner && } - {title} -
+
+
+
+ {showSpinner && } + {title} +
+ +
- -
) } diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 959f46c..b2e3573 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -18,7 +18,7 @@ function Dialog({ content }: DialogProps) { - + {content}