diff --git a/src/app/convert/page.tsx b/src/app/convert/page.tsx index a31fe6d..ad9df50 100644 --- a/src/app/convert/page.tsx +++ b/src/app/convert/page.tsx @@ -1,15 +1,15 @@ -'use client'; +"use client"; -import { useState } from 'react'; -import { AnimatePresence, motion } from 'framer-motion'; -import Link from 'next/link'; -import { DropZone } from '@/components/DropZone'; -import { FileRow } from '@/components/FileRow'; -import { PreviewModal } from '@/components/PreviewModal'; -import { useFileUpload } from '@/hooks/useFileUpload'; -import { useConversion } from '@/hooks/useConversion'; -import { formatFileSize } from '@/lib/utils'; -import { UploadedFile } from '@/types'; +import { useState } from "react"; +import { AnimatePresence, motion } from "framer-motion"; +import Link from "next/link"; +import { DropZone } from "@/components/DropZone"; +import { FileRow } from "@/components/FileRow"; +import { PreviewModal } from "@/components/PreviewModal"; +import { useFileUpload } from "@/hooks/useFileUpload"; +import { useConversion } from "@/hooks/useConversion"; +import { formatFileSize } from "@/lib/utils"; +import { UploadedFile } from "@/types"; /* Number of ghost rows to show below real files */ const MIN_VISIBLE_ROWS = 8; @@ -31,20 +31,17 @@ export default function ConvertPage() { clearAll, } = useFileUpload(); - const { - isConverting, - convertAll, - downloadFile, - downloadAllAsZip, - } = useConversion(updateFile); + const { isConverting, convertAll, downloadFile, downloadAllAsZip } = + useConversion(updateFile); const [previewFile, setPreviewFile] = useState(null); const hasFiles = files.length > 0; const convertableCount = files.filter( - (f) => f.targetFormat && f.status !== 'done' && f.availableFormats.length > 0 + (f) => + f.targetFormat && f.status !== "done" && f.availableFormats.length > 0, ).length; - const completedCount = files.filter((f) => f.status === 'done').length; + const completedCount = files.filter((f) => f.status === "done").length; const totalSize = files.reduce((acc, f) => acc + f.size, 0); const ghostRowCount = Math.max(0, MIN_VISIBLE_ROWS - files.length); @@ -64,9 +61,9 @@ export default function ConvertPage() { /> {/* Finder Window — the entire converter lives inside this */} -
+
{/* Traffic lights */} - +
@@ -82,11 +82,32 @@ export default function ConvertPage() { {/* Navigation arrows — hidden on mobile */}
- - + + + +
- + + +
@@ -94,9 +115,15 @@ export default function ConvertPage() {
{/* eslint-disable-next-line @next/next/no-img-element */} - Transmute - {'\u203A'} - Converter + + Transmute + + + {"\u203A"} + + + Converter +
{/* Right side — version + add files button */} @@ -110,7 +137,15 @@ export default function ConvertPage() { onClick={openFilePicker} title="Add files" > - + @@ -123,7 +158,8 @@ export default function ConvertPage() {
- {files.length} file{files.length !== 1 ? 's' : ''} + {files.length}{" "} + file{files.length !== 1 ? "s" : ""}
@@ -133,7 +169,8 @@ export default function ConvertPage() {
- {completedCount} converted + {completedCount}{" "} + converted )}
@@ -158,12 +195,11 @@ export default function ConvertPage() { {/* ─ Content area (scrollable) ─ */}
{/* Drop zone (empty state) */} {!hasFiles && ( @@ -189,7 +225,15 @@ export default function ConvertPage() { exit={{ opacity: 0 }} >
- + Drop to add files @@ -220,7 +264,7 @@ export default function ConvertPage() { {Array.from({ length: ghostRowCount }).map((_, i) => (
= 4 ? 'hidden sm:flex' : ''}`} + className={`flex items-center px-3 sm:px-4 py-2.5 ${i === 0 ? "cursor-pointer hover:bg-[#fafafa] active:bg-[#fafafa] transition-colors" : ""} ${i >= 4 ? "hidden sm:flex" : ""}`} onClick={i === 0 ? openFilePicker : undefined} > {/* Ghost icon */} @@ -229,25 +273,49 @@ export default function ConvertPage() {
{i === 0 ? ( - - + + - Drop files here or click to browse - Tap to add files + + Drop files here or click to browse + + + Tap to add files + ) : ( -
+
)}
{/* Ghost columns — desktop only */}
- {i < 2 &&
} + {i < 2 && ( +
+ )}
- {i < 2 &&
} + {i < 2 && ( +
+ )}
- {i < 1 &&
} + {i < 1 && ( +
+ )}
))} @@ -267,23 +335,37 @@ export default function ConvertPage() { - Converting... + + Converting... + ) : completedCount === files.length && completedCount > 0 ? ( <>
- All done + + All done + ) : ( {convertableCount > 0 ? ( <> - {convertableCount} ready to convert - {convertableCount} ready + + {convertableCount} ready to convert + + + {convertableCount} ready + - ) : 'Select formats'} + ) : ( + "Select formats" + )} )}
@@ -297,7 +379,14 @@ export default function ConvertPage() { initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1 }} > - + ZIP @@ -305,13 +394,21 @@ export default function ConvertPage() { )} Converting... @@ -319,10 +416,22 @@ export default function ConvertPage() { ) : ( <> - - + + - Transmute{convertableCount > 0 ? ` (${convertableCount})` : ''} + Transmute + {convertableCount > 0 ? ` (${convertableCount})` : ""} )} diff --git a/src/components/DropZone.tsx b/src/components/DropZone.tsx index 79fd012..7fb5b04 100644 --- a/src/components/DropZone.tsx +++ b/src/components/DropZone.tsx @@ -1,7 +1,7 @@ -'use client'; +"use client"; -import { motion } from 'framer-motion'; -import React from 'react'; +import { motion } from "framer-motion"; +import React from "react"; interface DropZoneProps { isDragging: boolean; @@ -26,33 +26,39 @@ export function DropZone({ // Empty state inside Finder window return (
{/* Upload icon */} - + -
-

- {isDragging ? 'Release to add' : 'Drop files here'} +
+

+ {isDragging ? "Release to add" : "Drop files here"}

-

+

{isDragging - ? 'Your files are ready for transformation' - : 'Images, documents, audio, video, data \u2014 all formats welcome'} + ? "Your files are ready for transformation" + : "Images, documents, audio, video, data — all formats welcome"}

- + Browse files -

+

70+ formats — 100% client-side