@@ -13,17 +13,22 @@ const formatCurrency = ( value ) => {
1313 return `$${ numeric . toFixed ( 2 ) } ` ;
1414} ;
1515
16- const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
16+ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard, sortConfig , handleSortChange } ) => {
1717 const [ edit , setEdit ] = useState ( { } ) ;
1818 const [ editValues , setEditValues ] = useState ( { } ) ;
1919 const [ notification , setNotification ] = useState ( { show : false , message : "" } ) ;
2020 const [ flippedCards , setFlippedCards ] = useState ( { } ) ;
21- const [ sortField , setSortField ] = useState ( "setName" ) ;
22- const [ sortDirection , setSortDirection ] = useState ( "asc" ) ;
21+ const isExternallySorted = Boolean ( sortConfig && typeof handleSortChange === "function" ) ;
22+ const [ internalSortField , setInternalSortField ] = useState ( "setName" ) ;
23+ const [ internalSortDirection , setInternalSortDirection ] = useState ( "asc" ) ;
24+ const sortField = isExternallySorted ? sortConfig . key : internalSortField ;
25+ const sortDirection = isExternallySorted
26+ ? ( sortConfig . direction === "descending" ? "desc" : "asc" )
27+ : internalSortDirection ;
2328 const displayInputClasses =
24- "min-w-[4rem] rounded-lg border border-white/30 bg-black/50 px-3 py-1 text-center font-semibold text-white transition hover:border-white/60 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400/60" ;
29+ "min-w-[4rem] rounded border border-white/30 bg-black/50 px-3 py-1 text-center font-semibold text-white transition hover:border-white/60 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400/60" ;
2530 const displayInputClassesRose =
26- "min-w-[4rem] rounded-lg border border-rose-300/60 bg-black/50 px-3 py-1 text-center font-semibold text-rose-200 transition hover:border-rose-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-400/60" ;
31+ "min-w-[4rem] rounded border border-rose-300/60 bg-black/50 px-3 py-1 text-center font-semibold text-rose-200 transition hover:border-rose-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-400/60" ;
2732
2833 const handleEdit = useCallback (
2934 ( cardId , field ) => {
@@ -111,6 +116,10 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
111116 const memoizedAggregatedData = useMemo ( ( ) => {
112117 if ( ! Array . isArray ( aggregatedData ) ) return [ ] ;
113118
119+ if ( isExternallySorted ) {
120+ return aggregatedData ;
121+ }
122+
114123 const sortedData = [ ...aggregatedData ] ;
115124
116125 if ( ! sortField ) {
@@ -140,7 +149,29 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
140149 } ) ;
141150
142151 return sortedData ;
143- } , [ aggregatedData , sortField , sortDirection ] ) ;
152+ } , [ aggregatedData , isExternallySorted , sortField , sortDirection ] ) ;
153+
154+ const handleSortFieldChange = useCallback (
155+ ( nextField ) => {
156+ if ( isExternallySorted ) {
157+ handleSortChange ( nextField ) ;
158+ return ;
159+ }
160+
161+ setInternalSortField ( nextField ) ;
162+ } ,
163+ [ handleSortChange , isExternallySorted ] ,
164+ ) ;
165+
166+ const toggleSortDirection = useCallback ( ( ) => {
167+ if ( isExternallySorted ) {
168+ const nextDirection = sortConfig . direction === "ascending" ? "descending" : "ascending" ;
169+ handleSortChange ( sortConfig . key , nextDirection ) ;
170+ return ;
171+ }
172+
173+ setInternalSortDirection ( ( prev ) => ( prev === "asc" ? "desc" : "asc" ) ) ;
174+ } , [ handleSortChange , isExternallySorted , sortConfig ] ) ;
144175
145176 return (
146177 < >
@@ -149,12 +180,13 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
149180 < span className = "font-medium text-white/70" > Sort</ span >
150181 < select
151182 value = { sortField }
152- onChange = { ( event ) => setSortField ( event . target . value ) }
153- className = "rounded-lg border border-white/15 bg-black/60 px-3 py-2 text-sm font-medium text-white/80 shadow-sm transition hover:border-white/40 focus:border-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-400/40"
183+ onChange = { ( event ) => handleSortFieldChange ( event . target . value ) }
184+ className = "rounded border border-white/15 bg-black/60 px-3 py-2 text-sm font-medium text-white/80 shadow-sm transition hover:border-white/40 focus:border-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-400/40"
154185 >
155186 < option value = "productName" > Card Name</ option >
156187 < option value = "setName" > Set Name</ option >
157188 < option value = "number" > Card Number</ option >
189+ < option value = "printing" > Printing</ option >
158190 < option value = "rarity" > Card Rarity</ option >
159191 < option value = "quantity" > Quantity</ option >
160192 < option value = "marketPrice" > Market Price</ option >
@@ -163,15 +195,15 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
163195 </ div >
164196 < button
165197 type = "button"
166- onClick = { ( ) => setSortDirection ( ( prev ) => ( prev === "asc" ? "desc" : "asc" ) ) }
167- className = "inline-flex items-center rounded-lg border border-white/15 bg-black/60 px-3 py-2 text-sm font-semibold uppercase tracking-wide text-white/80 transition hover:border-white/40 hover:text-white focus:border-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-400/40"
198+ onClick = { toggleSortDirection }
199+ className = "inline-flex items-center rounded border border-white/15 bg-black/60 px-3 py-2 text-sm font-semibold uppercase tracking-wide text-white/80 transition hover:border-white/40 hover:text-white focus:border-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-400/40"
168200 >
169201 { sortDirection === "asc" ? "Asc" : "Desc" }
170202 </ button >
171203 </ div >
172204
173- < div className = "w-full rounded-xl border border-white/10 bg-black/40 p-4 shadow-2xl sm:p-2" >
174- < div className = "grid grid-cols-1 gap-2 xl :grid-cols-2 2xl :grid-cols-3 " >
205+ < div className = "w-full rounded border border-white/10 bg-black/40 p-4 shadow-2xl sm:p-2" >
206+ < div className = "grid grid-cols-1 gap-2 sm :grid-cols-1 md:grid-cols-2 lg :grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 " >
175207 { memoizedAggregatedData . map ( ( card ) => {
176208 if ( ! card ) return null ;
177209
@@ -249,12 +281,12 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
249281 return (
250282 < div
251283 key = { card . _id }
252- className = "group relative flex mx-auto max- w-full h-[550px] max-h-full w-[325px ] flex-col rounded border border-white/10 bg-black/30 transition hover:border-indigo-400/50"
284+ className = "group relative flex flex-wrap mx-auto sm:w-fit lg: w-full min-h-[32rem ] flex-col rounded border border-white/10 bg-black/30 transition hover:border-indigo-400/50"
253285 >
254- < div className = { `relative flex-1 flip-card ${ isFlipped ? "flipped" : "" } ` } >
255- < div className = "flip-card-inner" >
286+ < div className = { `rounded relative flex-1 flip-card ${ isFlipped ? "flipped" : "" } ` } >
287+ < div className = "flip-card-inner rounded " >
256288 < div
257- className = "flip-card-front flex h-full w-full flex-col gap-4 "
289+ className = "flip-card-front flex h-[24rem] w-fit flex-col rounded "
258290 role = "button"
259291 tabIndex = { 0 }
260292 aria-pressed = { isFlipped }
@@ -266,20 +298,22 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
266298 }
267299 } }
268300 >
269- < div className = "relative flex h-full w-full items-center justify-center overflow-hidden rounded border p-4 border-white/10 bg-black/40 shadow-lg transition duration-200 group-hover:border-indigo-400/60 dark:border-white/20 dark:bg-gray-900/60" >
301+ < div className = "relative flex h-full w-auto items-center justify-center overflow-hidden rounded border border-white/10 bg-black/40 shadow-lg transition duration-200 group-hover:border-indigo-400/60 dark:border-white/20 dark:bg-gray-900/60" >
270302 < img
271- className = "mx-auto h-full w-full object-fill aspect-1 "
303+ className = "mx-auto h-full w-full object-top object-scale-down aspect-square "
272304 src = { imageSrc }
273305 alt = { `Card Image - ${ card . productName } ` }
274306 loading = "lazy"
275307 />
276308 { ( formatCurrency ( card . marketPrice ) || card . rarity || card . printing ) && (
277- < div className = "pointer-events-none absolute inset-x-0 top-0 flex h-full items-end justify-start overflow-hidden rounded-lg " >
309+ < div className = "pointer-events-none absolute inset-x-0 top-0 flex h-full items-end justify-start overflow-hidden rounded" >
278310 < div
279311 aria-hidden = "true"
280312 className = "absolute inset-x-0 bottom-0 min-h-[24rem] bg-gradient-to-t from-black/80 via-black/30 to-transparent opacity-90"
281313 />
282- < div className = "relative flex flex-col gap-1 text-white" >
314+
315+ < div className = "relative flex flex-col gap-1 text-white p-2 text-shadow glass w-full bg-transparent" >
316+ < h3 className = "text-lg font-semibold text-pretty break-words" > { card . productName } </ h3 >
283317 { formatCurrency ( card . marketPrice ) && (
284318 < p className = "text-lg font-semibold" > { formatCurrency ( card . marketPrice ) } </ p >
285319 ) }
@@ -291,7 +325,7 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
291325 ) }
292326 </ div >
293327 </ div >
294- < div className = "flip-card-back flex min-h-[24rem ] w-fit flex-col justify-between gap-3 rounded border border-white/10 bg-black/80 p-4 text-white shadow-lg dark:border-white/20 dark:bg-gray-900/80" >
328+ < div className = "flip-card-back flex min-h-[32rem ] w-full flex-col justify-between gap-3 rounded border border-white/10 bg-black p-4 text-white shadow-lg dark:border-white/20 dark:bg-gray-900/80" >
295329 < div className = "space-y-3" >
296330 < h3 className = "text-lg font-semibold text-center text-pretty break-words" > { card . productName } </ h3 >
297331 < div className = "space-y-1 text-xs text-white/70 sm:text-sm" >
@@ -305,9 +339,9 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
305339 ) ) }
306340 </ div >
307341 </ div >
308- < div className = "mx-auto mt-2 flex w-full flex-col gap-2 text-pretty sm:flex-row sm:gap-3" >
342+ < div className = "mx-auto mt-2 flex flex-wrap w-full gap-2 text-pretty sm:gap-3" >
309343 < Link
310- className = "inline-flex w-full items-center justify-center rounded-md border border-white/20 bg-white/10 px-2 py-1 text-sm font-semibold text-white transition hover:border-indigo-400 hover:bg-indigo-500/20"
344+ className = "inline-flex w-full items-center justify-center rounded border border-white/20 bg-white/10 px-2 py-1 text-sm font-semibold text-white transition hover:border-indigo-400 hover:bg-indigo-500/20"
311345 href = { {
312346 pathname : "/yugioh/sets/[letter]/cards/card-details" ,
313347 query : cardDetailsQuery ,
@@ -317,7 +351,7 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
317351 </ Link >
318352 < button
319353 type = "button"
320- className = "inline-flex w-full items-center justify-center rounded-md border border-white/20 px-2 py-1 text-sm font-medium text-white transition hover:border-indigo-400 hover:text-indigo-200"
354+ className = "inline-flex w-full items-center justify-center rounded border border-white/20 px-2 py-1 text-sm font-medium text-white transition hover:border-indigo-400 hover:text-indigo-200"
321355 onClick = { ( ) => toggleFlip ( card . _id , false ) }
322356 >
323357 Show Card Front
@@ -337,7 +371,7 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
337371 onChange = { ( event ) => handleChange ( event , card . _id , "quantity" ) }
338372 onBlur = { ( ) => handleSave ( card . _id , "quantity" ) }
339373 onKeyDown = { handleQuantityKeyDown }
340- className = "min-w-[4rem] rounded-lg border border-white/30 bg-black/60 px-3 py-1 text-center text-white focus:border-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-400/60"
374+ className = "min-w-[4rem] rounded border border-white/30 bg-black/60 px-3 py-1 text-center text-white focus:border-indigo-400 focus:outline-none focus:ring-2 focus:ring-indigo-400/60"
341375 min = { 0 }
342376 />
343377 ) : (
@@ -355,7 +389,7 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
355389 < span className = "text-xs font-semibold uppercase tracking-wide text-rose-300" > Remove Amount</ span >
356390 { edit [ card . _id ] === "deleteAmount" ? (
357391 < input
358- className = "min-w-[4rem] rounded-lg border border-rose-300/60 bg-black/60 px-3 py-1 text-center text-white focus:border-rose-400 focus:outline-none focus:ring-2 focus:ring-rose-400/60"
392+ className = "min-w-[4rem] rounded border border-rose-300/60 bg-black/60 px-3 py-1 text-center text-white focus:border-rose-400 focus:outline-none focus:ring-2 focus:ring-rose-400/60"
359393 type = "number"
360394 min = { 0 }
361395 max = { Math . max ( quantity , 0 ) }
0 commit comments