parent
e2fb99853c
commit
05b549b096
4 changed files with 235 additions and 43 deletions
@ -0,0 +1,77 @@ |
||||
import { ArrowDownWideNarrow, Check, ChevronDown } from 'lucide-react'; |
||||
import { useRef, useState } from 'react'; |
||||
import { useOutsideClick } from '../../hooks/use-outside-click'; |
||||
import type { SortByValues } from './DiscoverRoadmaps'; |
||||
|
||||
const sortingLabels: { label: string; value: SortByValues }[] = [ |
||||
{ |
||||
label: 'Newest', |
||||
value: 'createdAt', |
||||
}, |
||||
{ |
||||
label: 'Oldest', |
||||
value: '-createdAt', |
||||
}, |
||||
{ |
||||
label: 'Highest Rated', |
||||
value: 'rating', |
||||
}, |
||||
{ |
||||
label: 'Lowest Rated', |
||||
value: '-rating', |
||||
}, |
||||
]; |
||||
|
||||
type DiscoverRoadmapSortingProps = { |
||||
sortBy: SortByValues; |
||||
onSortChange: (sortBy: SortByValues) => void; |
||||
}; |
||||
|
||||
export function DiscoverRoadmapSorting(props: DiscoverRoadmapSortingProps) { |
||||
const { sortBy, onSortChange } = props; |
||||
|
||||
const [isOpen, setIsOpen] = useState(false); |
||||
const dropdownRef = useRef(null); |
||||
|
||||
const selectedValue = sortingLabels.find((item) => item.value === sortBy); |
||||
|
||||
useOutsideClick(dropdownRef, () => { |
||||
setIsOpen(false); |
||||
}); |
||||
|
||||
return ( |
||||
<div |
||||
className="min-auto relative flex flex-shrink-0 sm:min-w-[140px]" |
||||
ref={dropdownRef} |
||||
> |
||||
<button |
||||
className="py-15 flex w-full items-center justify-between gap-2 rounded-md border px-2 text-sm" |
||||
onClick={() => setIsOpen(!isOpen)} |
||||
> |
||||
<span>{selectedValue?.label}</span> |
||||
|
||||
<span> |
||||
<ChevronDown className="ml-4 h-3.5 w-3.5" /> |
||||
</span> |
||||
</button> |
||||
|
||||
{isOpen && ( |
||||
<div className="absolute right-0 top-10 z-10 min-w-40 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg"> |
||||
{sortingLabels.map((item) => ( |
||||
<button |
||||
key={item.value} |
||||
className="flex w-full items-center gap-2 px-4 py-2 text-sm hover:bg-gray-100" |
||||
onClick={() => { |
||||
onSortChange(item.value); |
||||
setIsOpen(false); |
||||
}} |
||||
> |
||||
<span>{item.label}</span> |
||||
{item.value === sortBy && <Check className="ml-auto h-4 w-4" />} |
||||
</button> |
||||
))} |
||||
</div> |
||||
)} |
||||
</div> |
||||
); |
||||
} |
@ -1,27 +1,8 @@ |
||||
--- |
||||
import { roadmapApi } from '../api/roadmap'; |
||||
import BaseLayout from '../layouts/BaseLayout.astro'; |
||||
import { DiscoverRoadmaps } from '../components/DiscoverRoadmaps/DiscoverRoadmaps'; |
||||
import { DiscoverError } from '../components/DiscoverRoadmaps/DiscoverError'; |
||||
|
||||
export const prerender = false; |
||||
|
||||
const roadmapApiClient = roadmapApi(Astro); |
||||
|
||||
const { error, response: roadmaps } = |
||||
await roadmapApiClient.listShowcaseRoadmap(); |
||||
const searchParams = Astro.url.searchParams.toString(); |
||||
--- |
||||
|
||||
<BaseLayout title='Discover Custom Roadmaps'> |
||||
{error && <DiscoverError message={error.message} />} |
||||
{ |
||||
roadmaps && ( |
||||
<DiscoverRoadmaps |
||||
roadmapsResponse={roadmaps} |
||||
searchParams={searchParams} |
||||
client:load |
||||
/> |
||||
) |
||||
} |
||||
<DiscoverRoadmaps client:load /> |
||||
</BaseLayout> |
||||
|
Loading…
Reference in new issue