Skip to content

Commit ecc78a2

Browse files
hh
1 parent a78c8c4 commit ecc78a2

13 files changed

Lines changed: 985 additions & 543 deletions

File tree

components/Layout.js

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import { useState } from 'react';
22
import SideNav from '@/components/Navigation/SideNav';
33
import Link from 'next/link';
44
import { MenuIcon, X } from 'lucide-react';
@@ -11,53 +11,70 @@ export default function Layout( { children } ) {
1111
};
1212

1313
return (
14-
<div className="flex h-full w-full mx-auto bg-gradient-to-br from-white/20 via-purple-900/90 to-black/80">
15-
{/* Sidebar */ }
16-
<div
17-
className={ `fixed inset-y-0 left-0 z-30 max-w-72 glass transform ${ isSidebarOpen ? 'translate-x-0' : '-translate-x-full'
18-
} transition-transform duration-300 ease-in-out lg:relative lg:translate-x-0` }
19-
>
20-
<div className="flex items-center justify-between gap-5 p-4 bg-gradient-to-r from-purple-900/80 to-slate-900/80 shadow-lg border-b border-purple-900">
21-
<h2 className="text-xl font-bold text-white text-shadow">
22-
<Link className="w-fit" href={ `/` } passHref>
23-
<span className="text-shadow px-2 bg-blur backdrop">CARD PRICE APP</span>
24-
</Link>
25-
</h2>
26-
<button
27-
className="lg:hidden text-white hover:text-purple-200 transition-colors text-2xl text-shadow bg-blur"
28-
onClick={ toggleSidebar }
29-
title={ "Close" }
30-
>
31-
<X size={ 28 } color={ "Red" } />
32-
</button>
33-
</div>
34-
<SideNav />
35-
</div>
14+
<div className="min-h-screen w-full">
3615

37-
{/* Main Content */ }
38-
<div className="flex-1 flex flex-col max-w-full mx-auto">
39-
{/* Mobile Header */ }
40-
<header className="sticky top-0 z-20 bg-gradient-to-r from-purple-900/80 to-slate-900/80 p-2 shadow-md lg:hidden">
41-
<div className="flex justify-between items-center">
42-
<h3 className="text-xl font-bold text-white text-shadow">
43-
<Link href={ `/` } passHref>
44-
<span className="text-shadow px-2">CARD PRICE APP</span>
16+
17+
<div className="relative flex flex-wrap min-h-screen w-full text-white">
18+
{/* Sidebar */ }
19+
<div
20+
className={ `fixed inset-y-0 left-0 z-50 w-[280px] max-w-xs transform transition-transform duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] lg:relative lg:translate-x-0 ${ isSidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0' }` }
21+
>
22+
<div className="glass-strong h-full border-r border-white/10 shadow-xl">
23+
<div className="flex items-center justify-between gap-4 border-b border-white/5 px-5 py-4 backdrop-blur">
24+
<Link className="group flex items-center gap-2 text-lg font-semibold tracking-wide" href="/" passHref>
25+
<span className="inline-flex h-10 w-10 items-center justify-center rounded-full bg-gradient-to-br from-purple-500/40 to-indigo-500/30 text-sm font-bold uppercase shadow-ring">
26+
CPA
27+
</span>
28+
<span className="text-shadow transition-colors group-hover:text-indigo-100">
29+
Card Price App
30+
</span>
4531
</Link>
46-
</h3>
32+
<button
33+
className="text-white/80 transition hover:text-white lg:hidden"
34+
onClick={ toggleSidebar }
35+
title="Close"
36+
>
37+
<X size={ 26 } />
38+
</button>
39+
</div>
40+
<SideNav />
41+
</div>
42+
</div>
43+
44+
{/* Main Content */ }
45+
<div className="flex min-h-screen w-full flex-1 flex-col">
46+
<header className="sticky top-0 z-30 flex items-center justify-between border-b border-white/5 bg-slate-900/60 px-4 py-3 backdrop-blur lg:hidden">
47+
<Link href="/" passHref className="text-base font-semibold tracking-wide">
48+
<span className="text-shadow">Card Price App</span>
49+
</Link>
4750
<button
48-
className="text-shadow text-white hover:text-purple-200 transition-colors text-3xl -m-1 p-1"
49-
title={ "Menu" }
51+
className="rounded-md border border-white/10 bg-white/5 p-2 text-white/90 transition hover:bg-white/10"
52+
title="Menu"
5053
onClick={ toggleSidebar }
5154
>
52-
<MenuIcon size={ 40 } />
55+
<MenuIcon size={ 24 } />
5356
</button>
54-
</div>
55-
</header>
57+
</header>
5658

57-
<main className="min-h-screen p-2 w-full max-w-[100%] mx-auto">
58-
<div className="container box-content mx-auto mt-5">{ children }</div>
59-
</main>
59+
<main className="relative flex-1 px-4 py-6 sm:px-6 lg:px-10">
60+
<div className="">
61+
<div className="glass-card animate-floaty absolute inset-x-10 top-10 -z-10 hidden h-32 rounded-full blur-3xl lg:block" />
62+
<div className="relative z-10">
63+
{ children }
64+
</div>
65+
</div>
66+
</main>
67+
</div>
6068
</div>
69+
70+
{ isSidebarOpen && (
71+
<button
72+
type="button"
73+
className="fixed inset-0 z-30 bg-black/50 lg:hidden"
74+
onClick={ toggleSidebar }
75+
aria-label="Close sidebar overlay"
76+
/>
77+
) }
6178
</div>
6279
);
6380
}

