Skip to content

Commit

Permalink
EMFXD-0000: Refactor global state (#20)
Browse files Browse the repository at this point in the history
* feat: ♻️ refactorize all global state of the card maker from context to zustand+immer
  • Loading branch information
michyaraque authored Dec 26, 2022
1 parent 3392048 commit 78c74e4
Show file tree
Hide file tree
Showing 75 changed files with 955 additions and 910 deletions.
4 changes: 2 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ module.exports = {
localeDetection: true,
}, */
trailingSlash: true,
reactStrictMode: true,
};
reactStrictMode: false,
};
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "card-maker",
"version": "0.0.1",
"name": "foxtrot-dashboard",
"version": "1.1.0",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down Expand Up @@ -32,6 +32,7 @@
"html-to-draftjs": "^1.5.0",
"html-to-image": "^1.9.0",
"html-to-react": "^1.5.0",
"immer": "^9.0.16",
"next": "^12.3.1",
"notiflix": "^3.2.5",
"re-resizable": "^6.9.9",
Expand All @@ -41,7 +42,8 @@
"react-hook-form": "^7.33.1",
"react-icons": "^4.4.0",
"react-scripts": "2.1.1",
"save-svg-as-png": "^1.4.17"
"save-svg-as-png": "^1.4.17",
"zustand": "^4.1.5"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^3.3.1",
Expand Down
22 changes: 0 additions & 22 deletions src/components/CardGame/Frame.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions src/components/Common/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
Avatar,
AvatarBadge,
Box,
Button,
Link as ChakraLink,
Collapse,
Flex,
Expand All @@ -22,7 +21,6 @@ import {
PopoverTrigger,
Stack,
Text,
WrapItem,
useBreakpointValue,
useColorModeValue,
useDisclosure,
Expand Down
12 changes: 10 additions & 2 deletions src/components/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ const DropdownMenu = ({
w="fit-content"
/>
</PopoverTrigger>
<PopoverContent w="fit-content" _focus={{ boxShadow: "none" }}>
<PopoverArrow />
<PopoverContent
w="fit-content"
_focus={{ boxShadow: "none" }}
backgroundColor="neutrals.900"
borderColor="neutrals.800"
>
<PopoverArrow
backgroundColor="neutrals.900"
borderColor="neutrals.800"
/>
<PopoverBody>
<Stack>
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from "react";

import { Center, Spinner } from "@chakra-ui/react";

const LoadingContent = () => (
Expand Down
2 changes: 1 addition & 1 deletion src/components/SliderOpacity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Props = {
sliderValue: number;
defaultValue?: number;
setSliderValue: (val: number) => void;
}
};

const SliderOpacity = ({
sliderValue = 60,
Expand Down
7 changes: 3 additions & 4 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export { default as Attack } from "./CardGame/Stats/Attack";
export { default as Health } from "./CardGame/Stats/Health";
export { default as Mana } from "./CardGame/Stats/Mana";
export * from "./CardGame";
export { default as Attack } from "../features/FoxtrotCardMaker/components/Parts/Stats/Attack";
export { default as Health } from "../features/FoxtrotCardMaker/components/Parts/Stats/Health";
export { default as Mana } from "../features/FoxtrotCardMaker/components/Parts/Stats/Mana";
export { default as Layout } from "./Common/Layout";
export { default as Navbar } from "./Common/Navbar";
export { default as DropdownMenu } from "./DropdownMenu";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import React, { useState } from "react";

import { Box, Flex } from "@chakra-ui/react";
import DropdownMenu from "components/DropdownMenu";

import { CardGeneratorForm, CardView } from "./components";
import InstagramPostCardVariant from "./variants/InstagramPostCardVariant";
import InstagramStoriesCardVariant from "./variants/InstagramStoriesCardVariant";
import {
CardGeneratorForm,
CardView,
} from "features/FoxtrotCardMaker/components";
import InstagramPostCardVariant from "features/FoxtrotCardMaker/components/InstagramPostCardVariant";
import InstagramStoriesCardVariant from "features/FoxtrotCardMaker/components/InstagramStoriesCardVariant";

const CardPage = () => {
const [isFrameVisible, setFrameVisibility] = useState<boolean>(true);
Expand Down
73 changes: 73 additions & 0 deletions src/features/FoxtrotCardMaker/components/CardGeneratorForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Box, Divider, Flex } from "@chakra-ui/react";

import {
DescriptionEditor,
FactionSelection,
ImageUpload,
NameInput,
QualitySelector,
RaritySelector,
StatsInput,
TypeSelector,
} from ".";

const CardGeneratorForm = () => {
return (
<Flex direction="column" w={{ base: "100%", md: "auto" }}>
<Box
mt="0"
height="100%"
w="100%"
bg="whiteAlpha.100"
p="20px"
borderRadius={8}
>
<Flex flexDirection="column" justify="space-between" h="100%">
<Box>
<Flex direction={{ base: "column", lg: "row" }} gap={2}>
<NameInput />
<StatsInput />
</Flex>

<Flex
mt={4}
gap={{ base: 4, md: 0 }}
direction={{ base: "column", lg: "row" }}
>
<Box w={{ base: "100%", lg: "50%" }}>
<DescriptionEditor />
</Box>

<Flex
direction={{ base: "row", lg: "column" }}
gap={2}
w={{ base: "100%", lg: "50%" }}
pl={{ base: 0, lg: 6 }}
>
<ImageUpload />
<TypeSelector />
</Flex>
</Flex>

<Flex
gap={4}
mt="10px"
direction="column"
w="100%"
position="relative"
>
<FactionSelection />
<RaritySelector />
</Flex>
</Box>
<Flex justify="flex-end" flexDirection="column">
<Divider mt="14px" />
<QualitySelector key="main_card_selector" />
</Flex>
</Flex>
</Box>
</Flex>
);
};

export default CardGeneratorForm;
63 changes: 63 additions & 0 deletions src/features/FoxtrotCardMaker/components/CardView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BoxProps } from "@chakra-ui/react";
import LoadingContent from "components/LoadingContent";
import { convertToRaw } from "draft-js";
import draftToHtml from "draftjs-to-html";
import {
Attack,
CardWrapper,
Description,
Frame,
Health,
Image,
Mana,
Title,
Type,
} from "features/FoxtrotCardMaker/components/Parts";
import {
CardType,
WRAPPER_ID,
} from "features/FoxtrotCardMaker/constants/cards";
import { useCardStore } from "features/FoxtrotCardMaker/stores/CardStore";

type Props = BoxProps & {
showFrame?: boolean;
};

const CardView = ({ showFrame = true }: Props) => {
const { cardState, loadingState, editorState } = useCardStore();
return (
<>
{loadingState.cardContent && <LoadingContent />}

<CardWrapper id={WRAPPER_ID} opacity={loadingState.cardContent ? 0.4 : 1}>
<Image image={cardState.selectedImage!} id="FXD" />

<Description rich>
{editorState
? draftToHtml(convertToRaw(editorState?.getCurrentContent()))
: ""}
</Description>
<Title text={cardState?.name} />

{showFrame && (
<>
<Frame
image={`/images/parts/frames/${cardState.rarity}/${cardState.faction}.png`}
/>
<Mana value={cardState.stats.mana} />

{cardState.type?.toLowerCase() !== CardType.TACTIC && (
<>
<Health value={cardState.stats.health} />
<Attack value={cardState.stats.attack} />
</>
)}
</>
)}
<Type value={cardState.type} />
</CardWrapper>
</>
);
};

export default CardView;
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import dynamic from "next/dynamic";

import React, { useContext } from "react";

import { Box } from "@chakra-ui/react";
import { useCardStore } from "features/FoxtrotCardMaker/stores/CardStore";
import { EditorProps } from "react-draft-wysiwyg";
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
import EditorCardContext, { EditorCardContextType } from "views/Generators/CardGenerator/context/EditorCardContext";

const Editor = dynamic<EditorProps>(
() => import("react-draft-wysiwyg").then((mod) => mod.Editor),
{ ssr: false }
);

const DescriptionEditor = () => {
const { editorState, onEditorStateChange } = useContext(EditorCardContext) as EditorCardContextType;
const { editorState, setEditorState } = useCardStore();

return (
<Box>
Expand All @@ -32,7 +30,7 @@ const DescriptionEditor = () => {
toolbarClassName="editor-toolbar"
wrapperClassName="editor-wrapper"
editorClassName="editor-box"
onEditorStateChange={onEditorStateChange}
onEditorStateChange={(state) => setEditorState(state)}
/>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from "react";

import { Button, ButtonProps } from "@chakra-ui/react";
import { onCapture } from "utils";

Expand Down
28 changes: 28 additions & 0 deletions src/features/FoxtrotCardMaker/components/Form/FactionSelection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Flex, HStack, Radio, RadioGroup } from "@chakra-ui/react";
import { factionCheckbox } from "features/FoxtrotCardMaker/constants/cards";
import { useCardStore } from "features/FoxtrotCardMaker/stores/CardStore";
import { TCardFaction } from "features/FoxtrotCardMaker/types/cards";
import { capitalize } from "utils";

const FactionSelection = () => {
const { cardState, setFaction } = useCardStore();

return (
<Flex direction="column" gap={4} w="100%" position="relative">
<RadioGroup
onChange={(value) => setFaction(value as TCardFaction)}
value={cardState.faction}
>
<HStack flexWrap="wrap">
{factionCheckbox.map(({ name, isDisabled }, index: number) => (
<Radio value={capitalize(name)} key={index} isDisabled={isDisabled}>
{capitalize(name)}
</Radio>
))}
</HStack>
</RadioGroup>
</Flex>
);
};

export default FactionSelection;
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import React, { useContext, useState } from "react";

import { PlusSquareIcon } from "@chakra-ui/icons";
import { Box, Image as ChakraImage, Flex, Input, Text } from "@chakra-ui/react";
import { useCardStore } from "features/FoxtrotCardMaker/stores/CardStore";
import { Notify } from "notiflix";
import CardContext from "views/Generators/CardGenerator/context/CardContext";

const ImageUpload = () => {
const { selectedImage, setSelectedImage } = useContext(CardContext);
const { cardState, setImage } = useCardStore();

const imageHandler = (
event: React.ChangeEvent<HTMLSelectElement | HTMLInputElement>
Expand All @@ -16,8 +14,8 @@ const ImageUpload = () => {
return Notify.failure("Prueba con otro tipo de imagen");
}
const reader = new FileReader();
reader.onload = function (e: any) {
setSelectedImage(e.target.result);
reader.onload = function (event: ProgressEvent<FileReader>) {
setImage(event?.target?.result);
};
reader.readAsDataURL(event.target.files[0]);
}
Expand Down Expand Up @@ -52,9 +50,9 @@ const ImageUpload = () => {
<Text whiteSpace="nowrap">Subir imagen</Text>
</Box>

{selectedImage ? (
{cardState.selectedImage ? (
<ChakraImage
src={selectedImage}
src={cardState.selectedImage}
w="32px"
h="32px"
minW="32px"
Expand Down
Loading

0 comments on commit 78c74e4

Please sign in to comment.