diff --git a/components/Bag/Map/AddNewMapFields.tsx b/components/Bag/Map/AddNewMapFields.tsx new file mode 100644 index 0000000..041b532 --- /dev/null +++ b/components/Bag/Map/AddNewMapFields.tsx @@ -0,0 +1,97 @@ +import { MapData, useLocalMapStorage } from "@/lib/hooks"; +import { Box, Button, FormLabel, HStack, Input, Fade } from "@chakra-ui/react"; +import { useRouter } from "next/router"; +import { Dispatch, SetStateAction } from "react"; + +export const AddNewFields = ({ + newMap, + enterMapUrl, + setNewMap, +}: { + newMap?: MapData; + enterMapUrl: (value: string) => void; + setNewMap: Dispatch>; +}) => { + const { reload } = useRouter(); + const { add } = useLocalMapStorage(); + return ( + + Add new map + + enterMapUrl(e.target.value)} + placeholder="https://i.imgur.com/image.png" + maxW="300px" + /> + + + + {!!newMap?.imgUrl && ( + + + setNewMap((prev) => ({ + ...prev, + imgUrl: prev?.imgUrl ?? "", + meta: { + ...prev?.meta, + author: prev?.meta?.author, + title: e.target.value, + }, + })) + } + /> + + + setNewMap((prev) => ({ + ...prev, + imgUrl: prev?.imgUrl ?? "", + meta: { + ...prev?.meta, + author: e.target.value, + title: prev?.meta?.title ?? "", + }, + })) + } + /> + + + setNewMap((prev) => ({ + ...prev, + imgUrl: prev?.imgUrl ?? "", + meta: { + ...prev?.meta, + author: prev?.meta?.author, + title: prev?.meta?.title ?? "", + url: e.target.value, + }, + })) + } + /> + + )} + + + ); +}; diff --git a/components/Bag/Map/MapModal/defaultMaps.ts b/components/Bag/Map/MapModal/defaultMaps.ts new file mode 100644 index 0000000..bb89e50 --- /dev/null +++ b/components/Bag/Map/MapModal/defaultMaps.ts @@ -0,0 +1,77 @@ +import { MapData } from "@/lib/hooks"; + +const BASRA_PORT: MapData = { + imgUrl: "https://arweave.net/krw7LMQOBj2U0Zvw8HQllZYmKd21LH71tQAQ-1eiKX0", + meta: { + title: "Basra Port", + author: "wandering__caretaker", + url: "https://www.reddit.com/r/Unmatched/comments/k377lm/basra_port_custom_mapwork_in_progress/", + }, +}; + +const APERATURE_LABS: MapData = { + imgUrl: + "https://preview.redd.it/custom-map-apeprture-labs-v0-ho2occy3xncc1.png?width=1057&format=png&auto=webp&s=3bfd644a097d7685178993d8252315deafb7e6d2", + meta: { + title: "Aperature Labs", + author: "Vediano", + url: "https://www.reddit.com/r/Unmatched/comments/197ipt6/custom_map_apeprture_labs/", + }, +}; + +const FOREST_CASTLE: MapData = { + imgUrl: + "https://preview.redd.it/forest-castle-custom-map-v0-onjy0jwtxbhc1.png?width=3000&format=png&auto=webp&s=8744485e283ed179f91dc601e53e2a769818732e", + meta: { + title: "Forest Castle", + author: "Vediano", + url: "https://www.reddit.com/r/Unmatched/comments/1alrt42/forest_castle_custom_map/", + }, +}; + +const CANNON_RUN: MapData = { + imgUrl: + "https://preview.redd.it/til2jxmi8jb71.jpg?width=640&crop=smart&auto=webp&s=2fa5384e86a4ab6924ba14772c5f54b5921743de", + meta: { + title: "Cannon Run", + author: "dwaynemagicfingers", + url: "https://www.reddit.com/r/Unmatched/comments/olcf26/cannon_run_custom_map_rules_in_comments/", + }, +}; + +const MENDED_DRUM: MapData = { + imgUrl: "https://i.imgur.com/NXBcIZN.jpeg", + meta: { + title: "The Mended Drum", + author: "ANDSUSHI", + url: "https://www.reddit.com/r/Unmatched/comments/141l9dk/i_made_3_new_custom_maps_the_mended_drum_the/", + }, +}; + +const OPERA: MapData = { + imgUrl: "https://i.imgur.com/Jiul7zg.jpeg", + meta: { + title: "Opera House", + author: "ANDSUSHI", + url: "https://www.reddit.com/r/Unmatched/comments/141l9dk/i_made_3_new_custom_maps_the_mended_drum_the/", + }, +}; + +const THE_CHALK: MapData = { + imgUrl: "https://i.imgur.com/UP7EC0p.jpeg", + meta: { + title: "The Chalk", + author: "ANDSUSHI", + url: "https://www.reddit.com/r/Unmatched/comments/141l9dk/i_made_3_new_custom_maps_the_mended_drum_the/", + }, +}; + +export const DEFAULT_MAPS: MapData[] = [ + MENDED_DRUM, + OPERA, + THE_CHALK, + BASRA_PORT, + APERATURE_LABS, + FOREST_CASTLE, + CANNON_RUN, +]; diff --git a/components/Bag/Map/MapModal/index.tsx b/components/Bag/Map/MapModal/index.tsx new file mode 100644 index 0000000..83d291d --- /dev/null +++ b/components/Bag/Map/MapModal/index.tsx @@ -0,0 +1,120 @@ +import { MapData, useLocalMapStorage } from "@/lib/hooks"; +import { + Image, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalFooter, + ModalBody, + ModalCloseButton, + Grid, + VStack, + Text, + Divider, + Box, +} from "@chakra-ui/react"; +import { useRouter } from "next/router"; +import { DEFAULT_MAPS } from "./defaultMaps"; +import Link from "next/link"; + +export const MapModal = () => { + const { query, push } = useRouter(); + const queryUrl = query.mapUrl as string | undefined; + const { data } = useLocalMapStorage(); + + const selectedMap = [...data, ...DEFAULT_MAPS].find( + (map) => map.imgUrl === queryUrl, + ); + + return ( + { + const { editMapUrl, ...rest } = query; + push({ query: { ...rest } }); + }} + > + + + Browse your saved Maps + + + + + {data?.map((map) => ( + + push({ query: { ...query, mapUrl: map.imgUrl } }) + } + /> + ))} + + + Default Maps + + {DEFAULT_MAPS?.map((map) => ( + + push({ query: { ...query, mapUrl: map.imgUrl } }) + } + /> + ))} + + + + + {selectedMap?.meta?.title} + + {selectedMap?.meta?.author && ( + by {selectedMap?.meta?.author} + )} + + mappreview + + + + + + + + ); +}; + +const MapTitle = (props: { map: MapData; onClick: () => void }) => { + return ( + + {props.map.meta?.title} + + ); +}; diff --git a/components/Bag/Map/index.tsx b/components/Bag/Map/index.tsx index 1070a30..56f1e71 100644 --- a/components/Bag/Map/index.tsx +++ b/components/Bag/Map/index.tsx @@ -1,18 +1,24 @@ -import { MapData } from "@/lib/hooks"; +import { MapData, useLocalMapStorage } from "@/lib/hooks"; import { Text, Box, - Button, - FormLabel, - HStack, - Input, - Slide, - Fade, + Flex, Grid, + Image, + HStack, + Button, + Skeleton, } from "@chakra-ui/react"; import { useState } from "react"; +import { AddNewFields } from "./AddNewMapFields"; +import { LinkIcon } from "@chakra-ui/icons"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { MapModal } from "./MapModal"; +import { DEFAULT_MAPS } from "./MapModal/defaultMaps"; export const BagMap = () => { + const { data, clear } = useLocalMapStorage(); const [newMap, setNewMap] = useState(); function enterMapUrl(value?: string) { @@ -23,75 +29,67 @@ export const BagMap = () => { })); } return ( - - - Add new map - - enterMapUrl(e.target.value)} - placeholder="https://i.imgur.com/image.png" - maxW="300px" - /> - - - - {!!newMap?.imgUrl && ( - - - setNewMap((prev) => ({ - ...prev, - imgUrl: prev?.imgUrl ?? "", - meta: { - ...prev?.meta, - author: e.target.value, - title: prev?.meta?.title ?? "", - }, - })) - } - /> + + + + {newMap?.imgUrl ? ( + map-preview + ) : ( + + )} + + {data?.map((map) => )} + - - setNewMap((prev) => ({ - ...prev, - imgUrl: prev?.imgUrl ?? "", - meta: { - ...prev?.meta, - author: prev?.meta?.author, - title: e.target.value, - }, - })) - } - /> + + Default Homebrewed Maps + + {DEFAULT_MAPS?.map((map) => )} - - setNewMap((prev) => ({ - ...prev, - imgUrl: prev?.imgUrl ?? "", - meta: { - ...prev?.meta, - author: prev?.meta?.author, - title: prev?.meta?.title ?? "", - url: e.target.value, - }, - })) - } - /> - - )} - - + ); }; + +const MapCard = (map: MapData) => { + const { query, push } = useRouter(); + return ( + + + {map.meta?.title} + {map.meta?.author && by {map.meta.author}} + {map.meta?.url && ( + + + + )} + + { + push({ query: { ...query, mapUrl: map.imgUrl, editMapUrl: true } }); + }} + /> + + ); +}; diff --git a/components/Game/Header/map.modal.tsx b/components/Game/Header/map.modal.tsx index 80426b1..bf158aa 100644 --- a/components/Game/Header/map.modal.tsx +++ b/components/Game/Header/map.modal.tsx @@ -1,3 +1,5 @@ +import { MapModal as MapSelectorModal } from "@/components/Bag/Map/MapModal"; +import { DEFAULT_MAPS } from "@/components/Bag/Map/MapModal/defaultMaps"; import { Text, Modal, @@ -23,50 +25,63 @@ export const MapModal = (props: { isOpen: boolean; onClose: () => void }) => { const [url] = useDebounce(_url, 300); return ( - - - - Change the Map - - - Map Image URL - setUrl(e.target.value)} - /> + <> + + + + + Change the Map + + + Map Image URL + setUrl(e.target.value)} + /> - - Changes local only. Share map link with friends you are playing - with. - - - Recommended 1200x1000 - - {!url && } - {url && map} - + + Changes local only. Share map link with friends you are playing + with. + + + Recommended 1200x1000 + + {!url && } + {url && map} + - - - - - - + + + + + + + + ); }; diff --git a/lib/hooks/useLocalStorage.ts b/lib/hooks/useLocalStorage.ts index e54bdf6..6a9a82c 100644 --- a/lib/hooks/useLocalStorage.ts +++ b/lib/hooks/useLocalStorage.ts @@ -164,6 +164,12 @@ export const useLocalMapStorage = () => { setMapList(maps); }; + const addMap = (map: MapData) => { + const newMapsList = [...mapList, map]; + localStorage.setItem(LS_KEY.MAP_LIST, JSON.stringify(newMapsList)); + setMapList(newMapsList); + }; + function clearList() { localStorage.removeItem(LS_KEY.MAP_LIST); setMapList([]); @@ -172,6 +178,7 @@ export const useLocalMapStorage = () => { return { data: mapList, set: setList, + add: addMap, clear: clearList, }; }; diff --git a/pages/bag.tsx b/pages/bag.tsx index b95b967..19f55a4 100644 --- a/pages/bag.tsx +++ b/pages/bag.tsx @@ -21,7 +21,7 @@ const BagPage = () => { Decks - Maps + Maps