Skip to content

Commit cf0560e

Browse files
resolved request 1-4
1 parent 10514ea commit cf0560e

3 files changed

Lines changed: 141 additions & 66 deletions

File tree

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
"start": "next start"
1111
},
1212
"dependencies": {
13+
"@dnd-kit/core": "^6.3.1",
14+
"@dnd-kit/sortable": "^10.0.0",
15+
"@dnd-kit/utilities": "^3.2.2",
1316
"@radix-ui/react-accordion": "^1.2.4",
1417
"@radix-ui/react-dialog": "^1.1.7",
1518
"@radix-ui/react-dropdown-menu": "^2.1.16",

pnpm-lock.yaml

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/upload/page.tsx

Lines changed: 82 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import {
2222
horizontalListSortingStrategy,
2323
} from "@dnd-kit/sortable";
2424
import { CSS } from "@dnd-kit/utilities";
25+
import Dropzone from "react-dropzone";
26+
import { Upload, XIcon } from "lucide-react";
27+
2528

2629
interface APIResponse {
2730
status: string;
@@ -257,57 +260,54 @@ export default function Page() {
257260
}
258261
};
259262

260-
return (
263+
return (
261264
<main className="mx-auto max-w-3xl px-4 py-8">
262265
<div className="flex h-[calc(100vh-85px)] flex-col justify-center px-6 font-play">
263266
<div className="2xl:my-15 flex flex-col items-center">
264267
{previews.length === 0 && (
265268
<fieldset className="mb-4 w-full max-w-md rounded-lg border-2 border-gray-300 p-4 pr-8">
266269
<div className="flex w-full flex-col 2xl:gap-y-4">
267270
<div>
268-
<section
269-
{...getRootProps()}
270-
className={`my-2 -mr-2 cursor-pointer rounded-2xl border-2 ${
271-
isDragging || isGlobalDragging
272-
? "border-solid border-[#6D28D9] bg-purple-50 dark:bg-[#130E1F]"
273-
: "border-dashed border-gray-300"
274-
} p-8 text-center transition-all duration-200`}
275-
onDragEnter={() => setIsDragging(true)}
276-
onDragLeave={() => setIsDragging(false)}
271+
<Dropzone
272+
onDrop={onDrop}
273+
accept={{
274+
'image/*': ['.jpeg', '.jpg', '.png', '.gif', '.bmp', '.webp'],
275+
'application/pdf': ['.pdf']
276+
}}
277+
multiple={true}
277278
>
278-
<input {...getInputProps()} />
279-
{isDragging || isGlobalDragging ? (
280-
<div className="flex flex-col items-center">
281-
<p className="text-lg font-medium text-[#6D28D9]">
282-
Drop files here
283-
</p>
284-
<svg
285-
className="mt-2 h-10 w-10 animate-bounce text-[#6D28D9]"
286-
fill="none"
287-
stroke="currentColor"
288-
strokeWidth="2"
289-
viewBox="0 0 24 24"
279+
{({ getRootProps, getInputProps, isDragActive }) => (
280+
<section
281+
{...getRootProps()}
282+
className={`my-2 -mr-2 cursor-pointer rounded-2xl border-2 ${
283+
isDragActive || isGlobalDragging
284+
? "border-solid border-[#6D28D9] bg-purple-50 dark:bg-[#130E1F]"
285+
: "border-dashed border-gray-300"
286+
} p-8 text-center transition-all duration-200`}
287+
>
288+
<input {...getInputProps()} />
289+
{isDragActive || isGlobalDragging ? (
290+
<div className="flex flex-col items-center">
291+
<p className="text-lg font-medium text-[#6D28D9]">
292+
Drop files here
293+
</p>
294+
<Upload className="mt-2 h-10 w-10 animate-bounce text-[#6D28D9]" />
295+
</div>
296+
) : (
297+
<p>
298+
Drag &apos;n&apos; drop some files here, or{" "}
299+
<span className="text-[#6D28D9]">click</span> to select
300+
files
301+
</p>
302+
)}
303+
<div
304+
className={`mt-2 text-xs ${files.length === 0 ? "text-red-500" : "text-gray-600"}`}
290305
>
291-
<path
292-
strokeLinecap="round"
293-
strokeLinejoin="round"
294-
d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5-5m0 0l5 5m-5-5v12"
295-
/>
296-
</svg>
297-
</div>
298-
) : (
299-
<p>
300-
Drag &apos;n&apos; drop some files here, or{" "}
301-
<span className="text-[#6D28D9]">click</span> to select
302-
files
303-
</p>
306+
{files.length} files selected
307+
</div>
308+
</section>
304309
)}
305-
<div
306-
className={`mt-2 text-xs ${files.length === 0 ? "text-red-500" : "text-gray-600"}`}
307-
>
308-
{files.length} files selected
309-
</div>
310-
</section>
310+
</Dropzone>
311311
<label className="mx-2 -mr-2 block text-center text-xs font-medium text-gray-700">
312312
Only Images and PDF are allowed
313313
<sup className="text-red-500">*</sup>
@@ -342,21 +342,23 @@ export default function Page() {
342342
{index + 1}
343343
</span>
344344
</div>
345-
<button
345+
<Button
346346
onClick={() => handleDelete(index)}
347-
className="absolute right-0 top-0 z-10 flex h-10 w-10 items-center justify-center rounded-bl-2xl rounded-tr-2xl bg-pink-800"
347+
variant="destructive"
348+
size="icon"
349+
className="absolute right-0 top-0 z-10 h-10 w-10 rounded-bl-2xl rounded-tr-2xl bg-pink-800 hover:bg-pink-900"
348350
title="Delete"
349351
>
350-
<FiTrash className="h-5 w-5 text-white" />
351-
</button>
352+
<FiTrash className="h-5 w-5" />
353+
</Button>
352354
{item.file.type.startsWith("image/") ? (
353355
<div className="relative h-full w-full">
354356
<Image
355357
src={item.preview}
356358
alt={`Page ${index + 1}`}
357359
fill
358360
className="object-cover"
359-
unoptimized // Since we're using object URLs
361+
unoptimized
360362
/>
361363
</div>
362364
) : (
@@ -370,21 +372,32 @@ export default function Page() {
370372
</div>
371373
</SortablePreview>
372374
))}
373-
<div
374-
className="relative h-20 w-20 cursor-pointer"
375-
{...getRootProps()}
375+
<Dropzone
376+
onDrop={onDrop}
377+
accept={{
378+
'image/*': ['.jpeg', '.jpg', '.png', '.gif', '.bmp', '.webp'],
379+
'application/pdf': ['.pdf']
380+
}}
381+
multiple={true}
376382
>
377-
<input {...getInputProps()} />
378-
<div className="absolute left-4 top-4 h-16 w-16 rounded-2xl bg-violet-950" />
379-
<div className="absolute left-0 top-0 h-10 w-10 rounded-[20px] bg-violet-950" />
380-
<div className="absolute left-1 top-1 h-8 w-8 rounded-[20px] bg-black/50" />
381-
<div className="absolute left-7 top-7 text-2xl text-white">
382-
+
383-
</div>
384-
<div className="absolute left-4 top-3 text-xs font-semibold text-white">
385-
{previews.length}
386-
</div>
387-
</div>
383+
{({ getRootProps, getInputProps }) => (
384+
<div
385+
className="relative h-20 w-20 cursor-pointer"
386+
{...getRootProps()}
387+
>
388+
<input {...getInputProps()} />
389+
<div className="absolute left-4 top-4 h-16 w-16 rounded-2xl bg-violet-950" />
390+
<div className="absolute left-0 top-0 h-10 w-10 rounded-[20px] bg-violet-950" />
391+
<div className="absolute left-1 top-1 h-8 w-8 rounded-[20px] bg-black/50" />
392+
<div className="absolute left-7 top-7 text-2xl text-white">
393+
+
394+
</div>
395+
<div className="absolute left-4 top-3 text-xs font-semibold text-white">
396+
{previews.length}
397+
</div>
398+
</div>
399+
)}
400+
</Dropzone>
388401
</div>
389402
</SortableContext>
390403
</DndContext>
@@ -398,7 +411,8 @@ export default function Page() {
398411
<Button
399412
onClick={handlePrint}
400413
disabled={isUploading || files.length === 0}
401-
className="mt-8 rounded-[40px] bg-violet-950 px-8 py-3 text-xl text-white"
414+
className="mt-8 rounded-[40px] bg-violet-950 px-8 py-3 text-xl text-white hover:bg-violet-800"
415+
size="lg"
402416
>
403417
{isUploading ? "Uploading..." : "Upload"}
404418
</Button>
@@ -408,13 +422,15 @@ export default function Page() {
408422
{zoomIndex !== null && (
409423
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-70">
410424
<div className="relative flex flex-col items-center rounded-lg bg-white p-4 shadow-lg">
411-
<button
425+
<Button
412426
onClick={() => setZoomIndex(null)}
413-
className="absolute right-2 top-2 rounded-full bg-gray-200 p-2 hover:bg-gray-300"
427+
variant="ghost"
428+
size="icon"
429+
className="absolute right-2 top-2 rounded-full bg-gray-200 hover:bg-gray-300"
414430
title="Close"
415431
>
416-
<FiX size={24} />
417-
</button>
432+
<XIcon className="h-6 w-6" />
433+
</Button>
418434
{previews[zoomIndex]?.file.type.startsWith("image/") ? (
419435
<Image
420436
src={previews[zoomIndex].preview}
@@ -441,4 +457,4 @@ export default function Page() {
441457
)}
442458
</main>
443459
);
444-
}
460+
}

0 commit comments

Comments
 (0)