@@ -5,6 +5,7 @@ import { useDropzone } from 'react-dropzone'
55import toast from 'react-hot-toast'
66import { Button } from '@/components/ui/button'
77import axios from 'axios'
8+ import { FiArrowUp , FiArrowDown , FiTrash , FiZoomIn , FiX } from "react-icons/fi"
89
910export default function Page ( ) {
1011 const [ campus ] = useState < 'vellore' | 'chennai' > ( 'vellore' )
@@ -13,6 +14,7 @@ export default function Page() {
1314 const [ isUploading , setIsUploading ] = useState ( false )
1415 const [ isDragging , setIsDragging ] = useState ( false )
1516 const [ isGlobalDragging , setIsGlobalDragging ] = useState ( false )
17+ const [ zoomIndex , setZoomIndex ] = useState < number | null > ( null )
1618
1719 // Handle drag & drop global visual feedback
1820 useEffect ( ( ) => {
@@ -104,63 +106,159 @@ export default function Page() {
104106 setFiles ( newPreviews . map ( p => p . file ) )
105107 }
106108
109+ const handleDelete = ( index : number ) => {
110+ const newPreviews = previews . filter ( ( _ , i ) => i !== index )
111+ setPreviews ( newPreviews )
112+ setFiles ( newPreviews . map ( p => p . file ) )
113+ }
114+
107115 return (
108116 < main className = "max-w-3xl mx-auto px-4 py-8" >
109- < fieldset
110- { ...getRootProps ( ) }
111- className = { `rounded-lg border-2 border-dashed p-6 text-center transition-colors duration-300
112- ${ isDragActive || isDragging || isGlobalDragging ? 'border-primary bg-primary/10' : 'border-muted' }
113- ` }
114- onDragEnter = { ( ) => setIsDragging ( true ) }
115- onDragLeave = { ( ) => setIsDragging ( false ) }
116- >
117- < input { ...getInputProps ( ) } />
118- < p className = "text-lg font-semibold" >
119- { isDragActive || isDragging || isGlobalDragging
120- ? 'Drop your PDFs or images here'
121- : 'Drag & drop PDFs or images here, or click to select' }
122- </ p >
123- < p className = "text-sm text-muted-foreground mt-2" > Max 5MB. PDF, JPG, PNG, GIF supported.</ p >
124- </ fieldset >
125-
126- { previews . length > 0 && (
127- < section className = "mt-6 space-y-4" >
128- { previews . map ( ( item , index ) => (
129- < div key = { index } className = "flex items-center gap-4 border p-4 rounded-md bg-gray-50" >
130- { item . file . type . startsWith ( 'image/' ) ? (
131- < img src = { item . preview } alt = "preview" className = "w-32 h-32 object-cover rounded-md" />
132- ) : (
133- < iframe
134- src = { item . preview }
135- className = "w-32 h-32 border rounded-md"
136- title = { `PDF preview ${ index } ` }
137- />
138- ) }
139- < div className = "flex flex-col gap-2 flex-1" >
140- < p className = "font-semibold text-gray-700 break-words" > { item . file . name } </ p >
141- < div className = "flex gap-2" >
142- < button
143- onClick = { ( ) => reorderFiles ( index , index - 1 ) }
144- disabled = { index === 0 }
145- className = "px-2 py-1 text-sm bg-gray-200 rounded disabled:opacity-50"
117+ < div className = "font-play flex h-[calc(100vh-85px)] flex-col justify-center px-6" >
118+ < div className = "2xl:my-15 flex flex-col items-center" >
119+ < fieldset className = "mb-4 w-full max-w-md rounded-lg border-2 border-gray-300 p-4 pr-8" >
120+ < div className = "flex w-full flex-col 2xl:gap-y-4" >
121+ < div >
122+ < section
123+ { ...getRootProps ( ) }
124+ className = { `my-2 -mr-2 cursor-pointer rounded-2xl border-2 ${
125+ isDragging || isGlobalDragging
126+ ? "border-solid border-[#6D28D9] bg-purple-50 dark:bg-[#130E1F]"
127+ : "border-dashed border-gray-300"
128+ } p-8 text-center transition-all duration-200`}
129+ onDragEnter = { ( ) => setIsDragging ( true ) }
130+ onDragLeave = { ( ) => setIsDragging ( false ) }
131+ >
132+ < input { ...getInputProps ( ) } />
133+ { isDragging || isGlobalDragging ? (
134+ < div className = "flex flex-col items-center" >
135+ < p className = "text-lg font-medium text-[#6D28D9]" >
136+ Drop files here
137+ </ p >
138+ < svg className = "mt-2 h-10 w-10 animate-bounce text-[#6D28D9]" fill = "none" stroke = "currentColor" strokeWidth = "2" viewBox = "0 0 24 24" >
139+ < path strokeLinecap = "round" strokeLinejoin = "round" d = "M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5-5m0 0l5 5m-5-5v12" />
140+ </ svg >
141+ </ div >
142+ ) : (
143+ < p >
144+ Drag 'n' drop some files here, or{ " " }
145+ < span className = "text-[#6D28D9]" > click</ span > to select files
146+ </ p >
147+ ) }
148+ < div
149+ className = { `mt-2 text-xs ${
150+ files ?. length === 0 ? "text-red-500" : "text-gray-600"
151+ } `}
146152 >
147- ↑
148- </ button >
149- < button
150- onClick = { ( ) => reorderFiles ( index , index + 1 ) }
151- disabled = { index === previews . length - 1 }
152- className = "px-2 py-1 text-sm bg-gray-200 rounded disabled:opacity-50"
153- >
154- ↓
155- </ button >
156- </ div >
153+ { files ?. length || 0 } files selected
154+ </ div >
155+ </ section >
156+ < label className = "mx-2 -mr-2 block text-center text-xs font-medium text-gray-700" >
157+ Only Images and PDF are allowed
158+ < sup className = "text-red-500" > *</ sup >
159+ </ label >
157160 </ div >
158161 </ div >
159- ) ) }
160- < Button onClick = { handlePrint } disabled = { isUploading } >
161- { isUploading ? 'Uploading...' : 'Upload Papers' }
162+ </ fieldset >
163+
164+ { previews . length > 0 && (
165+ < section className = "mt-6 space-y-4 w-full max-w-md" >
166+ { previews . map ( ( item , index ) => (
167+ < div
168+ key = { index }
169+ className = "flex flex-col items-center gap-4 border p-8 rounded-md "
170+ >
171+ { item . file . type . startsWith ( 'image/' ) ? (
172+ < img
173+ src = { item . preview }
174+ alt = "preview"
175+ className = "w-64 h-64 object-cover rounded-md mx-auto"
176+ />
177+ ) : (
178+ < iframe
179+ src = { item . preview }
180+ className = "w-64 h-64 border rounded-md mx-auto"
181+ title = { `PDF preview ${ index } ` }
182+ />
183+ ) }
184+ < div className = "flex flex-col gap-2 items-center w-full" >
185+ < p className = "font-semibold break-words text-[#6D28D9] text-center" > { item . file . name } </ p >
186+ < div className = "flex gap-2" >
187+ < button
188+ onClick = { ( ) => reorderFiles ( index , index - 1 ) }
189+ disabled = { index === 0 }
190+ className = "p-2 text-lg rounded bg-[#6D28D9] text-white disabled:opacity-50 flex items-center justify-center"
191+ title = "Move Up"
192+ >
193+ < FiArrowUp />
194+ </ button >
195+ < button
196+ onClick = { ( ) => reorderFiles ( index , index + 1 ) }
197+ disabled = { index === previews . length - 1 }
198+ className = "p-2 text-lg rounded bg-[#6D28D9] text-white disabled:opacity-50 flex items-center justify-center"
199+ title = "Move Down"
200+ >
201+ < FiArrowDown />
202+ </ button >
203+ < button
204+ onClick = { ( ) => setZoomIndex ( index ) }
205+ className = "p-2 text-lg rounded bg-[#6D28D9] text-white hover:bg-purple-700 flex items-center justify-center"
206+ title = "Zoom"
207+ >
208+ < FiZoomIn />
209+ </ button >
210+ < button
211+ onClick = { ( ) => handleDelete ( index ) }
212+ className = "p-2 text-lg rounded bg-[#6D28D9] text-white hover:bg-red-600 flex items-center justify-center"
213+ title = "Delete"
214+ >
215+ < FiTrash />
216+ </ button >
217+ </ div >
218+ </ div >
219+ </ div >
220+ ) ) }
221+ </ section >
222+ ) }
223+ < Button
224+ onClick = { handlePrint }
225+ disabled = { isUploading || files . length === 0 }
226+ className = { `w-fit rounded-md px-4 py-3 text-base ${
227+ isUploading || files . length === 0 ? "opacity-60" : ""
228+ } `}
229+ >
230+ { isUploading ? "Uploading..." : "Upload Papers" }
162231 </ Button >
163- </ section >
232+ </ div >
233+ </ div >
234+
235+
236+ { zoomIndex !== null && (
237+ < div className = "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-70" >
238+ < div className = "relative bg-white rounded-lg shadow-lg p-4 flex flex-col items-center" >
239+ < button
240+ onClick = { ( ) => setZoomIndex ( null ) }
241+ className = "absolute top-2 right-2 p-2 rounded-full bg-gray-200 hover:bg-gray-300"
242+ title = "Close"
243+ >
244+ < FiX size = { 24 } />
245+ </ button >
246+ { previews [ zoomIndex ] . file . type . startsWith ( 'image/' ) ? (
247+ < img
248+ src = { previews [ zoomIndex ] . preview }
249+ alt = "zoomed preview"
250+ className = "max-w-[80vw] max-h-[80vh] rounded-md"
251+ />
252+ ) : (
253+ < iframe
254+ src = { previews [ zoomIndex ] . preview }
255+ className = "w-[80vw] h-[80vh] border rounded-md"
256+ title = { `PDF zoom preview ${ zoomIndex } ` }
257+ />
258+ ) }
259+ < p className = "mt-4 font-semibold text-[#6D28D9] text-center break-words" > { previews [ zoomIndex ] . file . name } </ p >
260+ </ div >
261+ </ div >
164262 ) }
165263 </ main >
166264 )
0 commit comments