diff --git a/src/components/compose/Container.tsx b/src/components/compose/Container.tsx index aeda574..c43924b 100644 --- a/src/components/compose/Container.tsx +++ b/src/components/compose/Container.tsx @@ -1,14 +1,9 @@ import type { UniqueIdentifier } from "@dnd-kit/core"; import { useDroppable } from "@dnd-kit/core"; -import { - SortableContext, - verticalListSortingStrategy, -} from "@dnd-kit/sortable"; import { createContext, memo, type FC } from "react"; -import { ExerciseView, composeStore } from "@/util/composeStore"; import { Stack } from "@mui/material"; -import SortableItem from "./SortableItem"; +import { Item } from "./Item"; export const ContainerContext = createContext(null); @@ -16,32 +11,22 @@ const Container: FC<{ items: UniqueIdentifier[]; id: string }> = ({ items, id, }) => { - const exerciseView = composeStore((state) => state.exerciseView); const { setNodeRef } = useDroppable({ id: id, }); return ( - - - - {items.map((cardId: UniqueIdentifier) => ( - - ))} - - - + + {items.map((cardId: UniqueIdentifier) => ( + + ))} + ); }; diff --git a/src/components/compose/ExerciseCard.tsx b/src/components/compose/ExerciseCard.tsx index dba3208..f3673fe 100644 --- a/src/components/compose/ExerciseCard.tsx +++ b/src/components/compose/ExerciseCard.tsx @@ -8,7 +8,7 @@ import { Card, Chip, Divider, - Grid, + Grid2, IconButton, Stack, Tooltip, @@ -16,7 +16,7 @@ import { } from "@mui/material"; import { useAtomValue } from "jotai"; import { entries } from "lodash"; -import { FC, useContext, useMemo } from "react"; +import { FC, memo, useContext, useMemo } from "react"; import { MdEdit, MdStar } from "react-icons/md"; import FakeId from "../FakeId"; import { ContainerContext } from "./Container"; @@ -28,7 +28,6 @@ const ExerciseCard: FC<{ exercise: SelectExerciseQuery["exercise"] & { id: string }; }> = ({ exercise, isTalon, isDragging }) => { const containerId = useContext(ContainerContext); - const highlightedid = composeStore((state) => state.highlightedid); const view = composeStore((state) => state.view); const exerciseView = composeStore((state) => state.exerciseView); const placements = useAtomValue(exercisePlacementsAtom); @@ -63,7 +62,6 @@ const ExerciseCard: FC<{ return ( { - // setHighlightedid(exercise.id); - // }} - // onMouseLeave={() => { - // setHighlightedid(null); - // }} > )} - + + + {isSingleView && exercise.tags.map((tag) => ( @@ -165,9 +158,9 @@ const ExerciseCard: FC<{ {isDetailedView && ( <> - + {exercise.helpingQuestions.length > 0 && ( - + Segítőkérdések:
    {exercise.helpingQuestions.map((question) => ( @@ -178,10 +171,10 @@ const ExerciseCard: FC<{ ))}
-
+
)} {exercise.solutionOptions.length > 0 && ( - + Válaszopciók:
    {exercise.solutionOptions.map((question) => ( @@ -192,9 +185,9 @@ const ExerciseCard: FC<{ ))}
-
+ )} -
+ Megoldás: {exercise.solution} @@ -209,4 +202,5 @@ const ExerciseCard: FC<{ ); }; -export default ExerciseCard; +const MemoizedExerciseCard = memo(ExerciseCard); +export default MemoizedExerciseCard; diff --git a/src/components/compose/SortableItem.tsx b/src/components/compose/Item.tsx similarity index 61% rename from src/components/compose/SortableItem.tsx rename to src/components/compose/Item.tsx index e212975..057c0ad 100644 --- a/src/components/compose/SortableItem.tsx +++ b/src/components/compose/Item.tsx @@ -1,18 +1,13 @@ import ExerciseCard from "@/components/compose/ExerciseCard"; +import { useSelectExerciseQuery } from "@/generated/graphql.tsx"; import type { UniqueIdentifier } from "@dnd-kit/core"; -import { useSortable } from "@dnd-kit/sortable"; -import { CSS } from "@dnd-kit/utilities"; import { Card, Stack, Typography } from "@mui/material"; -import type { FC } from "react"; -import { useSelectExerciseQuery } from "@/generated/graphql.tsx"; +import { FC, memo } from "react"; export const Item: FC<{ id: UniqueIdentifier; isDragging?: boolean; }> = ({ id, isDragging = false }) => { - //const exercises = useAtomValue(exerciseCardsAtom); - //const exercise = exercises.find((exercise) => exercise.id === id); - const { data, loading } = useSelectExerciseQuery({ variables: { exerciseId: String(id), @@ -49,27 +44,5 @@ export const Item: FC<{ ); }; -const SortableItem: FC<{ id: UniqueIdentifier }> = ({ id }) => { - const { - attributes, - listeners, - setNodeRef, - transform, - transition, - isDragging, - } = useSortable({ id: id }); - - const style = { - transform: CSS.Transform.toString(transform), - transition, - alignSelf: "stretch", - }; - - return ( -
- -
- ); -}; - -export default SortableItem; +const MemoizedItem = memo(Item); +export default MemoizedItem; diff --git a/src/generated/graphql.tsx b/src/generated/graphql.tsx index c94a755..cffbf2a 100644 --- a/src/generated/graphql.tsx +++ b/src/generated/graphql.tsx @@ -659,6 +659,14 @@ export type UpdateExerciseMutationVariables = Exact<{ export type UpdateExerciseMutation = { __typename: 'Mutation', updateExercise: { __typename: 'Exercise', id: string } }; +export type UpdateExerciseSheetMutationVariables = Exact<{ + updateExerciseSheetId: Scalars['ID']['input']; + sheetData: UpdateExerciseSheetInput; +}>; + + +export type UpdateExerciseSheetMutation = { __typename: 'Mutation', updateExerciseSheet: { __typename: 'ExerciseSheet', id: string } }; + export type UpdateUserMutationVariables = Exact<{ data: UserUpdateInput; }>; @@ -1598,6 +1606,40 @@ export function useUpdateExerciseMutation(baseOptions?: Apollo.MutationHookOptio export type UpdateExerciseMutationHookResult = ReturnType; export type UpdateExerciseMutationResult = Apollo.MutationResult; export type UpdateExerciseMutationOptions = Apollo.BaseMutationOptions; +export const UpdateExerciseSheetDocument = gql` + mutation updateExerciseSheet($updateExerciseSheetId: ID!, $sheetData: UpdateExerciseSheetInput!) { + updateExerciseSheet(id: $updateExerciseSheetId, sheetData: $sheetData) { + id + } +} + `; +export type UpdateExerciseSheetMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateExerciseSheetMutation__ + * + * To run a mutation, you first call `useUpdateExerciseSheetMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateExerciseSheetMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateExerciseSheetMutation, { data, loading, error }] = useUpdateExerciseSheetMutation({ + * variables: { + * updateExerciseSheetId: // value for 'updateExerciseSheetId' + * sheetData: // value for 'sheetData' + * }, + * }); + */ +export function useUpdateExerciseSheetMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateExerciseSheetDocument, options); + } +export type UpdateExerciseSheetMutationHookResult = ReturnType; +export type UpdateExerciseSheetMutationResult = Apollo.MutationResult; +export type UpdateExerciseSheetMutationOptions = Apollo.BaseMutationOptions; export const UpdateUserDocument = gql` mutation UpdateUser($data: UserUpdateInput!) { updateUser(data: $data) { diff --git a/src/graphql/updateExerciseSheet.graphql b/src/graphql/updateExerciseSheet.graphql new file mode 100644 index 0000000..802b07a --- /dev/null +++ b/src/graphql/updateExerciseSheet.graphql @@ -0,0 +1,8 @@ +mutation updateExerciseSheet( + $updateExerciseSheetId: ID! + $sheetData: UpdateExerciseSheetInput! +) { + updateExerciseSheet(id: $updateExerciseSheetId, sheetData: $sheetData) { + id + } +} diff --git a/src/pages/compose/Compose.tsx b/src/pages/compose/Compose.tsx index 88abede..8fe3c09 100644 --- a/src/pages/compose/Compose.tsx +++ b/src/pages/compose/Compose.tsx @@ -1,39 +1,12 @@ -import type { - CollisionDetection, - DragEndEvent, - DragOverEvent, - DragStartEvent, - UniqueIdentifier, -} from "@dnd-kit/core"; -import { - closestCenter, - DndContext, - DragOverlay, - getFirstCollision, - KeyboardSensor, - MeasuringStrategy, - MouseSensor, - pointerWithin, - rectIntersection, - TouchSensor, - useSensor, - useSensors, -} from "@dnd-kit/core"; -import { arrayMove, sortableKeyboardCoordinates } from "@dnd-kit/sortable"; -import { FC, Fragment, useCallback, useEffect, useRef, useState } from "react"; +import type { UniqueIdentifier } from "@dnd-kit/core"; +import { FC, Fragment, useEffect } from "react"; -import { Item } from "@/components/compose/SortableItem"; import Talon from "@/components/compose/Talon"; -import { ExerciseAgeGroup, ExerciseSheetQuery } from "@/generated/graphql"; -import { - composeAtom, - exerciseCardsAtom, - exercisePlacementsAtom, -} from "@/util/atoms"; +import { ExerciseSheetQuery } from "@/generated/graphql"; +import { composeAtom } from "@/util/atoms"; import { composeStore, ExerciseView } from "@/util/composeStore"; -import { ExercisePlacements } from "@/util/types"; -import { Box, Grid, Stack, Typography } from "@mui/material"; -import { useAtom, useSetAtom } from "jotai"; +import { Box, Grid2, Stack, Typography } from "@mui/material"; +import { useAtom } from "jotai"; import { entries, keys, times } from "lodash"; import { useImmer } from "use-immer"; import Container from "../../components/compose/Container"; @@ -41,12 +14,10 @@ import Container from "../../components/compose/Container"; const Compose: FC<{ exerciseSheet?: ExerciseSheetQuery["exerciseSheet"] | null; }> = ({ exerciseSheet }) => { - const [talon, setTalon] = useImmer(["1", "2", "3"]); - const [exercises, setExercises] = useAtom(exerciseCardsAtom); + const [talon] = useImmer(["1", "2", "3"]); const view = composeStore((state) => state.view); const exerciseView = composeStore((state) => state.exerciseView); const [items, setItems] = useAtom(composeAtom); - const setPlacements = useSetAtom(exercisePlacementsAtom); useEffect(() => { setItems((draft) => { @@ -58,404 +29,60 @@ const Compose: FC<{ }, [exerciseSheet], ); - return draft; }); - }, [exerciseSheet?.sheetItems, setItems]); - - //console.log({ items }); - - // Use the defined sensors for drag and drop operation - const sensors = useSensors( - useSensor(MouseSensor, { - activationConstraint: { - // Require mouse to move 5px to start dragging, this allow onClick to be triggered on click - distance: 5, - }, - }), - useSensor(TouchSensor, { - activationConstraint: { - // Require mouse to move 5px to start dragging, this allow onClick to be triggered on click - tolerance: 5, - // Require to press for 100ms to start dragging, this can reduce the chance of dragging accidentally due to page scroll - delay: 100, - }, - }), - useSensor(KeyboardSensor, { - coordinateGetter: sortableKeyboardCoordinates, - }), - ); - - const [activeId, setActiveId] = useState(null); - - const lastOverId = useRef(null); - - // Ref to track if an item was just moved to a new container - const recentlyMovedToNewContainer = useRef(false); - - // Function to find which container an item belongs to - const findContainer = useCallback( - (id: UniqueIdentifier, options?: { excludeTalon: boolean }) => { - if (id === "talon") return id; - if (!options?.excludeTalon && talon.includes(id)) return "talon"; - // if the id is a container id itself - if (id in items) return id; - // find the container by looking into each of them - return Object.keys(items).find((key) => items[key].includes(id)); - }, - [items, talon], - ); - - // Ref to store the state of items before a drag operation begins - const itemsBeforeDrag = useRef(null); - - const insertCopyToTalon = useCallback( - (id: UniqueIdentifier) => { - console.log("insertCopyToTalon", { - id, - }); - const talonIndex = talon.indexOf(id); - const exercise = exercises.find((item) => item.id === id)!; - const newId = id + "."; - const newExercise = { - ...exercise, - id: newId, - }; - setExercises((draft) => { - draft.push(newExercise); - }); - setTalon((draft) => { - draft.splice(talonIndex, 1, newId); - }); - }, - [setExercises, exercises, setTalon, talon], - ); - - const updatePlacements = useCallback(() => { - const placements: ExercisePlacements = {}; - entries(items).forEach(([group, cards]) => { - cards.forEach((id) => { - const exercise = exercises.find((exercise) => exercise.id === id)?.data; - if (exercise) { - if (!placements[exercise.id]) { - placements[exercise.id] = { - KOALA: 0, - MEDVEBOCS: 0, - KISMEDVE: 0, - NAGYMEDVE: 0, - JEGESMEDVE: 0, - }; - } - placements[exercise.id][group.split("-")[0] as ExerciseAgeGroup]++; - } - }); - }); - setPlacements(placements); - }, [exercises, items, setPlacements]); - - // Function called when a drag operation begins - const handleDragStart = useCallback( - ({ active }: DragStartEvent) => { - // Store the current state of items - itemsBeforeDrag.current = { ...items }; - // Set the active (dragged) item id - setActiveId(active.id); - }, - [items], - ); - - // Function called when an item is dragged over another container - const handleDragOver = useCallback( - ({ active, over }: DragOverEvent) => { - if (!over || active.id in items) { - return; - } - - const { id: activeId } = active; - const { id: overId } = over; - - const activeContainer = findContainer(activeId); - const overContainer = findContainer(overId); - - // console.log("handleDragOver", { - // activeId, - // activeContainer, - // overContainer, - // }); - - if (!overContainer || !activeContainer) { - return; - } - if (overContainer === "talon") { - return; - } - if (activeContainer === "talon") { - setItems((items) => { - // clear duplicate items - for (const key in items) { - items[key] = items[key].filter((id) => id !== activeId); - } - const overItems = items[overContainer]; - const overIndex = overItems.indexOf(overId); - - const isBelowOverItem = - over && - active.rect.current.translated && - active.rect.current.translated.top > - over.rect.top + over.rect.height; - - const modifier = isBelowOverItem ? 1 : 0; - - const newIndex = - overIndex >= 0 ? overIndex + modifier : overItems.length + 1; - - recentlyMovedToNewContainer.current = true; - - items[overContainer] = [ - ...items[overContainer].slice(0, newIndex), - activeId, - ...items[overContainer].slice( - newIndex, - items[overContainer].length, - ), - ]; - }); - insertCopyToTalon(activeId); - } else if (activeContainer !== overContainer) { - setItems((items) => { - const activeItems = items[activeContainer]; - const overItems = items[overContainer]; - const overIndex = overItems.indexOf(overId); - const activeIndex = activeItems.indexOf(activeId); - - const isBelowOverItem = - over && - active.rect.current.translated && - active.rect.current.translated.top > - over.rect.top + over.rect.height; - - const modifier = isBelowOverItem ? 1 : 0; - - const newIndex = - overIndex >= 0 ? overIndex + modifier : overItems.length + 1; - - recentlyMovedToNewContainer.current = true; - - const activeTemp = items[activeContainer].filter( - (item) => item !== active.id, - ); - const overTemp = [ - ...items[overContainer].slice(0, newIndex), - items[activeContainer][activeIndex], - ...items[overContainer].slice( - newIndex, - items[overContainer].length, - ), - ]; - // update - items[activeContainer] = activeTemp; - items[overContainer] = overTemp; - }); - } - }, - [items, findContainer, setItems, insertCopyToTalon], - ); - - // Function called when a drag operation ends - const handleDragEnd = useCallback( - ({ active, over }: DragEndEvent) => { - const activeContainer = findContainer(active.id); - if (!over || !activeContainer) { - setActiveId(null); - return; - } - - const { id: activeId } = active; - const { id: overId } = over; - - const overContainer = findContainer(overId); - - if (!overContainer) { - setActiveId(null); - return; - } - //console.log("handleDragEnd", { activeContainer, active, over }); - - if (activeContainer === "talon") { - const overContainer = findContainer(overId, { excludeTalon: true }); - console.log("talon to", { overContainer }); - if (overContainer) { - const overIndex = items[overContainer].indexOf(overId); - setItems((items) => { - items[overContainer].splice(overIndex, 1, activeId); - }); - insertCopyToTalon(activeId); - } - } else { - const activeIndex = items[activeContainer].indexOf(activeId); - const overIndex = items[overContainer].indexOf(overId); - if (activeIndex !== overIndex) { - setItems((items) => ({ - ...items, - [overContainer]: arrayMove( - items[overContainer], - activeIndex, - overIndex, - ), - })); - } - } - updatePlacements(); - setActiveId(null); - }, - [findContainer, insertCopyToTalon, items, setItems, updatePlacements], - ); - - // Function called when a drag operation is cancelled - const onDragCancel = useCallback(() => { - console.log(itemsBeforeDrag.current); - setActiveId(null); - if (!itemsBeforeDrag.current) return; - setItems(() => itemsBeforeDrag.current); - itemsBeforeDrag.current = null; - }, [setItems]); - - /** - * Custom collision detection strategy optimized for multiple containers - * - First, find any droppable containers intersecting with the pointer. - * - If there are none, find intersecting containers with the active draggable. - * - If there are no intersecting containers, return the last matched intersection - */ - const collisionDetectionStrategy: CollisionDetection = useCallback( - (args) => { - if (activeId && activeId in items) { - return closestCenter({ - ...args, - droppableContainers: args.droppableContainers.filter( - (container) => container.id in items, - ), - }); - } - - // Start by finding any intersecting droppable - const pointerIntersections = pointerWithin(args); - const intersections = - pointerIntersections.length > 0 - ? // If there are droppables intersecting with the pointer, return those - pointerIntersections - : rectIntersection(args); - let overId = getFirstCollision(intersections, "id"); - - if (overId != null) { - if (overId in items) { - const containerItems = items[overId]; - - // If a container is matched and it contains items (columns 'A', 'B', 'C') - if (containerItems.length > 0) { - // Return the closest droppable within that container - overId = closestCenter({ - ...args, - droppableContainers: args.droppableContainers.filter( - (container) => - container.id !== overId && - containerItems.includes(container.id), - ), - })[0]?.id; - } - } - - lastOverId.current = overId; - - return [{ id: overId }]; - } - - // When a draggable item moves to a new container, the layout may shift - // and the `overId` may become `null`. We manually set the cached `lastOverId` - // to the id of the draggable item that was moved to the new container, otherwise - // the previous `overId` will be returned which can cause items to incorrectly shift positions - if (recentlyMovedToNewContainer.current) { - lastOverId.current = activeId; - } - - // If no droppable is matched, return the last match - return lastOverId.current ? [{ id: lastOverId.current }] : []; - }, - [activeId, items], - ); - - useEffect(() => { - requestAnimationFrame(() => { - recentlyMovedToNewContainer.current = false; - }); - }, [items]); + }, [exerciseSheet, exerciseSheet?.sheetItems, setItems]); return ( - - - - {view === "all" && ( - <> - - {times(5).map((i) => ( - - - {keys(items)[i].split("-")[0]} - - - ))} - - )} - {entries(items).map(([key, items], index) => { - return ( - - {index % 5 === 0 && ( - - - - {index === 0 && "Zöld"} - {index === 5 && "Bronz"} - {index === 10 && "Ezüst"} - {index === 15 && "Arany"} - - - - )} - {(view === "all" || key.split("-")[0] === view) && ( - - - - )} - - ); - })} - - {exerciseView !== ExerciseView.LIST && ( - - - + + + {view === "all" && ( + <> + + {times(5).map((i) => ( + + + {keys(items)[i].split("-")[0]} + + + ))} + )} - - {activeId ? : null} - - - + {entries(items).map(([key, items], index) => { + return ( + + {index % 5 === 0 && ( + + + + {index === 0 && "Zöld"} + {index === 5 && "Bronz"} + {index === 10 && "Ezüst"} + {index === 15 && "Arany"} + + + + )} + {(view === "all" || key.split("-")[0] === view) && ( + + + + )} + + ); + })} + + {exerciseView !== ExerciseView.LIST && ( + + + + )} +
); }; diff --git a/src/pages/compose/ComposePage.tsx b/src/pages/compose/ComposePage.tsx index c94a2be..9e354f5 100644 --- a/src/pages/compose/ComposePage.tsx +++ b/src/pages/compose/ComposePage.tsx @@ -1,6 +1,16 @@ +import { + ExerciseAgeGroup, + UpdateExerciseSheetInput, + useExerciseSheetQuery, + useUpdateExerciseSheetMutation, +} from "@/generated/graphql.tsx"; +import { composeAtom } from "@/util/atoms"; import { ExerciseView, composeStore } from "@/util/composeStore"; +import { LoadingButton } from "@mui/lab"; import { Box, + IconButton, + Input, Tab, Tabs, ToggleButton, @@ -8,33 +18,88 @@ import { Typography, } from "@mui/material"; import { Stack } from "@mui/system"; -import { FC } from "react"; -import Compose from "./Compose"; +import { useAtomValue } from "jotai"; +import { entries } from "lodash"; +import { useSnackbar } from "notistack"; +import { FC, useCallback } from "react"; +import { MdDone, MdEdit } from "react-icons/md"; import { useParams } from "react-router"; -import { useExerciseSheetQuery } from "@/generated/graphql.tsx"; +import { useToggle } from "react-use"; +import Compose from "./Compose"; const styles = { fontWeight: 500 }; const ComposePage: FC = () => { const { id } = useParams(); + const setName = composeStore((state) => state.setName); const exerciseSheetResult = useExerciseSheetQuery({ variables: { exerciseSheetId: id ?? "", }, + onCompleted: (data) => { + setName(data.exerciseSheet?.name ?? ""); + }, }); + const [mutate, mutationState] = useUpdateExerciseSheetMutation(); const view = composeStore((state) => state.view); const exerciseView = composeStore((state) => state.exerciseView); + const name = composeStore((state) => state.name); const setValue = composeStore((state) => state.setValue); const setView = composeStore((state) => state.setView); + const [isNameEditing, toggleNameEditing] = useToggle(false); + const items = useAtomValue(composeAtom); + const snack = useSnackbar(); + + const save = useCallback(async () => { + const data: UpdateExerciseSheetInput = { + name, + sheetItems: [], + }; + + entries(items).forEach(([key, exercises]) => { + const [ageGroup, level] = key.split("-"); + data.sheetItems?.push({ + ageGroup: ageGroup as ExerciseAgeGroup, + level: parseInt(level), + exercises: exercises as string[], + }); + }); + await mutate({ + variables: { + updateExerciseSheetId: id!, + sheetData: data, + }, + }); + snack.enqueueSnackbar("Mentve", { variant: "success" }); + toggleNameEditing(false); + }, [id, items, mutate, name, snack, toggleNameEditing]); return ( <> - - Feladatsor-összeállítás: {exerciseSheetResult.data?.exerciseSheet?.name} - - + {isNameEditing ? ( +
+ + setName(e.target.value)} + /> + + + + +
+ ) : ( + + {name} + + + + + )} + { - setValue({ exerciseView: value })} - > - + setValue({ exerciseView: value })} > - Kártya - - + Kártya + + + Lista + + + - Lista - - + Mentés + +
diff --git a/src/util/composeStore.ts b/src/util/composeStore.ts index fddf858..262080c 100644 --- a/src/util/composeStore.ts +++ b/src/util/composeStore.ts @@ -8,46 +8,37 @@ export enum ExerciseView { } type ComposeView = ExerciseAgeGroup | "all"; type TState = { - highlightedid: string | null; + selectedId: string | null; hoverLocation: string | null; hoverIndex: number | null; view: ComposeView; exerciseView: ExerciseView; + name: string; }; type TActions = { - setHighlightedid: (id: string | null) => void; - setHoverLocation: (location: string | null) => void; - setHoverIndex: (index: number | null) => void; + setSelectedId: (id: string | null) => void; setView: (view: ComposeView) => void; setExerciseView: (view: ExerciseView) => void; setValue: (values: Partial) => void; + setName: (name: string) => void; }; const defaultState: TState = { - highlightedid: null, + selectedId: null, hoverLocation: null, hoverIndex: null, view: "all", exerciseView: ExerciseView.CARD, + name: "", }; export const composeStore = create()( immer((set) => ({ ...defaultState, - setHighlightedid: (id) => { + setSelectedId: (id) => { set((state) => { - state.highlightedid = id; - }); - }, - setHoverLocation: (location) => { - set((state) => { - state.hoverLocation = location; - }); - }, - setHoverIndex: (index) => { - set((state) => { - state.hoverIndex = index; + state.selectedId = id; }); }, setView: (view) => { @@ -65,5 +56,10 @@ export const composeStore = create()( Object.assign(state, values); }); }, + setName: (name: string) => { + set((state) => { + state.name = name; + }); + }, })), );