+ rawTags
+ ? rawTags
+ .split(",")
+ .map((tag) => tag.trim())
+ .filter((tag) => tag.length > 0)
+ : [],
+ [rawTags]
+ );
+
+ const [filterCount, setFilterCount] = useState(tags.length);
+
+ // Filter menu button handler
+ const handleClick = () => {
+ if (!isOpen) {
+ setIsOpen(true);
+ // slight delay to trigger animation
+ setTimeout(() => setIsVisible(true), 10);
+ } else {
+ setIsVisible(false);
+ setTimeout(() => {
+ setIsOpen(false);
+ }, 200);
+ }
+ };
+
+ // Count all active filters
+ useEffect(() => {
+ let count = tags.length;
+ if (platform) count++;
+ if (gender) count++;
+
+ setFilterCount(count);
+ }, [tags, platform, gender]);
+
+ return (
+
+ );
+}
diff --git a/src/components/mii-list/gender-select.tsx b/src/components/mii-list/gender-select.tsx
index 25997cf..0b7eb56 100644
--- a/src/components/mii-list/gender-select.tsx
+++ b/src/components/mii-list/gender-select.tsx
@@ -29,24 +29,28 @@ export default function GenderSelect() {
};
return (
-
+
diff --git a/src/components/mii-list/index.tsx b/src/components/mii-list/index.tsx
index 9a98733..7c363a9 100644
--- a/src/components/mii-list/index.tsx
+++ b/src/components/mii-list/index.tsx
@@ -1,6 +1,6 @@
import Link from "next/link";
-import { MiiGender, Prisma } from "@prisma/client";
+import { MiiGender, MiiPlatform, Prisma } from "@prisma/client";
import { Icon } from "@iconify/react";
import { z } from "zod";
@@ -10,8 +10,7 @@ import { querySchema } from "@/lib/schemas";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
-import GenderSelect from "./gender-select";
-import TagFilter from "./tag-filter";
+import FilterMenu from "./filter-menu";
import SortSelect from "./sort-select";
import Carousel from "../carousel";
import LikeButton from "../like-button";
@@ -36,6 +35,7 @@ const searchSchema = z.object({
.map((tag) => tag.trim())
.filter((tag) => tag.length > 0)
),
+ platform: z.enum(MiiPlatform, { error: "Platform must be either 'THREE_DS', or 'SWITCH'" }).optional(),
gender: z.enum(MiiGender, { error: "Gender must be either 'MALE', or 'FEMALE'" }).optional(),
// todo: incorporate tagsSchema
// Pages
@@ -60,7 +60,7 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
const parsed = searchSchema.safeParse(searchParams);
if (!parsed.success) return
{parsed.error.issues[0].message}
;
- const { q: query, sort, tags, gender, page = 1, limit = 24, seed } = parsed.data;
+ const { q: query, sort, tags, platform, gender, page = 1, limit = 24, seed } = parsed.data;
// My Likes page
let miiIdsLiked: number[] | undefined = undefined;
@@ -82,6 +82,8 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
}),
// Tag filtering
...(tags && tags.length > 0 && { tags: { hasEvery: tags } }),
+ // Platform
+ ...(platform && { platform: { equals: platform } }),
// Gender
...(gender && { gender: { equals: gender } }),
// Profiles
@@ -99,6 +101,7 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
},
},
}),
+ platform: true,
name: true,
imageCount: true,
tags: true,
@@ -201,9 +204,8 @@ export default async function MiiList({ searchParams, userId, inLikesPage }: Pro
)}
diff --git a/src/components/mii-list/platform-select.tsx b/src/components/mii-list/platform-select.tsx
new file mode 100644
index 0000000..8915d8e
--- /dev/null
+++ b/src/components/mii-list/platform-select.tsx
@@ -0,0 +1,58 @@
+"use client";
+
+import { useRouter, useSearchParams } from "next/navigation";
+import { useState, useTransition } from "react";
+import { Icon } from "@iconify/react";
+import { MiiPlatform } from "@prisma/client";
+
+export default function PlatformSelect() {
+ const router = useRouter();
+ const searchParams = useSearchParams();
+ const [, startTransition] = useTransition();
+
+ const [selected, setSelected] = useState