From a4c3c312796a3d5598ac92aa81dc6c80ddd9ba7c Mon Sep 17 00:00:00 2001
From: Emi Matchu <emi@matchu.dev>
Date: Tue, 21 Jan 2025 15:07:17 -0800
Subject: [PATCH] Add hint to outfit editor when searching for "token",
 "nostalgic", etc

I don't know how reliably people actually know that we support NC
Styles, because the token items aren't searchable.

In this change, we add a little message to teach people about this
feature, if they search for words that match known styles, or the
colloquial word "token" (even though style token items aren't actually
called that on-site).
---
 .../wardrobe-2020/WardrobePage/SearchPanel.js | 59 ++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/app/javascript/wardrobe-2020/WardrobePage/SearchPanel.js b/app/javascript/wardrobe-2020/WardrobePage/SearchPanel.js
index bb43a1de..01c59a9f 100644
--- a/app/javascript/wardrobe-2020/WardrobePage/SearchPanel.js
+++ b/app/javascript/wardrobe-2020/WardrobePage/SearchPanel.js
@@ -1,10 +1,18 @@
 import React from "react";
-import { Box, Text, useColorModeValue, VisuallyHidden } from "@chakra-ui/react";
+import {
+	Alert,
+	AlertIcon,
+	Box,
+	Text,
+	useColorModeValue,
+	VisuallyHidden,
+} from "@chakra-ui/react";
 
 import Item, { ItemListContainer, ItemListSkeleton } from "./Item";
 import PaginationToolbar from "../components/PaginationToolbar";
 import { useSearchResults } from "./useSearchResults";
 import { MajorErrorMessage } from "../util";
+import { useAltStylesForSpecies } from "../loaders/alt-styles";
 
 export const SEARCH_PER_PAGE = 30;
 
@@ -161,6 +169,7 @@ function SearchResults({
 					size="sm"
 				/>
 			</Box>
+			<SearchNCStylesHint query={query} outfitState={outfitState} />
 			<ItemListContainer paddingX="4" paddingBottom="2">
 				{items.map((item, index) => (
 					<SearchResultItem
@@ -262,6 +271,54 @@ function SearchResultItem({
 	);
 }
 
+function SearchNCStylesHint({ query, outfitState }) {
+	const { data: altStyles } = useAltStylesForSpecies(outfitState.speciesId);
+
+	const message = getSearchNCStylesMessage(query, altStyles);
+	if (!message) {
+		return null;
+	}
+
+	return (
+		<Box paddingX="4" paddingY="2">
+			<Alert status="info" variant="left-accent" fontSize="sm" color="blue.900">
+				<AlertIcon />
+				{message}
+			</Alert>
+		</Box>
+	);
+}
+
+function getSearchNCStylesMessage(query, altStyles) {
+	const seriesMainNames = [
+		...new Set((altStyles ?? []).map((as) => as.seriesMainName)),
+	];
+	const queryWords = query.value.toLowerCase().split(/\s+/);
+
+	if (queryWords.includes("token")) {
+		return (
+			<>
+				If you're looking for NC Styles, check the emotion picker below the pet
+				preview!
+			</>
+		);
+	}
+
+	// NOTE: This won't work on multi-word series names, of which there are
+	//       currently none.
+	const seriesWord = seriesMainNames.find((n) =>
+		queryWords.includes(n.toLowerCase()),
+	);
+	if (seriesWord != null) {
+		return (
+			<>
+				If you're looking for NC Styles, check the emotion picker below the pet
+				preview!
+			</>
+		);
+	}
+}
+
 /**
  * serializeQuery stably converts a search query object to a string, for easier
  * JS comparison.