Skip to content

Commit de1406a

Browse files
authored
feat: #856 manage friends (#857)
* feat: #856 manage friends * finish friends page
1 parent 939b8e9 commit de1406a

File tree

18 files changed

+620
-15
lines changed

18 files changed

+620
-15
lines changed

frontend/public/locales/de-DE/header.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"overview": "Übersicht",
33
"collection": "Sammlung",
44
"trade": "Tausch",
5+
"friends": "Freunde",
56
"scan": "Scannen",
67
"decks": "Decks",
78
"selectLanguage": "Sprache auswählen",

frontend/public/locales/en-US/header.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"overview": "Overview",
33
"collection": "Collection",
44
"trade": "Trade",
5+
"friends": "Friends",
56
"scan": "Scan",
67
"decks": "Decks",
78
"selectLanguage": "Select language",

frontend/public/locales/es-ES/header.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"overview": "Inicio",
33
"collection": "Colección",
44
"trade": "Intercambios",
5+
"friends": "Amigos",
56
"selectLanguage": "Seleccionar idioma",
67
"community": "Comunidad ↗",
78
"login": "Iniciar sesión",

frontend/public/locales/fr-FR/header.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"overview": "Vue d'ensemble",
33
"collection": "Collection",
44
"trade": "Échanges",
5+
"friends": "Amis",
56
"scan": "Scanneur",
67
"decks": "Decks",
78
"selectLanguage": "Sélectionner une langue",

frontend/public/locales/it-IT/header.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"overview": "Panoramica",
33
"collection": "Collezione",
44
"trade": "Scambio",
5+
"friends": "Amici",
56
"scan": "Scansiona",
67
"selectLanguage": "Seleziona lingua",
78
"community": "Community ↗",

frontend/public/locales/pt-BR/header.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"overview": "Visão Geral",
33
"collection": "Coleção",
44
"trade": "Troca",
5+
"friends": "Amigos",
56
"selectLanguage": "Selecionar idioma",
67
"community": "Comunidade ↗",
78
"login": "Entrar",

frontend/src/App.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const Scan = lazy(() => import('./pages/scan/Scan.tsx'))
2525
const EditProfile = lazy(() => import('./components/EditProfile.tsx'))
2626
const CardDetail = lazy(() => import('./pages/collection/CardDetail.tsx'))
2727

28+
const Friends = lazy(() => import('./pages/friends/Friends.tsx'))
29+
2830
const TradeWithRedirect = () => {
2931
const { friendId } = useParams()
3032
return <Navigate to={`/trade/${friendId}`} replace />
@@ -90,6 +92,7 @@ function App() {
9092
{ path: '/decks/:id', element: <DeckView /> },
9193
{ path: '/scan', element: <Scan /> },
9294
{ path: '/trade/*', element: <Trade /> },
95+
{ path: '/friends', element: <Friends /> },
9396
],
9497
},
9598
])