components/Navigation/SideNav.js

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Link from "next/link";
1+
import Link from "next/link";
22
import { useMemo, useState } from "react";
33
import { useRouter } from "next/router";
44

@@ -35,73 +35,50 @@ export default function SideNav() {
3535
}
3636
};
3737

38-
return (
39-
<nav className="p-4 min-h-max z-50">
40-
<ul className="inset-2 rounded-lg bg-opacity-50">
41-
<li className="navButton mb-2 rounded-lg`">
42-
<Link href="/yugioh" title={ "Search for current Yu-Gi-Oh! card prices" } passHref>
43-
<span className="rounded-none block w-full text-left p-2 text-white bg-clip-padding border border-zinc-600 font-semibold backdrop-opacity-90 backdrop-blur-md hover:bg-zinc-400 bg-gradient-to-tr to-neutral-400 from-purple-800 hover:text-white">
44-
Yu-Gi-Oh! Card Prices
45-
</span>
46-
</Link>
47-
</li>
48-
49-
<li className="navButton mb-2 rounded-lg`">
50-
<Link href="/yugioh/sets/set-index" title={ "Browse Yu-Gi-Oh! sets" } passHref>
51-
<span className="rounded-none block w-full text-left p-2 text-white bg-clip-padding border border-zinc-600 font-semibold backdrop-opacity-90 backdrop-blur-md hover:bg-zinc-400 bg-gradient-to-tr to-neutral-400 from-purple-800 hover:text-white">
52-
Browse Yu-Gi-Oh! Sets
53-
</span>
54-
</Link>
55-
</li>
56-
57-
<li className="navButton mb-2 rounded-lg`">
58-
<Link href="/yugioh/deck-builder" title={ "Build and test decks" } passHref>
59-
<span className="rounded-none block w-full text-left p-2 text-white bg-clip-padding border border-zinc-600 font-semibold backdrop-opacity-90 backdrop-blur-md hover:bg-zinc-400 bg-gradient-to-tr to-neutral-400 from-purple-800 hover:text-white">
60-
Yu-Gi-Oh! Deck Builder
61-
</span>
62-
</Link>
63-
</li>
38+
const links = [
39+
{ href: "/yugioh", label: "Yu-Gi-Oh! Card Prices", title: "Search for current Yu-Gi-Oh! card prices" },
40+
{ href: "/yugioh/sets/set-index", label: "Browse Yu-Gi-Oh! Sets", title: "Browse Yu-Gi-Oh! sets" },
41+
{ href: "/yugioh/deck-builder", label: "Yu-Gi-Oh! Deck Builder", title: "Build and test decks" },
42+
{ href: "/sports", label: "Sports Card Prices", title: "Get current sports card prices" },
43+
{ href: "/yugioh/my-collection", label: "My Collection", title: "View your saved cards" },
44+
];
6445

65-
<li className="navButton mb-2 rounded-lg`">
66-
<Link href="/sports" title={ "Get current sports card prices" } passHref>
67-
<span className="rounded-none block w-full text-left p-2 text-white bg-clip-padding border border-zinc-600 font-semibold backdrop-opacity-90 backdrop-blur-md hover:bg-zinc-400 bg-gradient-to-tr to-neutral-400 from-purple-800 hover:text-white">
68-
Sports Card Prices
69-
</span>
70-
</Link>
71-
</li>
72-
73-
<li className="navButton mb-2 rounded-lg">
74-
<Link href="/yugioh/my-collection" title={ "View your saved cards" } passHref>
75-
<span className="rounded-none block w-full text-left p-2 text-white bg-clip-padding border border-zinc-600 font-semibold backdrop-opacity-90 backdrop-blur-md hover:bg-zinc-400 bg-gradient-to-tr to-neutral-400 from-purple-800 hover:text-white">
76-
My Collection
77-
</span>
78-
</Link>
79-
</li>
46+
return (
47+
<nav className="flex max-h-fit flex-col justify-between px-4 py-6">
48+
<ul className="space-y-3">
49+
{ links.map( ( item ) => (
50+
<li key={ item.href } className="navButton">
51+
<Link href={ item.href } title={ item.title } passHref>
52+
<span className="block">
53+
{ item.label }
54+
</span>
55+
</Link>
56+
</li>
57+
) ) }
58+
</ul>
8059

81-
{ isAuthenticated && (
82-
<li className="navButton mt-4 rounded">
83-
<button
84-
onClick={ handleLogout }
85-
className="navButton rounded block w-full text-left p-2 text-white bg-clip-padding border border-zinc-600 font-semibold backdrop-opacity-90 backdrop-blur-md hover:bg-zinc-400 bg-gradient-to-tr from-red-900 to-purple-600 hover:text-white"
86-
title={ "Log out" }
60+
<div className="mt-6 space-y-3">
61+
{ isAuthenticated ? (
62+
<button
63+
onClick={ handleLogout }
64+
className="w-full rounded-lg border border-white/10 bg-red-500/20 px-4 py-2 text-sm font-semibold tracking-wide text-red-100 transition hover:bg-red-500/30"
65+
title="Log out"
66+
>
67+
Log Out
68+
</button>
69+
) : (
70+
!isAuthenticated && (
71+
<Link
72+
href="/login"
73+
title="Log in"
74+
passHref
75+
className="block w-full rounded-lg border border-white/10 bg-white/5 px-4 py-2 text-center text-sm font-semibold tracking-wide text-white/90 transition hover:bg-white/10"
8776
>
88-
Log Out
89-
</button>
90-
</li>
77+
Log In
78+
</Link>
79+
)
9180
) }
92-
{ !isAuthenticated && (
93-
<div className="w-full">
94-
<button className="mt-4 rounded block w-full text-left p-2 bg-clip-padding bg-zinc-800 border border-zinc-600 hover:transition-transform hover:ease-in-out hover:duration-700 font-semibold backdrop-opacity-90 backdrop-blur-md hover:bg-gradient-to-tr hover:from-purple-900 hover:to-green-600">
95-
<Link
96-
href="/login"
97-
title={ "Log in" }
98-
passHref
99-
>
100-
Log In
101-
</Link>
102-
</button>
103-
</div> ) }
104-
</ul>
81+
</div>
10582
</nav>
10683
);
10784
}

components/Notification.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
import { XMarkIcon } from '@heroicons/react/20/solid';
22
import { useEffect } from 'react';
33

4-
const Notification = ({ show, setShow, message }) => {
5-
useEffect(() => {
6-
if (show) {
7-
const timer = setTimeout(() => setShow(false), 1500);
8-
return () => clearTimeout(timer);
4+
const Notification = ( { show, setShow, message } ) => {
5+
useEffect( () => {
6+
if ( show ) {
7+
const timer = setTimeout( () => setShow( false ), 1500 );
8+
return () => clearTimeout( timer );
99
}
10-
}, [show, setShow]);
10+
}, [ show, setShow ] );
1111

1212
return (
1313
<div
1414
aria-live="assertive"
15-
className={`z-50 pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6 transition duration-300 ${ show ? 'opacity-100 translate-y-0 sm:translate-x-0' : 'opacity-0 translate-y-2 sm:translate-y-0 sm:translate-x-2' }`}
15+
className={ `mx-auto mt-24 z-50 pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6 transition duration-300 ${ show ? 'opacity-100 translate-y-0 sm:translate-x-0' : 'opacity-0 translate-y-2 sm:translate-y-0 sm:translate-x-2' }` }
1616
>
17-
<div className="z-50 flex w-full flex-col items-center space-y-4 sm:items-end">
18-
<div className="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">
19-
<div className="p-4">
17+
<div className=" z-50 flex w-full flex-col items-center space-y-4 sm:items-end">
18+
<div className="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg backdrop shadow-lg ring-1 ring-black ring-opacity-5">
19+
<div className="glass p-4">
2020
<div className="flex items-center">
2121
<div className="flex w-0 flex-1 justify-between">
22-
<p className="w-0 flex-1 text-sm font-medium text-gray-900">{message}</p>
22+
<p className=" w-0 flex-1 text-sm text-text-shadow font-semibold">{ message }</p>
2323
</div>
2424
<div className="ml-4 flex flex-shrink-0">
2525
<button
2626
type="button"
2727
className="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
28-
onClick={() => setShow(false)}
28+
onClick={ () => setShow( false ) }
2929
>
3030
<span className="sr-only">Close</span>
3131
<XMarkIcon className="h-5 w-5" aria-hidden="true" />

components/Yugioh/GridView.js

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useMemo, useState } from 'react';
1+
import { useCallback, useMemo, useState } from 'react';
22
import Image from 'next/image';
33
import Link from 'next/link';
44
import { useRouter } from 'next/router';
@@ -150,7 +150,7 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
150150
return (
151151
<div
152152
key={ card._id }
153-
className={ `glass rounded-md flip-card card group mx-auto ${ flippedCards[ card._id ] ? 'flipped' : '' }` }
153+
className={ `glass rounded-md h-96 flip-card card group mx-auto ${ flippedCards[ card._id ] ? 'flipped' : '' }` }
154154
>
155155
<div
156156
className="flip-card-inner hover:cursor-pointer "
@@ -159,7 +159,7 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
159159
{/* FRONT */ }
160160
<div className="flip-card-front">
161161
<img
162-
className="w-full h-96 aspect-auto object-scale-down object-center"
162+
className="w-full h-auto aspect-auto object-scale-down object-center"
163163
as="image"
164164
priority="true"
165165
unoptimized="true"
@@ -171,18 +171,39 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
171171
</div>
172172

173173
{/* BACK */ }
174-
<div className="flip-card-back p-5 mx-auto cursor-default glass backdrop-opacity-15 text-white text-shadow overflow-hidden">
174+
<div className="flip-card-back h-96 p-5 mx-auto cursor-default glass backdrop-opacity-15 text-white text-shadow overflow-hidden">
175175

176176
<div>
177177
<h3 className="text-xl font-bold text-center">{ card.productName }</h3>
178-
<div className="text-sm space-y-1 mt-2 text-shadow">
179-
<div className="flex justify-between"><span className="font-bold">Set:</span> <span className='text-pretty text-end'>{ card.setName }</span></div>
180-
<div className="flex justify-between"><span className="font-bold">Number:</span> <span>{ card.number }</span></div>
181-
<div className="flex justify-between"><span className="font-bold">Rarity:</span> <span>{ card.rarity }</span></div>
182-
<div className="flex justify-between"><span className="font-bold">Printing:</span> <span>{ card.printing }</span></div>
183-
<div className="flex justify-between"><span className="font-bold">Condition:</span> <span>{ card.condition }</span></div>
184-
<div className="flex justify-between"><span className="font-bold">Old Price:</span> <span>${ card.oldPrice }</span></div>
185-
<div className="flex justify-between"><span className="font-bold">Market Price:</span> <span>${ card.marketPrice }</span></div>
178+
<div className="text-sm space-y-1 mt-2 text-shadow backdrop">
179+
<div className="flex justify-between">
180+
<span className="font-bold">Set:</span>
181+
<span className='text-pretty text-end'>{ card.setName }</span>
182+
</div>
183+
<div className="flex justify-between">
184+
<span className="font-bold">Number:</span>
185+
<span className='text-pretty text-end'>{ card.number }</span>
186+
</div>
187+
<div className="flex justify-between">
188+
<span className="font-bold">Rarity:</span>
189+
<span className='text-pretty text-end'>{ card.rarity }</span>
190+
</div>
191+
<div className="flex justify-between">
192+
<span className="font-bold">Printing:</span>
193+
<span className='text-pretty text-end'>{ card.printing }</span>
194+
</div>
195+
<div className="flex justify-between">
196+
<span className="font-bold">Condition:</span>
197+
<span className='text-pretty text-end'>{ card.condition }</span>
198+
</div>
199+
<div className="flex justify-between">
200+
<span className="font-bold">Old Price:</span>
201+
<span className='text-pretty text-end'>${ card.oldPrice }</span>
202+
</div>
203+
<div className="flex justify-between">
204+
<span className="font-bold">Market Price:</span>
205+
<span className='text-pretty text-end'>${ card.marketPrice }</span>
206+
</div>
186207
</div>
187208
</div>
188209
<Link
@@ -197,9 +218,7 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
197218
edition: card.printing || "Unknown Edition",
198219
source: 'collection'
199220
}
200-
201221
} }
202-
passHref
203222
>
204223

205224
<p className='hover:cursor-pointer p-2 mx-auto text-shadow text-2xl mt-5 max-w-prose text-center underline hover:no-underline underline-offset-2'>
@@ -271,7 +290,6 @@ const GridView = ( { aggregatedData, onDeleteCard, onUpdateCard } ) => {
271290
} }
272291

273292
className="w-16 text-center px-2 py-1 glass mx-auto"
274-
name="delete"
275293
/>
276294
) : (
277295
<span

0 commit comments

Comments
 (0)