Skip to content

Commit e4120cc

Browse files
authored
Add decks sort by (#852)
1 parent 5556296 commit e4120cc

File tree

4 files changed

+30
-15
lines changed

4 files changed

+30
-15
lines changed

frontend/src/components/Filters.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ interface PropsDropdown<T> extends Props<T> {
4545

4646
export function DropdownFilter<T extends string | number>({ label, options, value, onChange, className, show = (x) => String(x) }: PropsDropdown<T>) {
4747
return (
48-
<label className={cn(commonClassName, 'flex items-baseline justify-between gap-5 px-3 py-1 my-auto text-neutral-400', className)}>
48+
<label className={cn(commonClassName, 'flex items-baseline justify-between gap-5 px-3 py-1 text-neutral-400', className)}>
4949
{label && <span className="text-sm">{label}</span>}
5050
<select value={value} onChange={(e) => onChange(e.target.value as T)} className="min-h-[27px] text-sm text-right cursor-pointer">
5151
{options.map((x) => (

frontend/src/lib/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ export function chunk<T>(arr: T[], size: number): T[][] {
1818
return res
1919
}
2020

21+
export function capitalize(str: string) {
22+
return str.charAt(0).toUpperCase() + str.slice(1)
23+
}
24+
2125
export function formatFriendId(friendId: string): string {
2226
if (!friendId || friendId.length !== 16) {
2327
return friendId

frontend/src/pages/decks/Decks.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@ import { ChevronFirst, ChevronLeft, ChevronRight } from 'lucide-react'
22
import { useState } from 'react'
33
import { Link, useNavigate, useParams } from 'react-router'
44
import ErrorAlert from '@/components/ErrorAlert'
5-
import { TabsFilter, ToggleFilter } from '@/components/Filters'
5+
import { DropdownFilter, TabsFilter, ToggleFilter } from '@/components/Filters'
66
import { Spinner } from '@/components/Spinner'
77
import { Button } from '@/components/ui/button'
88
import { showCardType } from '@/components/utils'
9-
import { type DeckFilters, deckKinds } from '@/services/decks/deckService'
9+
import { capitalize } from '@/lib/utils'
10+
import { type DeckFilters, deckKinds, deckOrder } from '@/services/decks/deckService'
1011
import { useDecksSearch } from '@/services/decks/useDeck'
1112
import { energies } from '@/types'
1213
import { DeckItem } from './DeckItem'
1314

1415
export default function Decks() {
1516
const navigate = useNavigate()
1617
const { kind } = useParams<{ kind: DeckFilters['kind'] }>()
17-
const validKind = kind && deckKinds.includes(kind) ? kind : 'popular'
18+
const validKind = kind && deckKinds.includes(kind) ? kind : 'community'
1819

19-
const [filters, setFilters] = useState<DeckFilters>({ kind: validKind, page: 0, energy: [] })
20+
const [filters, setFilters] = useState<DeckFilters>({ kind: validKind, orderby: 'popular', page: 0, energy: [] })
2021
const { data, isLoading, isError, error } = useDecksSearch(filters)
2122

2223
const handleKindChange = (newKind: DeckFilters['kind']) => {
@@ -33,13 +34,16 @@ export default function Decks() {
3334
<ChevronRight />
3435
</Button>
3536
</Link>
36-
<TabsFilter
37-
className="w-full"
38-
options={deckKinds}
39-
value={filters.kind}
40-
onChange={handleKindChange}
41-
show={(kind) => `${kind.charAt(0).toUpperCase() + kind.slice(1)} decks`}
42-
/>
37+
<TabsFilter className="w-full" options={deckKinds} value={filters.kind} onChange={handleKindChange} show={(kind) => `${capitalize(kind)} decks`} />
38+
{filters.kind === 'community' && (
39+
<DropdownFilter
40+
options={deckOrder}
41+
value={filters.orderby}
42+
onChange={(orderby) => setFilters((prev) => ({ ...prev, orderby }))}
43+
label="Sort by"
44+
show={capitalize}
45+
/>
46+
)}
4347
<ToggleFilter options={energies} value={filters.energy} onChange={(energy) => setFilters((prev) => ({ ...prev, energy }))} show={showCardType} />
4448
</div>
4549
<div className="flex flex-col gap-2 sm:w-xl">

frontend/src/services/decks/deckService.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { supabase } from '@/lib/supabase'
22
import type { Deck, Energy } from '@/types'
33

4-
export const deckKinds = ['popular', 'liked', 'my'] as const
4+
export const deckKinds = ['community', 'liked', 'my'] as const
5+
export const deckOrder = ['popular', 'new'] as const
56

67
export interface DeckFilters {
78
kind: (typeof deckKinds)[number]
9+
orderby: (typeof deckOrder)[number]
810
page: number
911
energy: Energy[]
1012
}
@@ -43,8 +45,13 @@ export async function getDecks(filters: DeckFilters) {
4345
tbl = tbl.from('decks').select('*', { count: 'exact' })
4446
} else if (filters.kind === 'liked') {
4547
tbl = tbl.from('deck_likes').select('*, public_decks!id(*)', { count: 'exact' })
46-
} else if (filters.kind === 'popular') {
47-
tbl = tbl.from('public_decks').select('*', { count: 'exact' }).order('likes', { ascending: false })
48+
} else if (filters.kind === 'community') {
49+
tbl = tbl.from('public_decks').select('*', { count: 'exact' })
50+
if (filters.orderby === 'popular') {
51+
tbl = tbl.order('likes', { ascending: false })
52+
} else if (filters.orderby === 'new') {
53+
tbl = tbl.order('created_at', { ascending: false })
54+
}
4855
}
4956

5057
const col_prefix = filters.kind === 'liked' ? 'public_decks.' : ''

0 commit comments

Comments
 (0)