diff --git a/scripts/setup-mysql.sql b/scripts/setup-mysql.sql
index 4a5c8dc..2e13f90 100644
--- a/scripts/setup-mysql.sql
+++ b/scripts/setup-mysql.sql
@@ -25,7 +25,7 @@ GRANT INSERT, UPDATE ON swf_assets TO impress2020;
GRANT INSERT ON modeling_logs TO impress2020;
-- User data tables
-GRANT SELECT ON closet_hangers TO impress2020;
+GRANT SELECT, INSERT ON closet_hangers TO impress2020;
GRANT SELECT ON closet_lists TO impress2020;
GRANT SELECT ON item_outfit_relationships TO impress2020;
GRANT SELECT ON outfits TO impress2020;
diff --git a/src/app/ItemPage.js b/src/app/ItemPage.js
index 04fb96e..702aabe 100644
--- a/src/app/ItemPage.js
+++ b/src/app/ItemPage.js
@@ -25,7 +25,7 @@ import {
} from "@chakra-ui/icons";
import { MdPause, MdPlayArrow } from "react-icons/md";
import gql from "graphql-tag";
-import { useQuery } from "@apollo/client";
+import { useQuery, useMutation } from "@apollo/client";
import { useParams } from "react-router-dom";
import {
@@ -41,6 +41,7 @@ import {
} from "./components/useOutfitAppearance";
import OutfitPreview from "./components/OutfitPreview";
import SpeciesColorPicker from "./components/SpeciesColorPicker";
+import useCurrentUser from "./components/useCurrentUser";
import { useLocalStorage } from "./util";
import WIPCallout from "./components/WIPCallout";
@@ -55,10 +56,12 @@ function ItemPage() {
* `isEmbedded` prop is true, so we know not to e.g. set the page title.
*/
export function ItemPageContent({ itemId, isEmbedded }) {
+ const { isLoggedIn } = useCurrentUser();
+
return (
-
+ {isLoggedIn && }
{!isEmbedded && }
Trade lists coming soon!
@@ -311,10 +314,9 @@ function ItemPageOwnWantButtons({ itemId }) {
const theme = useTheme();
const toast = useToast();
- const [currentUserOwnsThis, setCurrentUserOwnsThis] = React.useState(false);
const [currentUserWantsThis, setCurrentUserWantsThis] = React.useState(false);
- const { loading, error } = useQuery(
+ const { loading, error, data } = useQuery(
gql`
query ItemPageOwnWantButtons($itemId: ID!) {
item(id: $itemId) {
@@ -327,7 +329,6 @@ function ItemPageOwnWantButtons({ itemId }) {
{
variables: { itemId },
onCompleted: (data) => {
- setCurrentUserOwnsThis(data?.item?.currentUserOwnsThis || false);
setCurrentUserWantsThis(data?.item?.currentUserWantsThis || false);
},
}
@@ -340,82 +341,172 @@ function ItemPageOwnWantButtons({ itemId }) {
return (
-
- {
- setCurrentUserOwnsThis(e.target.checked);
- toast({
- title: "Todo: This doesn't actually work yet!",
- status: "info",
- duration: 1500,
- });
- }}
- />
-
-
+
-
- {
- setCurrentUserWantsThis(e.target.checked);
- toast({
- title: "Todo: This doesn't actually work yet!",
- status: "info",
- duration: 1500,
- });
- }}
- />
-
-
+
);
}
+function ItemPageOwnButton({ itemId, isChecked }) {
+ const theme = useTheme();
+ const toast = useToast();
+
+ const [sendAddMutation] = useMutation(
+ gql`
+ mutation ItemPageOwnButtonAdd($itemId: ID!) {
+ addToItemsCurrentUserOwns(itemId: $itemId) {
+ id
+ currentUserOwnsThis
+ }
+ }
+ `,
+ {
+ variables: { itemId },
+ optimisticResponse: {
+ __typename: "Mutation",
+ addToItemsCurrentUserOwns: {
+ __typename: "Item",
+ id: itemId,
+ currentUserOwnsThis: true,
+ },
+ },
+ }
+ );
+
+ return (
+
+ {
+ if (e.target.checked) {
+ sendAddMutation().catch((e) => {
+ console.error(e);
+ toast({
+ title: "We had trouble adding this to the items you own.",
+ description: "Check your internet connection, and try again.",
+ status: "error",
+ duration: 5000,
+ });
+ });
+ } else {
+ toast({
+ title: "Todo: This doesn't actually work yet!",
+ status: "info",
+ duration: 1500,
+ });
+ }
+ }}
+ />
+
+
+ );
+}
+
+function ItemPageWantButton({ itemId, isChecked }) {
+ const theme = useTheme();
+ const toast = useToast();
+
+ const [sendAddMutation] = useMutation(
+ gql`
+ mutation ItemPageWantButtonAdd($itemId: ID!) {
+ addToItemsCurrentUserWants(itemId: $itemId) {
+ id
+ currentUserWantsThis
+ }
+ }
+ `,
+ {
+ variables: { itemId },
+ optimisticResponse: {
+ __typename: "Mutation",
+ addToItemsCurrentUserWants: {
+ __typename: "Item",
+ id: itemId,
+ currentUserWantsThis: true,
+ },
+ },
+ }
+ );
+
+ return (
+
+ {
+ if (e.target.checked) {
+ sendAddMutation().catch((e) => {
+ console.error(e);
+ toast({
+ title: "We had trouble adding this to the items you want.",
+ description: "Check your internet connection, and try again.",
+ status: "error",
+ duration: 5000,
+ });
+ });
+ } else {
+ toast({
+ title: "Todo: This doesn't actually work yet!",
+ status: "info",
+ duration: 1500,
+ });
+ }
+ }}
+ />
+
+
+ );
+}
+
function IconCheckbox({ icon, isChecked, ...props }) {
return (
diff --git a/src/app/components/useCurrentUser.js b/src/app/components/useCurrentUser.js
index f1b6666..26ee11b 100644
--- a/src/app/components/useCurrentUser.js
+++ b/src/app/components/useCurrentUser.js
@@ -4,7 +4,7 @@ function useCurrentUser() {
const { isLoading, isAuthenticated, user } = useAuth0();
if (isLoading || !isAuthenticated) {
- return { id: null, username: null };
+ return { id: null, username: null, isLoggedIn: false };
}
// NOTE: Users created correctly should have these attributes... but I'm
@@ -13,7 +13,7 @@ function useCurrentUser() {
const id = user.sub?.match(/^auth0\|impress-([0-9]+)$/)?.[1];
const username = user["https://oauth.impress-2020.openneo.net/username"];
- return { id, username };
+ return { id, username, isLoggedIn: true };
}
export default useCurrentUser;