feat: sort select in mii list
This commit is contained in:
parent
cc506f2619
commit
b5b431028a
2 changed files with 65 additions and 18 deletions
|
|
@ -6,6 +6,7 @@ import { prisma } from "@/lib/prisma";
|
|||
|
||||
import Carousel from "./carousel";
|
||||
import LikeButton from "./like-button";
|
||||
import SortSelect from "./sort-select";
|
||||
|
||||
interface Props {
|
||||
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
|
||||
|
|
@ -18,18 +19,16 @@ export default async function MiiList({ searchParams, userId, where }: Props) {
|
|||
const session = await auth();
|
||||
const resolvedSearchParams = await searchParams;
|
||||
|
||||
// sort search param
|
||||
const orderBy: { createdAt?: Prisma.SortOrder; likes?: Prisma.SortOrder } = {};
|
||||
// Sort search param
|
||||
// Defaults to newest
|
||||
const orderBy: Prisma.MiiOrderByWithRelationInput =
|
||||
resolvedSearchParams.sort === "newest"
|
||||
? { createdAt: "desc" }
|
||||
: resolvedSearchParams.sort === "likes"
|
||||
? { likedBy: { _count: "desc" } }
|
||||
: { createdAt: "desc" };
|
||||
|
||||
if (resolvedSearchParams.sort === "newest") {
|
||||
orderBy.createdAt = "desc";
|
||||
} else if (resolvedSearchParams.sort === "likes") {
|
||||
orderBy.likes = "desc";
|
||||
} else {
|
||||
orderBy.createdAt = "desc"; // Default to newest if no valid sort is provided
|
||||
}
|
||||
|
||||
// tag search param
|
||||
// Tag search param
|
||||
const rawTags = resolvedSearchParams.tags;
|
||||
const tagFilter =
|
||||
typeof rawTags === "string"
|
||||
|
|
@ -115,13 +114,7 @@ export default async function MiiList({ searchParams, userId, where }: Props) {
|
|||
<span>todo</span>
|
||||
</div>
|
||||
|
||||
<div className="pill gap-2">
|
||||
<label htmlFor="sort">Sort:</label>
|
||||
<select name="sort">
|
||||
<option value="likes">Likes</option>
|
||||
<option value="newest">Newest</option>
|
||||
</select>
|
||||
</div>
|
||||
<SortSelect />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
54
src/app/components/sort-select.tsx
Normal file
54
src/app/components/sort-select.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"use client";
|
||||
|
||||
import { Icon } from "@iconify/react";
|
||||
import { useSelect } from "downshift";
|
||||
import { redirect, useSearchParams } from "next/navigation";
|
||||
|
||||
type Sort = "likes" | "newest";
|
||||
|
||||
const items = ["likes", "newest"];
|
||||
|
||||
export default function SortSelect() {
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const currentSort = (searchParams.get("sort") as Sort) || "newest";
|
||||
|
||||
const { isOpen, getToggleButtonProps, getMenuProps, getItemProps, highlightedIndex, selectedItem } = useSelect({
|
||||
items,
|
||||
selectedItem: currentSort,
|
||||
onSelectedItemChange: ({ selectedItem }) => {
|
||||
if (!selectedItem) return;
|
||||
redirect(`?sort=${selectedItem}`);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="relative w-full">
|
||||
{/* Toggle button to open the dropdown */}
|
||||
<button type="button" {...getToggleButtonProps()} className="pill input w-full gap-1 !justify-between">
|
||||
<span>Sort by </span>
|
||||
{selectedItem || "Select a way to sort"}
|
||||
<Icon icon="tabler:chevron-down" className="ml-2 size-5" />
|
||||
</button>
|
||||
|
||||
{/* Dropdown menu */}
|
||||
<ul
|
||||
{...getMenuProps()}
|
||||
className={`absolute z-50 w-full bg-orange-200 border-2 border-orange-400 rounded-lg mt-1 shadow-lg max-h-60 overflow-y-auto ${
|
||||
isOpen ? "block" : "hidden"
|
||||
}`}
|
||||
>
|
||||
{isOpen &&
|
||||
items.map((item, index) => (
|
||||
<li
|
||||
key={item}
|
||||
{...getItemProps({ item, index })}
|
||||
className={`px-4 py-1 cursor-pointer text-sm ${highlightedIndex === index ? "bg-black/15" : ""}`}
|
||||
>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue