Skip to content

Commit 5e86097

Browse files
greg19marcelpanse
andauthored
Add find trades button (#843)
* Add find trades button * only show button for tradable cards --------- Co-authored-by: marcel panse <marcel.panse@gmail.com>
1 parent 9ff681a commit 5e86097

File tree

12 files changed

+112
-112
lines changed

12 files changed

+112
-112
lines changed

frontend/public/locales/de-DE/trade-matches.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
"tabMatches": "Matches",
5353
"noAccount": "First set up your account using 'Edit profile' in the top right corner.",
5454
"longOperation": "This might take a while.",
55-
"movedToCollectionPage": "You can now manage your trading cards on your collection page.",
5655
"search": {
5756
"byCard": "Search {{cardName}}",
5857
"selectCard": "Select card to search",

frontend/public/locales/en-US/trade-matches.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
"toCollect": "To collect",
5353
"toKeep": "To keep",
5454
"longOperation": "This might take a while.",
55-
"movedToCollectionPage": "You can now manage your trading cards on your collection page.",
5655
"search": {
5756
"byCard": "Search {{cardName}}",
5857
"selectCard": "Select card to search",

frontend/public/locales/es-ES/trade-matches.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
"isActiveTrading": "Accepting new trades",
5656
"toCollectTooltip": "The amount of cards you want to collect by trading. Tip: Set this value to 0 to exclude a rarity from trading.",
5757
"toKeepTooltip": "The minimum amount of cards you want to trade down to.",
58-
"movedToCollectionPage": "You can now manage your trading cards on your collection page.",
5958
"search": {
6059
"byCard": "Search {{cardName}}",
6160
"selectCard": "Select card to search",

frontend/public/locales/fr-FR/trade-matches.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
"isActiveTrading": "Accepter de recevoir des échanges",
5353
"toCollectTooltip": "Le nombre de carte que vous souhaitez collectionner après échange. Astuce : définissez cette valeur à 0 pour exclure une rareté des échanges.",
5454
"toKeepTooltip": "Le nombre minimum de cartes que vous souhaitez conserver après échange.",
55-
"movedToCollectionPage": "Vous pouvez maintenant gérer vos cartes à échanger sur votre page de collection.",
5655
"search": {
5756
"byCard": "Rechercher {{cardName}}",
5857
"selectCard": "Sélectionner une carte",

frontend/public/locales/it-IT/trade-matches.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
"isActiveTrading": "Accepting new trades",
5858
"toCollectTooltip": "The amount of cards you want to collect by trading. Tip: Set this value to 0 to exclude a rarity from trading.",
5959
"toKeepTooltip": "The minimum amount of cards you want to trade down to.",
60-
"movedToCollectionPage": "You can now manage your trading cards on your collection page.",
6160
"search": {
6261
"byCard": "Search {{cardName}}",
6362
"selectCard": "Select card to search",

frontend/public/locales/pt-BR/trade-matches.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
"isActiveTrading": "Accepting new trades",
5454
"toCollectTooltip": "The amount of cards you want to collect by trading. Tip: Set this value to 0 to exclude a rarity from trading.",
5555
"toKeepTooltip": "The minimum amount of cards you want to trade down to.",
56-
"movedToCollectionPage": "You can now manage your trading cards on your collection page.",
5756
"search": {
5857
"byCard": "Search {{cardName}}",
5958
"selectCard": "Select card to search",

frontend/src/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ function App() {
7373
<Outlet />
7474
</Suspense>
7575
</ErrorBoundary>
76+
<ErrorBoundary fallback={null} onError={() => toast({ variant: 'destructive', description: 'Failed opening card details.' })}>
77+
<CardDetail />
78+
</ErrorBoundary>
7679
<EditProfile />
7780
</>
7881
),
@@ -108,9 +111,6 @@ function App() {
108111
<RouterProvider router={router} />
109112
<InstallPrompt />
110113
<DonationPopup />
111-
<ErrorBoundary fallback={null} onError={() => toast({ variant: 'destructive', description: 'Failed opening card details.' })}>
112-
<CardDetail />
113-
</ErrorBoundary>
114114
{/* Add React Query DevTools (only in development) */}
115115
{process.env.NODE_ENV === 'development' && <ReactQueryDevtools initialIsOpen={false} />}
116116
</DialogContext.Provider>

frontend/src/pages/collection/CardDetail.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import i18n from 'i18next'
22
import { CircleHelp } from 'lucide-react'
33
import { type ReactNode, useEffect, useState } from 'react'
44
import { useTranslation } from 'react-i18next'
5+
import { Link } from 'react-router'
56
import { Tooltip } from 'react-tooltip'
67
import { Card as CardComponent } from '@/components/Card'
78
import { CardLine } from '@/components/CardLine'
@@ -13,7 +14,7 @@ import { craftingCost, getCardByInternalId, getExpansionById } from '@/lib/Cards
1314
import { pullRateForSpecificCard } from '@/lib/stats'
1415
import { getCardNameByLang } from '@/lib/utils'
1516
import { useCollection, useDeleteCard, useSelectedCard } from '@/services/collection/useCollection'
16-
import type { Card, CollectionRow } from '@/types'
17+
import { type Card, type CollectionRow, tradableRarities } from '@/types'
1718

1819
function CardProperty({ name, children }: { name: string; children: ReactNode }) {
1920
return (
@@ -74,16 +75,15 @@ export default function CardDetail() {
7475
}
7576
}
7677

78+
const setOpen = (open: boolean) => {
79+
if (!open) {
80+
setIsOpen(open)
81+
setTimeout(() => setId(undefined), 300) // keep content when sliding out
82+
}
83+
}
84+
7785
return (
78-
<Sheet
79-
open={Boolean(id) && isOpen}
80-
onOpenChange={(open) => {
81-
if (!open) {
82-
setIsOpen(open)
83-
setTimeout(() => setId(undefined), 300) // keep content when sliding out
84-
}
85-
}}
86-
>
86+
<Sheet open={Boolean(id) && isOpen} onOpenChange={setOpen}>
8787
<SheetContent className="transition-all duration-300 ease-in-out border-slate-600 overflow-y-auto w-full md:w-[725px]">
8888
<SheetHeader>
8989
<SheetTitle>
@@ -137,6 +137,12 @@ export default function CardDetail() {
137137
)}
138138
</div>
139139

140+
{card?.rarity && tradableRarities.includes(card.rarity as (typeof tradableRarities)[number]) && (
141+
<Link to={`/trade/matches/results?card_id=${card?.internal_id}`} onClick={() => setOpen(false)}>
142+
<Button>Find trades</Button>
143+
</Link>
144+
)}
145+
140146
<div className="mt-8">
141147
<CardProperty name={t('text.expansion')}>{card?.expansion}</CardProperty>
142148
<CardProperty name={t('text.pack')}>{card && t(card.pack, { ns: 'common/packs' })}</CardProperty>

frontend/src/pages/trade/Trade.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router'
44
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
55
import TradeWith from '@/pages/trade/TradeWith.tsx'
66
import TradeMatches from './TradeMatches'
7+
import TradeMatchesResults from './TradeMatchesResults.tsx'
78
import TradeOffers from './TradeOffers'
89
import TradeSettings from './TradeSettings.tsx'
910

@@ -23,9 +24,6 @@ function Trade() {
2324
return (
2425
<Tabs className="flex flex-col mx-auto max-w-[900px]" value={currentTab} onValueChange={(value) => navigate(`/trade/${value}`)}>
2526
<TabsList className="gap-4 mb-6 rounded-lg border-b-1 border-neutral-700 border-solid dark:bg-transparent pb-2">
26-
<TabsTrigger className="text-md" value="cards">
27-
{t('tabCards')}
28-
</TabsTrigger>
2927
<TabsTrigger className="text-md" value="offers">
3028
{t('tabOffers')}
3129
</TabsTrigger>
@@ -38,9 +36,9 @@ function Trade() {
3836
</TabsList>
3937
<Routes>
4038
<Route path="/" element={<Navigate to="/trade/offers" replace />} />
41-
<Route path="cards" element={<p>{t('movedToCollectionPage')}</p> /* TODO: remove the tab after 14.01.2026 */} />
4239
<Route path="offers" element={<TradeOffers />} />
4340
<Route path="matches" element={<TradeMatches />} />
41+
<Route path="matches/results" element={<TradeMatchesResults />} />
4442
<Route path="settings" element={<TradeSettings />} />
4543
<Route path=":friendId" element={<TradeWith />} />
4644
</Routes>
Lines changed: 32 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,26 @@
11
import { useVirtualizer } from '@tanstack/react-virtual'
22
import i18n from 'i18next'
3-
import { ChevronRight } from 'lucide-react'
43
import { useRef, useState } from 'react'
54
import { useTranslation } from 'react-i18next'
6-
import { Link } from 'react-router'
5+
import { useNavigate } from 'react-router'
76
import { CardLine } from '@/components/CardLine'
87
import SearchInput from '@/components/filters/SearchInput'
98
import { Button } from '@/components/ui/button'
109
import { getCardByInternalId } from '@/lib/CardsDB'
1110
import { getFilteredCards } from '@/lib/filters'
1211
import { getCardNameByLang } from '@/lib/utils.ts'
13-
import { useTradingPartners } from '@/services/trade/useTrade.ts'
1412
import { tradableRarities } from '@/types'
1513

16-
function TradeMatches() {
14+
export default function TradeMatches() {
1715
const { t } = useTranslation(['trade-matches', 'common'])
16+
const navigate = useNavigate()
1817

1918
const scrollRef = useRef(null)
2019
const [search, setSearch] = useState('')
2120
const [selectedCard, setSelectedCard] = useState<number>()
22-
const [showResults, setShowResults] = useState(false)
2321
const cards = getFilteredCards({ search, rarity: [...tradableRarities] }, new Map())
2422
const card = selectedCard && getCardByInternalId(selectedCard)
2523

26-
const { data: tradingPartners, isLoading, isError } = useTradingPartners(showResults, selectedCard)
27-
2824
const virtualizer = useVirtualizer({
2925
getScrollElement: () => scrollRef.current,
3026
count: cards.length,
@@ -33,89 +29,38 @@ function TradeMatches() {
3329
})
3430

3531
if (selectedCard && !card) {
36-
throw new Error('Card selected was not found in the database!')
37-
}
38-
39-
if (!showResults) {
40-
return (
41-
<div className="sm:w-sm mx-auto">
42-
<SearchInput setValue={setSearch} />
43-
<div ref={scrollRef} className="my-2 h-96 rounded border border-neutral-700 px-1 overflow-y-auto">
44-
<ul style={{ height: `${virtualizer.getTotalSize()}px` }} className="relative">
45-
{virtualizer.getVirtualItems().map((row) => {
46-
const c = cards[row.index]
47-
return (
48-
<button
49-
type="button"
50-
key={row.key}
51-
className="absolute top-0 left-0 w-full cursor-pointer"
52-
style={{ height: `${row.size}px`, transform: `translateY(${row.start}px)` }}
53-
onClick={() => setSelectedCard((prev) => (prev === c.internal_id ? undefined : c.internal_id))}
54-
>
55-
<CardLine className={`w-full ${selectedCard === c.internal_id && 'bg-green-900'} hover:bg-neutral-600`} card_id={c.card_id} />
56-
</button>
57-
)
58-
})}
59-
</ul>
60-
</div>
61-
<div className="flex gap-2">
62-
<Button
63-
className="w-1/2"
64-
disabled={!selectedCard}
65-
onClick={() => {
66-
setShowResults(true)
67-
}}
68-
>
69-
{card ? t('search.byCard', { cardName: getCardNameByLang(card, i18n.language) }) : t('search.selectCard')}
70-
</Button>
71-
<Button
72-
className="w-1/2"
73-
onClick={() => {
74-
setSelectedCard(undefined)
75-
setShowResults(true)
76-
}}
77-
>
78-
{t('search.allCards')}
79-
</Button>
80-
</div>
81-
</div>
82-
)
32+
throw new Error('Selected card was not found in the database')
8333
}
8434

85-
if (isLoading) {
86-
return (
87-
<p className="text-xl text-center py-8">
88-
{t('common:loading')}
89-
<br />
90-
{t('longOperation')}
91-
</p>
92-
)
93-
}
94-
95-
if (isError || !tradingPartners) {
96-
return <p className="text-xl text-center py-8">{t('common:error')}</p>
97-
}
98-
99-
if (tradingPartners.length === 0) {
100-
return <p className="text-xl text-center py-8">{t('noTradePartners')}</p>
101-
}
102-
103-
const linkSuffix = selectedCard ? `?friend_card=${selectedCard}` : ''
10435
return (
105-
<div className="flex flex-col gap-4">
106-
{tradingPartners.map((partner) => (
107-
<div key={partner.friend_id} className="max-w-md w-full flex justify-between items-center mx-auto px-4">
108-
<p className="mr-2">{partner.username}</p>
109-
<Link to={`/trade/${partner.friend_id}${linkSuffix}`}>
110-
<Button variant="outline" className="my-auto">
111-
{t('viewTradePartner', { tradeMatches: partner.trade_matches })}
112-
<ChevronRight />
113-
</Button>
114-
</Link>
115-
</div>
116-
))}
36+
<div className="sm:w-sm mx-auto">
37+
<SearchInput setValue={setSearch} />
38+
<div ref={scrollRef} className="my-2 h-96 rounded border border-neutral-700 px-1 overflow-y-auto">
39+
<ul style={{ height: `${virtualizer.getTotalSize()}px` }} className="relative">
40+
{virtualizer.getVirtualItems().map((row) => {
41+
const c = cards[row.index]
42+
return (
43+
<button
44+
type="button"
45+
key={row.key}
46+
className="absolute top-0 left-0 w-full cursor-pointer"
47+
style={{ height: `${row.size}px`, transform: `translateY(${row.start}px)` }}
48+
onClick={() => setSelectedCard((prev) => (prev === c.internal_id ? undefined : c.internal_id))}
49+
>
50+
<CardLine className={`w-full ${selectedCard === c.internal_id && 'bg-green-900'} hover:bg-neutral-600`} card_id={c.card_id} />
51+
</button>
52+
)
53+
})}
54+
</ul>
55+
</div>
56+
<div className="flex gap-2">
57+
<Button className="w-1/2" disabled={!selectedCard} onClick={() => navigate(`/trade/matches/results?card_id=${selectedCard}`)}>
58+
{card ? t('search.byCard', { cardName: getCardNameByLang(card, i18n.language) }) : t('search.selectCard')}
59+
</Button>
60+
<Button className="w-1/2" onClick={() => navigate('/trade/matches/results')}>
61+
{t('search.allCards')}
62+
</Button>
63+
</div>
11764
</div>
11865
)
11966
}
120-
121-
export default TradeMatches

0 commit comments

Comments
 (0)