diff --git a/app/javascript/wardrobe-2020/ItemPage.js b/app/javascript/wardrobe-2020/ItemPage.js
index dd80b2e6..0d655421 100644
--- a/app/javascript/wardrobe-2020/ItemPage.js
+++ b/app/javascript/wardrobe-2020/ItemPage.js
@@ -56,13 +56,13 @@ import useCurrentUser from "./components/useCurrentUser";
import SpeciesFacesPicker, {
colorIsBasic,
} from "./ItemPage/SpeciesFacesPicker";
-import { useRouter } from "next/router";
-import Head from "next/head";
-function ItemPage() {
- const { query } = useRouter();
- return ;
-}
+// Removed for the wardrobe-2020 case.
+// TODO: Refactor this stuff, do we even need ItemPageContent really?
+// function ItemPage() {
+// const { query } = useRouter();
+// return ;
+// }
/**
* ItemPageContent is the content of ItemPage, but we also use it as the
@@ -102,11 +102,6 @@ export function ItemPageContent({ itemId, isEmbedded = false }) {
return (
<>
- {!isEmbedded && item?.name && (
-
- {item?.name} | Dress to Impress
-
- )}
- {/* eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element */}
+ {/* eslint-disable-next-line jsx-a11y/alt-text */}
)}
@@ -416,7 +416,7 @@ function CrossFadeImage(incomingImageProps) {
opacity: 1;
`}
>
- {/* eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element */}
+ {/* eslint-disable-next-line jsx-a11y/alt-text */}
- {/* eslint-disable-next-line jsx-a11y/alt-text, @next/next/no-img-element */}
+ {/* eslint-disable-next-line jsx-a11y/alt-text */}
sendDeleteOutfitMutation({ variables: { id } })
.then(() => {
- pushHistory(`/your-outfits`);
+ window.location = "/your-outfits";
})
.catch((e) => {
/* handled in error UI */
diff --git a/app/javascript/wardrobe-2020/WardrobePage/index.js b/app/javascript/wardrobe-2020/WardrobePage/index.js
index 4798bf8f..4ace189c 100644
--- a/app/javascript/wardrobe-2020/WardrobePage/index.js
+++ b/app/javascript/wardrobe-2020/WardrobePage/index.js
@@ -1,6 +1,5 @@
import React from "react";
import { useToast } from "@chakra-ui/react";
-import { useRouter } from "next/router";
import { emptySearchQuery } from "./SearchToolbar";
import ItemsAndSearchPanels from "./ItemsAndSearchPanels";
@@ -30,8 +29,9 @@ function WardrobePage() {
// We manage outfit saving up here, rather than at the point of the UI where
// "Saving" indicators appear. That way, auto-saving still happens even when
- // the indicator isn't on the page, e.g. when searching. We also mount a
- // in this component to prevent navigating away before saving.
+ // the indicator isn't on the page, e.g. when searching.
+ // NOTE: This only applies to navigations leaving the wardrobe-2020 app, not
+ // within!
const outfitSaving = useOutfitSaving(outfitState, dispatchToOutfit);
// TODO: I haven't found a great place for this error UI yet, and this case
@@ -86,20 +86,6 @@ function WardrobePage() {
- {/*
- * TODO: This might unnecessarily block navigations that we don't
- * necessarily need to, e.g., navigating back to Your Outfits while the
- * save request is in flight. We could instead submit the save mutation
- * immediately on client-side nav, and have each outfit save mutation
- * install a `beforeunload` handler that ensures that you don't close
- * the page altogether while it's in flight. But let's start simple and
- * see how annoying it actually is in practice lol
- */}
-
-
{
- const handleWindowClose = (e) => {
- if (!when) return;
- e.preventDefault();
- return (e.returnValue = message);
- };
- const handleBrowseAway = () => {
- if (!when) return;
- if (window.confirm(message)) return;
- router.events.emit("routeChangeError");
- throw "routeChange aborted by .";
- };
- window.addEventListener("beforeunload", handleWindowClose);
- router.events.on("routeChangeStart", handleBrowseAway);
- return () => {
- window.removeEventListener("beforeunload", handleWindowClose);
- router.events.off("routeChangeStart", handleBrowseAway);
- };
- }, [when, message, router]);
-
- return null;
-}
-
export default WardrobePage;
diff --git a/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js b/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js
index 8e730562..fe0f8cb2 100644
--- a/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js
+++ b/app/javascript/wardrobe-2020/WardrobePage/support/AppearanceLayerSupportUploadModal.js
@@ -292,7 +292,6 @@ function AppearanceLayerSupportReviewStep({
marginTop="2"
>
{imageWithAlphaUrl && (
- // eslint-disable-next-line @next/next/no-img-element
{
@@ -175,7 +176,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
// It's important that this callback _doesn't_ change when the outfit
// changes, so that the auto-save effect is only responding to the
// debounced state!
- [sendSaveOutfitMutation, pathname, pushHistory, toast]
+ [sendSaveOutfitMutation, pathname, navigate, toast]
);
const saveOutfit = React.useCallback(
diff --git a/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js b/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js
index c137763a..5d26c4f9 100644
--- a/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js
+++ b/app/javascript/wardrobe-2020/WardrobePage/useOutfitState.js
@@ -4,7 +4,6 @@ import produce, { enableMapSet } from "immer";
import { useQuery, useApolloClient } from "@apollo/client";
import { itemAppearanceFragment } from "../components/useOutfitAppearance";
-import { useRouter } from "next/router";
enableMapSet();
@@ -382,25 +381,26 @@ const EMPTY_CUSTOMIZATION_STATE = {
};
function useParseOutfitUrl() {
- const { query } = useRouter();
+ const [searchParams] = useSearchParams();
// We memoize this to make `outfitStateWithoutExtras` an even more reliable
// stable object!
const memoizedOutfitState = React.useMemo(
- () => readOutfitStateFromQuery(query),
+ () => readOutfitStateFromSearchParams(searchParams),
[query]
);
return memoizedOutfitState;
}
-export function readOutfitStateFromQuery(query) {
+function readOutfitStateFromSearchParams(searchParams) {
// For the /outfits/:id page, ignore the query string, and just wait for the
// outfit data to load in!
- if (query.outfitId != null) {
+ const outfitId = searchParams.get("outfitId");
+ if (outfitId != null) {
return {
...EMPTY_CUSTOMIZATION_STATE,
- id: query.outfitId,
+ id: outfitId,
};
}
@@ -408,52 +408,16 @@ export function readOutfitStateFromQuery(query) {
// not specified.
return {
id: null,
- name: getValueFromQuery(query.name),
- speciesId: getValueFromQuery(query.species) || "1",
- colorId: getValueFromQuery(query.color) || "8",
- pose: getValueFromQuery(query.pose) || "HAPPY_FEM",
- appearanceId: getValueFromQuery(query.state) || null,
- wornItemIds: new Set(getListFromQuery(query["objects[]"])),
- closetedItemIds: new Set(getListFromQuery(query["closet[]"])),
+ name: searchParams.get("name"),
+ speciesId: searchParams.get("species") || "1",
+ colorId: searchParams.get("color") || "8",
+ pose: searchParams.get("pose") || "HAPPY_FEM",
+ appearanceId: searchParams.get("state") || null,
+ wornItemIds: new Set(searchParams.getAll("objects[]")),
+ closetedItemIds: new Set(searchParams.getAll("closet[]")),
};
}
-/**
- * getValueFromQuery reads the given value from Next's `router.query` as a
- * single value. For example:
- *
- * ?foo=bar -> "bar" -> "bar"
- * ?foo=bar&foo=baz -> ["bar", "baz"] -> "bar"
- * ?lol=huh -> undefined -> null
- */
-function getValueFromQuery(value) {
- if (Array.isArray(value)) {
- return value[0];
- } else if (value != null) {
- return value;
- } else {
- return null;
- }
-}
-
-/**
- * getListFromQuery reads the given value from Next's `router.query` as a list
- * of values. For example:
- *
- * ?foo=bar -> "bar" -> ["bar"]
- * ?foo=bar&foo=baz -> ["bar", "baz"] -> ["bar", "baz"]
- * ?lol=huh -> undefined -> []
- */
-function getListFromQuery(value) {
- if (Array.isArray(value)) {
- return value;
- } else if (value != null) {
- return [value];
- } else {
- return [];
- }
-}
-
function getOutfitStateFromOutfitData(outfit) {
if (!outfit) {
return EMPTY_CUSTOMIZATION_STATE;
diff --git a/app/javascript/wardrobe-2020/components/PaginationToolbar.js b/app/javascript/wardrobe-2020/components/PaginationToolbar.js
index bf600b45..4c7d45c1 100644
--- a/app/javascript/wardrobe-2020/components/PaginationToolbar.js
+++ b/app/javascript/wardrobe-2020/components/PaginationToolbar.js
@@ -1,6 +1,6 @@
import React from "react";
import { Box, Button, Flex, Select } from "@chakra-ui/react";
-import { useRouter } from "next/router";
+import { useSearchParams } from "react-router-dom";
function PaginationToolbar({
isLoading,
@@ -72,9 +72,9 @@ function PaginationToolbar({
}
export function useRouterPagination(totalCount, numPerPage) {
- const { query, push: pushHistory } = useRouter();
+ const [searchParams, setSearchParams] = useSearchParams();
- const currentOffset = parseInt(query.offset) || 0;
+ const currentOffset = parseInt(searchParams.get("offset")) || 0;
const currentPageIndex = Math.floor(currentOffset / numPerPage);
const currentPageNumber = currentPageIndex + 1;
@@ -82,11 +82,12 @@ export function useRouterPagination(totalCount, numPerPage) {
const buildPageUrl = React.useCallback(
(newPageNumber) => {
- const newParams = new URLSearchParams(query);
- const newPageIndex = newPageNumber - 1;
- const newOffset = newPageIndex * numPerPage;
- newParams.set("offset", newOffset);
- return "?" + newParams.toString();
+ setSearchParams((newParams) => {
+ const newPageIndex = newPageNumber - 1;
+ const newOffset = newPageIndex * numPerPage;
+ newParams.set("offset", newOffset);
+ return newParams;
+ });
},
[query, numPerPage]
);
diff --git a/app/javascript/wardrobe-2020/components/SquareItemCard.js b/app/javascript/wardrobe-2020/components/SquareItemCard.js
index f4caf56b..f0530041 100644
--- a/app/javascript/wardrobe-2020/components/SquareItemCard.js
+++ b/app/javascript/wardrobe-2020/components/SquareItemCard.js
@@ -225,7 +225,6 @@ function ItemThumbnail({ item, tradeMatchingMode }) {
position: relative;
`}
>
- {/* eslint-disable-next-line @next/next/no-img-element */}
[:new, :create], :path => 'neopets-users'
end
- get '/users/current-user/outfits' => 'outfits#index', :as => :current_user_outfits
+ get '/your-outfits', to: 'outfits#index', as: :current_user_outfits
+ get '/users/current-user/outfits', to: redirect('/your-outfits')
post '/pets/load' => 'pets#load', :as => :load_pet
post '/pets/submit' => 'pets#submit', :method => :post