frontend/src/components/HamburgerMenu.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const menuItems: MenuItem[] = [
2121
{ title: 'collection', href: '/collection' },
2222
{ title: 'decks', href: '/decks' },
2323
{ title: 'trade', href: '/trade' },
24+
{ title: 'friends', href: '/friends' },
2425
{ title: 'scan', href: '/scan' },
2526
{ title: 'blog', href: 'https://blog.tcgpocketcollectiontracker.com' },
2627
{ title: 'community', href: 'https://community.tcgpocketcollectiontracker.com' },
@@ -40,7 +41,7 @@ export default function HamburgerMenu() {
4041
return (
4142
<Sheet open={open} onOpenChange={setOpen}>
4243
<SheetTrigger asChild>
43-
<Button variant="ghost" size="icon" className="md:hidden">
44+
<Button variant="ghost" size="icon" className="lg:hidden">
4445
<Menu className="h-5 w-5" />
4546
<span className="sr-only">{t('toggle')}</span>
4647
</Button>

frontend/src/components/Header.tsx

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Export from '@/pages/export/Export'
2121
import Import from '@/pages/import/Import'
2222
import { useProfileDialog } from '@/services/account/useAccount'
2323
import { useLoginDialog, useLogout, useUser } from '@/services/auth/useAuth'
24+
import { usePendingRequests } from '@/services/friends/useFriends'
2425
import { useActionableTradeCount } from '@/services/trade/useTrade.ts'
2526
import { Badge } from './ui/badge'
2627

@@ -29,6 +30,8 @@ export function Header() {
2930
const { t, i18n } = useTranslation('header')
3031
const { data: user } = useUser()
3132
const { data: actionableTradeCount } = useActionableTradeCount()
33+
const { data: pendingRequests = [] } = usePendingRequests()
34+
const pendingFriendCount = pendingRequests.length
3235
const logoutMutation = useLogout()
3336

3437
const { isLoginDialogOpen, setIsLoginDialogOpen } = useLoginDialog()
@@ -62,36 +65,36 @@ export function Header() {
6265
<NavigationMenu className="max-w-full justify-start">
6366
<NavigationMenuList>
6467
{/* dynamic item for mobile that switches between overview and collection depending on the current page */}
65-
<NavigationMenuLink asChild className="block sm:hidden">
68+
<NavigationMenuLink asChild className="block md:hidden">
6669
<Link to={isOverviewPage ? '/collection' : '/'}>
6770
<Button className="px-2 sm:px-4" variant="ghost">
6871
{isOverviewPage ? t('collection') : t('overview')}
6972
</Button>
7073
</Link>
7174
</NavigationMenuLink>
7275

73-
<NavigationMenuLink asChild className="hidden sm:block">
76+
<NavigationMenuLink asChild className="hidden md:block">
7477
<Link to="/">
7578
<Button className="px-2 sm:px-4" variant="ghost">
7679
{t('overview')}
7780
</Button>
7881
</Link>
7982
</NavigationMenuLink>
80-
<NavigationMenuLink asChild className="hidden sm:block">
83+
<NavigationMenuLink asChild className="hidden md:block">
8184
<Link to="/collection">
8285
<Button className="px-2 sm:px-4" variant="ghost">
8386
{t('collection')}
8487
</Button>
8588
</Link>
8689
</NavigationMenuLink>
87-
<NavigationMenuLink asChild className="hidden sm:block">
90+
<NavigationMenuLink asChild className="hidden md:block">
8891
<Link to="/decks">
8992
<Button className="px-2 sm:px-4" variant="ghost">
9093
{t('Decks')}
9194
</Button>
9295
</Link>
9396
</NavigationMenuLink>
94-
<NavigationMenuLink asChild className={`${actionableTradeCount ? 'block' : 'hidden'} sm:block`}>
97+
<NavigationMenuLink asChild className={`${actionableTradeCount ? 'block' : 'hidden'} md:block`}>
9598
<Link to="/trade">
9699
<Button className="px-2 sm:px-4" variant="ghost">
97100
{t('trade')}
@@ -104,22 +107,35 @@ export function Header() {
104107
</Button>
105108
</Link>
106109
</NavigationMenuLink>
107-
<NavigationMenuLink asChild className={`${actionableTradeCount ? 'hidden sm:block' : ''}`}>
110+
<NavigationMenuLink asChild className={`${pendingFriendCount && !actionableTradeCount ? 'block' : 'hidden'} md:block`}>
111+
<Link to="/friends">
112+
<Button className="px-2 sm:px-4" variant="ghost">
113+
{t('friends')}
114+
<Badge
115+
className={`h-5 min-w-5 rounded-full font-mono tabular-nums -mt-2 ${pendingFriendCount ? 'flex' : 'hidden'} justify-center`}
116+
variant="destructive"
117+
>
118+
{pendingFriendCount}
119+
</Badge>
120+
</Button>
121+
</Link>
122+
</NavigationMenuLink>
123+
<NavigationMenuLink asChild className={`${actionableTradeCount || pendingFriendCount ? 'hidden sm:block' : ''}`}>
108124
<Link to="/scan">
109125
<Button className="px-2 sm:px-4" variant="ghost">
110126
{t('scan')}
111127
</Button>
112128
</Link>
113129
</NavigationMenuLink>
114130
<NavigationMenuLink asChild className="hidden lg:block">
115-
<Link to="https://blog.tcgpocketcollectiontracker.com" className="hidden md:block">
131+
<Link to="https://blog.tcgpocketcollectiontracker.com" className="hidden lg:block">
116132
<Button className="px-2 sm:px-4" variant="ghost">
117133
{t('blog')}
118134
</Button>
119135
</Link>
120136
</NavigationMenuLink>
121137
<NavigationMenuLink asChild className="hidden lg:block">
122-
<Link to="https://community.tcgpocketcollectiontracker.com" className="hidden md:block">
138+
<Link to="https://community.tcgpocketcollectiontracker.com" className="hidden lg:block">
123139
<Button className="px-2 sm:px-4" variant="ghost">
124140
{t('community')}
125141
</Button>
@@ -158,6 +174,9 @@ export function Header() {
158174
<DropdownMenuLabel>{t('myAccount')}</DropdownMenuLabel>
159175
<DropdownMenuSeparator />
160176
<DropdownMenuItem onClick={() => setIsProfileDialogOpen(true)}>{t('editProfile')}</DropdownMenuItem>
177+
<DropdownMenuItem asChild>
178+
<Link to="/friends">{t('friends')}</Link>
179+
</DropdownMenuItem>
161180
<DropdownMenuSeparator />
162181
<DropdownMenuItem onClick={() => setIsExportDialogOpen(true)}>{t('export')}</DropdownMenuItem>
163182
<DropdownMenuItem onClick={() => setIsImportDialogOpen(true)}>{t('import')}</DropdownMenuItem>

0 commit comments

Comments
 (0)