diff --git a/package-lock.json b/package-lock.json index cb653de..e52233d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@types/react-dom": "^18.2.17", "@vitejs/plugin-react": "^4.2.1", "autoprefixer": "^10.4.16", - "eslint": "^8.55.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", @@ -1111,22 +1111,25 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -1147,10 +1150,12 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", @@ -2317,9 +2322,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001570", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", - "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "dev": true, "funding": [ { @@ -2334,7 +2339,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/canvg": { "version": "3.0.10", @@ -2873,16 +2879,17 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", diff --git a/package.json b/package.json index 4e1bf2e..5ac3791 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@types/react-dom": "^18.2.17", "@vitejs/plugin-react": "^4.2.1", "autoprefixer": "^10.4.16", - "eslint": "^8.55.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", diff --git a/src/context/AreasContext.jsx b/src/context/AreasContext.jsx index cc020ba..cdfcba6 100644 --- a/src/context/AreasContext.jsx +++ b/src/context/AreasContext.jsx @@ -1,12 +1,23 @@ -import { createContext, useState } from "react"; -import { Action, ObjectType, defaultBlue } from "../data/constants"; -import { useUndoRedo, useTransform, useSelect } from "../hooks"; -import { Toast } from "@douyinfe/semi-ui"; -import { useTranslation } from "react-i18next"; +import React, { createContext, useState, ReactNode, useContext } from 'react'; +import PropTypes from 'prop-types'; +import { Action, ObjectType, defaultBlue } from '../data/constants'; +import { useUndoRedo, useTransform, useSelect } from '../hooks'; +import { Toast } from '@douyinfe/semi-ui'; +import { useTranslation } from 'react-i18next'; -export const AreasContext = createContext(null); +// Define context +export const AreasContext = createContext(null); // Ensure export is here -export default function AreasContextProvider({ children }) { +export const useAreasContext = () => { + const context = useContext(AreasContext); + if (!context) { + throw new Error('useAreasContext must be used within an AreasContextProvider'); + } + return context; +}; + +// AreasContextProvider component +const AreasContextProvider = ({ children }) => { const { t } = useTranslation(); const [areas, setAreas] = useState([]); const { transform } = useTransform(); @@ -15,86 +26,84 @@ export default function AreasContextProvider({ children }) { const addArea = (data, addToHistory = true) => { if (data) { - setAreas((prev) => { - const temp = prev.slice(); - temp.splice(data.id, 0, data); - return temp.map((t, i) => ({ ...t, id: i })); - }); + addExistingArea(data); } else { - const width = 200; - const height = 200; - setAreas((prev) => [ - ...prev, - { - id: prev.length, - name: `area_${prev.length}`, - x: transform.pan.x - width / 2, - y: transform.pan.y - height / 2, - width, - height, - color: defaultBlue, - }, - ]); + addNewArea(); } if (addToHistory) { - setUndoStack((prev) => [ - ...prev, - { - action: Action.ADD, - element: ObjectType.AREA, - message: t("add_area"), - }, - ]); - setRedoStack([]); + addActionToHistory(Action.ADD, ObjectType.AREA, t("add_area")); } }; + const addExistingArea = (data) => { + setAreas(prev => { + const updatedAreas = [...prev]; + updatedAreas.splice(data.id, 0, data); + return updatedAreas.map((area, i) => ({ ...area, id: i })); + }); + }; + + const addNewArea = () => { + const width = 200; + const height = 200; + setAreas(prev => [ + ...prev, + { + id: prev.length, + name: `area_${prev.length}`, + x: transform.pan.x - width / 2, + y: transform.pan.y - height / 2, + width, + height, + color: defaultBlue, + }, + ]); + }; + const deleteArea = (id, addToHistory = true) => { + if (id < 0 || id >= areas.length) return; // Handle invalid ID if (addToHistory) { Toast.success(t("area_deleted")); - setUndoStack((prev) => [ - ...prev, - { - action: Action.DELETE, - element: ObjectType.AREA, - data: areas[id], - message: t("delete_area", areas[id].name), - }, - ]); - setRedoStack([]); + addActionToHistory(Action.DELETE, ObjectType.AREA, t("delete_area", areas[id].name), areas[id]); } - setAreas((prev) => - prev.filter((e) => e.id !== id).map((e, i) => ({ ...e, id: i })), - ); + setAreas(prev => { + const filteredAreas = prev.filter(e => e.id !== id); + return filteredAreas.map((e, i) => ({ ...e, id: i })); + }); if (id === selectedElement.id) { - setSelectedElement((prev) => ({ - ...prev, - element: ObjectType.NONE, - id: -1, - open: false, - })); + clearSelectedElement(); } }; + const clearSelectedElement = () => { + setSelectedElement({ + element: ObjectType.NONE, + id: -1, + open: false, + }); + }; + const updateArea = (id, values) => { - setAreas((prev) => - prev.map((t) => { - if (t.id === id) { - return { - ...t, - ...values, - }; - } - return t; - }), - ); + setAreas(prev => prev.map(area => area.id === id ? { ...area, ...values } : area)); + }; + + const addActionToHistory = (action, element, message, data) => { + setUndoStack(prev => [ + ...prev, + { action, element, message, data }, + ]); + setRedoStack([]); }; return ( - + {children} ); -} +}; + +AreasContextProvider.propTypes = { + children: PropTypes.node.isRequired, +}; + +export default AreasContextProvider;