From 0a21444ee45020323e7a62d31fa3879e3dc29b15 Mon Sep 17 00:00:00 2001
From: Vitalii Kiiko
Date: Tue, 20 Aug 2024 15:23:07 +0200
Subject: [PATCH] - added form edit page; - saving progress with the builder;
---
package-lock.json | 74 +++++++++++++++-
package.json | 2 +
src/assets/scss/components/formBuilder.scss | 74 ++++++++++++++++
src/assets/scss/theme.scss | 3 +-
.../components/BuilderElement/index.js | 65 ++++++++++++++
.../components/FormBuilder/index.js | 73 ++++++++++++++++
.../components/ItemTypes/index.js | 3 +
src/pages/BandoEditForm/index.js | 87 +++++++++++++++++++
src/pages/BandoEditForms/index.js | 19 +++-
src/routes.js | 2 +
yarn.lock | 61 +++++++++++--
11 files changed, 452 insertions(+), 11 deletions(-)
create mode 100644 src/assets/scss/components/formBuilder.scss
create mode 100644 src/pages/BandoEditForm/components/BuilderElement/index.js
create mode 100644 src/pages/BandoEditForm/components/FormBuilder/index.js
create mode 100644 src/pages/BandoEditForm/components/ItemTypes/index.js
create mode 100644 src/pages/BandoEditForm/index.js
diff --git a/package-lock.json b/package-lock.json
index f88904d..def2de4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,6 +23,8 @@
"primereact": "^10.8.2",
"ramda": "0.30.1",
"react": "18.3.1",
+ "react-dnd": "^16.0.1",
+ "react-dnd-html5-backend": "^16.0.1",
"react-dom": "18.3.1",
"react-hook-form": "7.52.2",
"react-router-dom": "6.26.0",
@@ -37,7 +39,7 @@
"@wordpress/babel-plugin-makepot": "6.5.0",
"babel-plugin-macros": "3.1.0",
"sass": "1.77.8",
- "sass-loader": "^16.0.0"
+ "sass-loader": "16.0.0"
}
},
"node_modules/@alloc/quick-lru": {
@@ -3484,6 +3486,21 @@
"node": ">= 8"
}
},
+ "node_modules/@react-dnd/asap": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
+ "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
+ },
+ "node_modules/@react-dnd/invariant": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
+ "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
+ },
+ "node_modules/@react-dnd/shallowequal": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
+ "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
+ },
"node_modules/@remix-run/router": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.0.tgz",
@@ -6902,6 +6919,16 @@
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
},
+ "node_modules/dnd-core": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
+ "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
+ "dependencies": {
+ "@react-dnd/asap": "^5.0.1",
+ "@react-dnd/invariant": "^4.0.1",
+ "redux": "^4.2.0"
+ }
+ },
"node_modules/dns-packet": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
@@ -15088,6 +15115,43 @@
"node": ">=8"
}
},
+ "node_modules/react-dnd": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
+ "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
+ "dependencies": {
+ "@react-dnd/invariant": "^4.0.1",
+ "@react-dnd/shallowequal": "^4.0.1",
+ "dnd-core": "^16.0.1",
+ "fast-deep-equal": "^3.1.3",
+ "hoist-non-react-statics": "^3.3.2"
+ },
+ "peerDependencies": {
+ "@types/hoist-non-react-statics": ">= 3.3.1",
+ "@types/node": ">= 12",
+ "@types/react": ">= 16",
+ "react": ">= 16.14"
+ },
+ "peerDependenciesMeta": {
+ "@types/hoist-non-react-statics": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-dnd-html5-backend": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz",
+ "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==",
+ "dependencies": {
+ "dnd-core": "^16.0.1"
+ }
+ },
"node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
@@ -15377,6 +15441,14 @@
"node": ">=6.0.0"
}
},
+ "node_modules/redux": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
+ "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
+ "dependencies": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz",
diff --git a/package.json b/package.json
index 52deb1f..86de8be 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,8 @@
"primereact": "^10.8.2",
"ramda": "0.30.1",
"react": "18.3.1",
+ "react-dnd": "^16.0.1",
+ "react-dnd-html5-backend": "^16.0.1",
"react-dom": "18.3.1",
"react-hook-form": "7.52.2",
"react-router-dom": "6.26.0",
diff --git a/src/assets/scss/components/formBuilder.scss b/src/assets/scss/components/formBuilder.scss
new file mode 100644
index 0000000..61f9e31
--- /dev/null
+++ b/src/assets/scss/components/formBuilder.scss
@@ -0,0 +1,74 @@
+.formBuilder {
+ display: flex;
+ gap: 20px;
+ width: 100%;
+ min-height: 500px;
+}
+
+.formBuilder__main {
+ flex: 1 1 100%;
+ display: flex;
+ flex-direction: column;
+
+ h2 {
+ color: #404D5B;
+ font-size: 21px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ }
+}
+
+.formBuilder__content {
+ flex-grow: 2;
+ display: flex;
+ flex-direction: column;
+ gap: 7px;
+ padding: 20px;
+ border: 1px #DDD;
+ background: var(--surface-50);
+ box-shadow: 0px 0px 2px 1px rgba(0, 0, 0, 0.10);
+}
+
+.formBuilder__element {
+ display: flex;
+ padding: 10px 20px;
+ border: 1px dashed var(--button-secondary-borderColor);
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 21px;
+}
+
+.formBuilder__aside {
+ flex: 0 0 250px;
+ display: flex;
+ flex-direction: column;
+
+ h2 {
+ color: #404D5B;
+ font-size: 21px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ }
+}
+
+.formBuilder__list {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+
+ li {
+ display: flex;
+ padding: 10px 20px;
+ border: 1px dashed var(--button-secondary-borderColor);
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 21px;
+ }
+}
\ No newline at end of file
diff --git a/src/assets/scss/theme.scss b/src/assets/scss/theme.scss
index 03e524b..b8c9f1c 100644
--- a/src/assets/scss/theme.scss
+++ b/src/assets/scss/theme.scss
@@ -109,4 +109,5 @@ body {
@import "./components/statsBigBadges.scss";
@import "./components/bandoStatusTag.scss";
@import "./components/appForm.scss";
-@import "./components/pageBando.scss";
\ No newline at end of file
+@import "./components/pageBando.scss";
+@import "./components/formBuilder.scss";
\ No newline at end of file
diff --git a/src/pages/BandoEditForm/components/BuilderElement/index.js b/src/pages/BandoEditForm/components/BuilderElement/index.js
new file mode 100644
index 0000000..75a274c
--- /dev/null
+++ b/src/pages/BandoEditForm/components/BuilderElement/index.js
@@ -0,0 +1,65 @@
+import React, { useRef, } from 'react'
+import { useDrag, useDrop } from 'react-dnd'
+import { ItemTypes } from '../ItemTypes';
+
+
+const BuilderElement = ({ id, text, index, move }) => {
+ const ref = useRef(null);
+
+ const [{ handlerId }, drop] = useDrop({
+ accept: ItemTypes.FIELD,
+ collect(monitor) {
+ return {
+ handlerId: monitor.getHandlerId(),
+ }
+ },
+ hover(item, monitor) {
+ if (!ref.current) {
+ return
+ }
+ const dragIndex = item.index
+ const hoverIndex = index
+
+ if (dragIndex === hoverIndex) {
+ return
+ }
+
+ const hoverBoundingRect = ref.current?.getBoundingClientRect()
+ const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2
+ const clientOffset = monitor.getClientOffset()
+ const hoverClientY = clientOffset.y - hoverBoundingRect.top
+
+ if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
+ return
+ }
+
+ if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
+ return
+ }
+
+ move(dragIndex, hoverIndex)
+ item.index = hoverIndex
+ },
+ });
+
+ const [{ isDragging }, drag] = useDrag({
+ type: ItemTypes.FIELD,
+ item: () => {
+ return { id, index }
+ },
+ collect: (monitor) => ({
+ isDragging: monitor.isDragging(),
+ }),
+ });
+
+ const opacity = isDragging ? 0 : 1;
+ drag(drop(ref));
+
+ return (
+
+ {text}
+
+ )
+}
+
+export default BuilderElement;
\ No newline at end of file
diff --git a/src/pages/BandoEditForm/components/FormBuilder/index.js b/src/pages/BandoEditForm/components/FormBuilder/index.js
new file mode 100644
index 0000000..11609fe
--- /dev/null
+++ b/src/pages/BandoEditForm/components/FormBuilder/index.js
@@ -0,0 +1,73 @@
+import React, { useCallback, useState } from 'react'
+import { __ } from '@wordpress/i18n';
+
+// components
+import BuilderElement from '../BuilderElement';
+
+const FormBuilder = () => {
+ const [fields, setFields] = useState([
+ {
+ id: 1,
+ text: 'Write a cool JS library',
+ },
+ {
+ id: 2,
+ text: 'Make it generic enough',
+ }
+ ]);
+ const [items, setItems] = useState([
+ {
+ id: 1,
+ label: 'Text Input'
+ },
+ {
+ id: 2,
+ label: 'Text Area'
+ }
+ ])
+
+ const moveField = useCallback((dragIndex, hoverIndex) => {
+ console.log('dragIndex, hoverIndex:', dragIndex, hoverIndex)
+ /*setFields((prevCards) =>
+ update(prevCards, {
+ $splice: [
+ [dragIndex, 1],
+ [hoverIndex, 0, prevCards[dragIndex]],
+ ],
+ }),
+ )*/
+ }, []);
+
+ const renderField = useCallback((card, index) => {
+ return (
+
+ )
+ }, []);
+
+ return (
+
+
+
{__('Trascina qui gli elementi del Form', 'gepafin')}
+
+ {fields.map((field, i) => renderField(field, i))}
+
+
+
+
{__('Elementi del Form', 'gepafin')}
+
+ {items.map((item) => -
+ {item.label}
+
)}
+
+
+
+ )
+}
+
+export default FormBuilder;
diff --git a/src/pages/BandoEditForm/components/ItemTypes/index.js b/src/pages/BandoEditForm/components/ItemTypes/index.js
new file mode 100644
index 0000000..9a2725b
--- /dev/null
+++ b/src/pages/BandoEditForm/components/ItemTypes/index.js
@@ -0,0 +1,3 @@
+export const ItemTypes = {
+ FIELD: 'field',
+}
\ No newline at end of file
diff --git a/src/pages/BandoEditForm/index.js b/src/pages/BandoEditForm/index.js
new file mode 100644
index 0000000..ac08054
--- /dev/null
+++ b/src/pages/BandoEditForm/index.js
@@ -0,0 +1,87 @@
+import React, { useEffect } from 'react';
+import { __ } from '@wordpress/i18n';
+import { useNavigate, useParams } from 'react-router-dom';
+import { DndProvider } from 'react-dnd'
+import { HTML5Backend } from 'react-dnd-html5-backend'
+
+// components
+import FormBuilder from './components/FormBuilder';
+import { Button } from 'primereact/button';
+
+const BandoEditForm = () => {
+ const { id, formId } = useParams();
+ const navigate = useNavigate();
+ //const [data, setData] = useState({});
+ //const [isLoading, setIsLoading] = useState(true);
+
+ const goBack = () => {
+ navigate('/bandi/11/forms');
+ }
+
+ const doSave = () => {
+ console.log('doSave');
+ }
+
+ const openPreview = () => {
+ console.log('openPreview');
+ }
+
+ const doPublish = () => {
+ console.log('doPublish');
+ }
+
+ useEffect(() => {
+ const parsed = parseInt(id)
+ const bandoId = !isNaN(parsed) ? parsed : 0;
+ const parsedFormId = parseInt(formId)
+ const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
+
+ // TODO
+ }, [id]);
+
+ return (
+
+
+
{__('Editor del Form', 'gepafin')}
+
+ {__('Imposta gli elementi del tuo Form.', 'gepafin')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+
+}
+
+export default BandoEditForm;
\ No newline at end of file
diff --git a/src/pages/BandoEditForms/index.js b/src/pages/BandoEditForms/index.js
index 6f5260b..0fecca3 100644
--- a/src/pages/BandoEditForms/index.js
+++ b/src/pages/BandoEditForms/index.js
@@ -1,16 +1,20 @@
import React, { useState, useEffect, useRef } from 'react';
import { __ } from '@wordpress/i18n';
-import { useParams } from 'react-router-dom';
-import { Skeleton } from 'primereact/skeleton';
-import getBandoLabel from '../../helpers/getBandoLabel';
+import { useParams, useNavigate } from 'react-router-dom';
// components
+import { Button } from 'primereact/button';
const BandoEditForms = () => {
const { id } = useParams();
+ const navigate = useNavigate();
//const [data, setData] = useState({});
//const [isLoading, setIsLoading] = useState(true);
+ const doCreateNewForm = () => {
+ navigate('/bandi/11/forms/new');
+ }
+
useEffect(() => {
const parsed = parseInt(id)
const bandoId = !isNaN(parsed) ? parsed : 0;
@@ -26,6 +30,15 @@ const BandoEditForms = () => {
{__('Scegli come vuoi procedere:', 'gepafin')}
+
+
+
+
+
+
)
diff --git a/src/routes.js b/src/routes.js
index 0648a27..33c3470 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -10,6 +10,7 @@ import Bandi from './pages/Bandi';
import BandoEdit from './pages/BandoEdit';
import BandoView from './pages/BandoView';
import BandoEditForms from './pages/BandoEditForms';
+import BandoEditForm from './pages/BandoEditForm';
const routes = () => (
@@ -20,6 +21,7 @@ const routes = () => (
}/>
}/>
}/>
+ }/>
}/>
{/*}/>*/}
diff --git a/yarn.lock b/yarn.lock
index db321b8..f7c8c3e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1129,7 +1129,7 @@
resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
-"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
+"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.24.5"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz"
integrity sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==
@@ -1775,6 +1775,21 @@
schema-utils "^4.2.0"
source-map "^0.7.3"
+"@react-dnd/asap@^5.0.1":
+ version "5.0.2"
+ resolved "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz"
+ integrity sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==
+
+"@react-dnd/invariant@^4.0.1":
+ version "4.0.2"
+ resolved "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz"
+ integrity sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==
+
+"@react-dnd/shallowequal@^4.0.1":
+ version "4.0.2"
+ resolved "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz"
+ integrity sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==
+
"@remix-run/router@1.19.0":
version "1.19.0"
resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.19.0.tgz"
@@ -2163,7 +2178,7 @@
dependencies:
"@types/node" "*"
-"@types/node@*":
+"@types/node@*", "@types/node@>= 12":
version "22.1.0"
resolved "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz"
integrity sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==
@@ -2214,7 +2229,7 @@
dependencies:
"@types/react" "*"
-"@types/react@*", "@types/react@^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react@^18.2.79", "@types/react@>=16.8", "@types/react@0.14 || 15 || 16 || 17 || 18":
+"@types/react@*", "@types/react@^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react@^18.2.79", "@types/react@>= 16", "@types/react@>=16.8", "@types/react@0.14 || 15 || 16 || 17 || 18":
version "18.3.3"
resolved "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz"
integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==
@@ -4080,6 +4095,15 @@ dlv@^1.1.3:
resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
+dnd-core@^16.0.1:
+ version "16.0.1"
+ resolved "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz"
+ integrity sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==
+ dependencies:
+ "@react-dnd/asap" "^5.0.1"
+ "@react-dnd/invariant" "^4.0.1"
+ redux "^4.2.0"
+
dns-packet@^5.2.2:
version "5.6.1"
resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz"
@@ -5396,7 +5420,7 @@ header-case@^2.0.4:
capital-case "^1.0.4"
tslib "^2.0.3"
-hoist-non-react-statics@^3.3.1:
+hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -8250,6 +8274,24 @@ react-dev-utils@^12.0.1:
strip-ansi "^6.0.1"
text-table "^0.2.0"
+react-dnd-html5-backend@^16.0.1:
+ version "16.0.1"
+ resolved "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz"
+ integrity sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==
+ dependencies:
+ dnd-core "^16.0.1"
+
+react-dnd@^16.0.1:
+ version "16.0.1"
+ resolved "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz"
+ integrity sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==
+ dependencies:
+ "@react-dnd/invariant" "^4.0.1"
+ "@react-dnd/shallowequal" "^4.0.1"
+ dnd-core "^16.0.1"
+ fast-deep-equal "^3.1.3"
+ hoist-non-react-statics "^3.3.2"
+
react-dom@*, "react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", react-dom@^18.3.0, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@18.3.1:
version "18.3.1"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
@@ -8381,7 +8423,7 @@ react-transition-group@^4.4.1:
loose-envify "^1.4.0"
prop-types "^15.6.2"
-"react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.0 || ^18.0.0 || ^19.0.0", react@^18.3.0, react@^18.3.1, "react@>= 16", react@>=16.6.0, react@>=16.8, react@>=16.8.0, "react@0.14 || 15 || 16 || 17 || 18", react@18.3.1:
+"react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.0 || ^18.0.0 || ^19.0.0", react@^18.3.0, react@^18.3.1, "react@>= 16", "react@>= 16.14", react@>=16.6.0, react@>=16.8, react@>=16.8.0, "react@0.14 || 15 || 16 || 17 || 18", react@18.3.1:
version "18.3.1"
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
@@ -8431,6 +8473,13 @@ recursive-readdir@^2.2.2:
dependencies:
minimatch "^3.0.5"
+redux@^4.2.0:
+ version "4.2.1"
+ resolved "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz"
+ integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
+ dependencies:
+ "@babel/runtime" "^7.9.2"
+
reflect.getprototypeof@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz"
@@ -8691,7 +8740,7 @@ sass-loader@^12.3.0:
klona "^2.0.4"
neo-async "^2.6.2"
-sass-loader@^16.0.0:
+sass-loader@16.0.0:
version "16.0.0"
resolved "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.0.tgz"
integrity sha512-n13Z+3rU9A177dk4888czcVFiC8CL9dii4qpXWUg3YIIgZEvi9TCFKjOQcbK0kJM7DJu9VucrZFddvNfYCPwtw==