Commit f8f20561 authored by Ben Anderson's avatar Ben Anderson

Resolved Merge conflicts AFp-110

parents b1d492ce 9c2fe6a4
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
"react-router": "^5.2.0", "react-router": "^5.2.0",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^2.0.3",
"web-vitals": "^1.0.1" "web-vitals": "^1.0.1"
} }
}, },
...@@ -1516,6 +1518,36 @@ ...@@ -1516,6 +1518,36 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@fluentui/react-component-event-listener": {
"version": "0.51.7",
"resolved": "https://registry.npmjs.org/@fluentui/react-component-event-listener/-/react-component-event-listener-0.51.7.tgz",
"integrity": "sha512-NjVm+crN0T9A7vITL8alZeHnuV8zi2gos0nezU/2YOxaUAB9E4zKiPxt/6k5U50rJs/gj8Nu45iXxnjO41HbZg==",
"dependencies": {
"@babel/runtime": "^7.10.4"
},
"peerDependencies": {
"react": "^16.8.0 || ^17",
"react-dom": "^16.8.0 || ^17"
}
},
"node_modules/@fluentui/react-component-ref": {
"version": "0.51.7",
"resolved": "https://registry.npmjs.org/@fluentui/react-component-ref/-/react-component-ref-0.51.7.tgz",
"integrity": "sha512-CX27jVJYaFoBCWpuWAizQZ2se137ku1dmDyn8sw+ySNJa+kkQf7LnMydiPW5K7cRdUSqUJW3eS4EjKRvVAx8xA==",
"dependencies": {
"@babel/runtime": "^7.10.4",
"react-is": "^16.6.3"
},
"peerDependencies": {
"react": "^16.8.0 || ^17",
"react-dom": "^16.8.0 || ^17"
}
},
"node_modules/@fluentui/react-component-ref/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/@hapi/address": { "node_modules/@hapi/address": {
"version": "2.1.4", "version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
...@@ -2119,6 +2151,19 @@ ...@@ -2119,6 +2151,19 @@
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="
}, },
"node_modules/@semantic-ui-react/event-stack": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@semantic-ui-react/event-stack/-/event-stack-3.1.2.tgz",
"integrity": "sha512-Yd0Qf7lPCIjzJ9bZYfurlNu2RDXT6KKSyubHfYK3WjRauhxCsq6Fk2LMRI9DEvShoEU+AsLSv3NGkqXAcVp0zg==",
"dependencies": {
"exenv": "^1.2.2",
"prop-types": "^15.6.2"
},
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0",
"react-dom": "^16.0.0 || ^17.0.0"
}
},
"node_modules/@sinonjs/commons": { "node_modules/@sinonjs/commons": {
"version": "1.8.2", "version": "1.8.2",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz",
...@@ -4787,6 +4832,14 @@ ...@@ -4787,6 +4832,14 @@
"wrap-ansi": "^6.2.0" "wrap-ansi": "^6.2.0"
} }
}, },
"node_modules/clsx": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
"engines": {
"node": ">=6"
}
},
"node_modules/co": { "node_modules/co": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
...@@ -7340,6 +7393,11 @@ ...@@ -7340,6 +7393,11 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1" "url": "https://github.com/sindresorhus/execa?sponsor=1"
} }
}, },
"node_modules/exenv": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
},
"node_modules/exit": { "node_modules/exit": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
...@@ -10760,6 +10818,11 @@ ...@@ -10760,6 +10818,11 @@
"node": ">= 10.13.0" "node": ">= 10.13.0"
} }
}, },
"node_modules/jquery": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
...@@ -10923,6 +10986,11 @@ ...@@ -10923,6 +10986,11 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/keyboard-key": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/keyboard-key/-/keyboard-key-1.1.0.tgz",
"integrity": "sha512-qkBzPTi3rlAKvX7k0/ub44sqOfXeLc/jcnGGmj5c7BJpU8eDrEVPyhCvNYAaoubbsLm9uGWwQJO1ytQK1a9/dQ=="
},
"node_modules/killable": { "node_modules/killable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
...@@ -14553,6 +14621,11 @@ ...@@ -14553,6 +14621,11 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
}, },
"node_modules/react-fast-compare": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
},
"node_modules/react-hook-form": { "node_modules/react-hook-form": {
"version": "7.4.1", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.4.1.tgz", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.4.1.tgz",
...@@ -14594,6 +14667,19 @@ ...@@ -14594,6 +14667,19 @@
"react-dom": ">=16.3.0" "react-dom": ">=16.3.0"
} }
}, },
"node_modules/react-popper": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz",
"integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==",
"dependencies": {
"react-fast-compare": "^3.0.1",
"warning": "^4.0.2"
},
"peerDependencies": {
"@popperjs/core": "^2.0.0",
"react": "^16.8.0 || ^17"
}
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.8.3", "version": "0.8.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
...@@ -16011,6 +16097,38 @@ ...@@ -16011,6 +16097,38 @@
"node-forge": "^0.10.0" "node-forge": "^0.10.0"
} }
}, },
"node_modules/semantic-ui-css": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.4.1.tgz",
"integrity": "sha512-Pkp0p9oWOxlH0kODx7qFpIRYpK1T4WJOO4lNnpNPOoWKCrYsfHqYSKgk5fHfQtnWnsAKy7nLJMW02bgDWWFZFg==",
"dependencies": {
"jquery": "x.*"
}
},
"node_modules/semantic-ui-react": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-2.0.3.tgz",
"integrity": "sha512-a0hGN6XXw64sRSKwWqMCKSI/AGLohxNeWuErS39eswvBbUnLjBij8ZoEdiqDiz/PuWpwYIRjgmQVrut+7h3b2g==",
"dependencies": {
"@babel/runtime": "^7.10.5",
"@fluentui/react-component-event-listener": "~0.51.6",
"@fluentui/react-component-ref": "~0.51.6",
"@popperjs/core": "^2.6.0",
"@semantic-ui-react/event-stack": "^3.1.2",
"clsx": "^1.1.1",
"keyboard-key": "^1.1.0",
"lodash": "^4.17.19",
"lodash-es": "^4.17.15",
"prop-types": "^15.7.2",
"react-is": "^16.8.6 || ^17.0.0",
"react-popper": "^2.2.4",
"shallowequal": "^1.1.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
}
},
"node_modules/semver": { "node_modules/semver": {
"version": "7.3.2", "version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
...@@ -16199,6 +16317,11 @@ ...@@ -16199,6 +16317,11 @@
"sha.js": "bin.js" "sha.js": "bin.js"
} }
}, },
"node_modules/shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
...@@ -21367,6 +21490,30 @@ ...@@ -21367,6 +21490,30 @@
} }
} }
}, },
"@fluentui/react-component-event-listener": {
"version": "0.51.7",
"resolved": "https://registry.npmjs.org/@fluentui/react-component-event-listener/-/react-component-event-listener-0.51.7.tgz",
"integrity": "sha512-NjVm+crN0T9A7vITL8alZeHnuV8zi2gos0nezU/2YOxaUAB9E4zKiPxt/6k5U50rJs/gj8Nu45iXxnjO41HbZg==",
"requires": {
"@babel/runtime": "^7.10.4"
}
},
"@fluentui/react-component-ref": {
"version": "0.51.7",
"resolved": "https://registry.npmjs.org/@fluentui/react-component-ref/-/react-component-ref-0.51.7.tgz",
"integrity": "sha512-CX27jVJYaFoBCWpuWAizQZ2se137ku1dmDyn8sw+ySNJa+kkQf7LnMydiPW5K7cRdUSqUJW3eS4EjKRvVAx8xA==",
"requires": {
"@babel/runtime": "^7.10.4",
"react-is": "^16.6.3"
},
"dependencies": {
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}
}
},
"@hapi/address": { "@hapi/address": {
"version": "2.1.4", "version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
...@@ -21823,6 +21970,15 @@ ...@@ -21823,6 +21970,15 @@
} }
} }
}, },
"@semantic-ui-react/event-stack": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@semantic-ui-react/event-stack/-/event-stack-3.1.2.tgz",
"integrity": "sha512-Yd0Qf7lPCIjzJ9bZYfurlNu2RDXT6KKSyubHfYK3WjRauhxCsq6Fk2LMRI9DEvShoEU+AsLSv3NGkqXAcVp0zg==",
"requires": {
"exenv": "^1.2.2",
"prop-types": "^15.6.2"
}
},
"@sinonjs/commons": { "@sinonjs/commons": {
"version": "1.8.2", "version": "1.8.2",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz",
...@@ -23943,6 +24099,11 @@ ...@@ -23943,6 +24099,11 @@
"wrap-ansi": "^6.2.0" "wrap-ansi": "^6.2.0"
} }
}, },
"clsx": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
},
"co": { "co": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
...@@ -25957,6 +26118,11 @@ ...@@ -25957,6 +26118,11 @@
"strip-final-newline": "^2.0.0" "strip-final-newline": "^2.0.0"
} }
}, },
"exenv": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
},
"exit": { "exit": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
...@@ -28639,6 +28805,11 @@ ...@@ -28639,6 +28805,11 @@
"supports-color": "^7.0.0" "supports-color": "^7.0.0"
} }
}, },
"jquery": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
},
"js-tokens": { "js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
...@@ -28768,6 +28939,11 @@ ...@@ -28768,6 +28939,11 @@
"object.assign": "^4.1.2" "object.assign": "^4.1.2"
} }
}, },
"keyboard-key": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/keyboard-key/-/keyboard-key-1.1.0.tgz",
"integrity": "sha512-qkBzPTi3rlAKvX7k0/ub44sqOfXeLc/jcnGGmj5c7BJpU8eDrEVPyhCvNYAaoubbsLm9uGWwQJO1ytQK1a9/dQ=="
},
"killable": { "killable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
...@@ -31686,6 +31862,11 @@ ...@@ -31686,6 +31862,11 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
}, },
"react-fast-compare": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
},
"react-hook-form": { "react-hook-form": {
"version": "7.4.1", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.4.1.tgz", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.4.1.tgz",
...@@ -31717,6 +31898,15 @@ ...@@ -31717,6 +31898,15 @@
"warning": "^4.0.3" "warning": "^4.0.3"
} }
}, },
"react-popper": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz",
"integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==",
"requires": {
"react-fast-compare": "^3.0.1",
"warning": "^4.0.2"
}
},
"react-refresh": { "react-refresh": {
"version": "0.8.3", "version": "0.8.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
...@@ -32816,6 +33006,34 @@ ...@@ -32816,6 +33006,34 @@
"node-forge": "^0.10.0" "node-forge": "^0.10.0"
} }
}, },
"semantic-ui-css": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.4.1.tgz",
"integrity": "sha512-Pkp0p9oWOxlH0kODx7qFpIRYpK1T4WJOO4lNnpNPOoWKCrYsfHqYSKgk5fHfQtnWnsAKy7nLJMW02bgDWWFZFg==",
"requires": {
"jquery": "x.*"
}
},
"semantic-ui-react": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/semantic-ui-react/-/semantic-ui-react-2.0.3.tgz",
"integrity": "sha512-a0hGN6XXw64sRSKwWqMCKSI/AGLohxNeWuErS39eswvBbUnLjBij8ZoEdiqDiz/PuWpwYIRjgmQVrut+7h3b2g==",
"requires": {
"@babel/runtime": "^7.10.5",
"@fluentui/react-component-event-listener": "~0.51.6",
"@fluentui/react-component-ref": "~0.51.6",
"@popperjs/core": "^2.6.0",
"@semantic-ui-react/event-stack": "^3.1.2",
"clsx": "^1.1.1",
"keyboard-key": "^1.1.0",
"lodash": "^4.17.19",
"lodash-es": "^4.17.15",
"prop-types": "^15.7.2",
"react-is": "^16.8.6 || ^17.0.0",
"react-popper": "^2.2.4",
"shallowequal": "^1.1.0"
}
},
"semver": { "semver": {
"version": "7.3.2", "version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
...@@ -32982,6 +33200,11 @@ ...@@ -32982,6 +33200,11 @@
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
} }
}, },
"shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"shebang-command": { "shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
"react-router": "^5.2.0", "react-router": "^5.2.0",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^2.0.3",
"web-vitals": "^1.0.1" "web-vitals": "^1.0.1"
}, },
"scripts": { "scripts": {
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0"
crossorigin="anonymous" crossorigin="anonymous"
/> />
<link async rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui@${props.versions.sui}/dist/semantic.min.css" />
<script async src="//cdn.jsdelivr.net/npm/semantic-ui@${props.versions.sui}/dist/semantic.min.js"></script>
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
......
...@@ -4,6 +4,7 @@ import Main from "./component/Main"; ...@@ -4,6 +4,7 @@ import Main from "./component/Main";
import AuthRoute from "./component/AuthRoute"; import AuthRoute from "./component/AuthRoute";
import { Switch } from "react-router"; import { Switch } from "react-router";
import Login from "./component/Login"; import Login from "./component/Login";
import 'semantic-ui-css/semantic.min.css'
function App() { function App() {
return ( return (
......
...@@ -4,8 +4,9 @@ import AuthRoute from "./AuthRoute"; ...@@ -4,8 +4,9 @@ import AuthRoute from "./AuthRoute";
import ProductForm from "./ProductForm"; import ProductForm from "./ProductForm";
import ProductGrid from "./ProductGrid"; import ProductGrid from "./ProductGrid";
import SearchResults from "./SearchResults"; import SearchResults from "./SearchResults";
import {getAllProducts} from "../actions/apiRequests.js" import { getAllProducts } from "../actions/apiRequests.js";
import PromotionNewFormComponent from "./promotionforms/PromotionNewFormComponent"; import PromotionNewFormComponent from "./promotionforms/PromotionNewFormComponent";
import PromotionIndexComponent from "./promo_index/PromotionsIndexComponent";
export default function Main() { export default function Main() {
const [productData, setproductData] = useState([]); const [productData, setproductData] = useState([]);
...@@ -34,11 +35,13 @@ export default function Main() { ...@@ -34,11 +35,13 @@ export default function Main() {
component={PromotionNewFormComponent} component={PromotionNewFormComponent}
></AuthRoute> ></AuthRoute>
<AuthRoute exact path="/products" component={ProductGrid}></AuthRoute> <AuthRoute exact path="/products" component={ProductGrid}></AuthRoute>
<AuthRoute path="/promos">PROMOS</AuthRoute> <AuthRoute path="/promos">
<PromotionIndexComponent />
</AuthRoute>
<AuthRoute exact path="/"> <AuthRoute exact path="/">
<Redirect to="/products" /> <Redirect to="/products" />
</AuthRoute> </AuthRoute>
<AuthRoute path="/searchResults" component={SearchResults}/> <AuthRoute path="/searchResults" component={SearchResults} />
<AuthRoute> <AuthRoute>
<h1>404 Page Not Found</h1> <h1>404 Page Not Found</h1>
</AuthRoute> </AuthRoute>
......
import {useState, useEffect} from 'react';
import Config from '../../config';
import "./promolistStyle.css";
import { NavLink } from 'react-router-dom';
export default function PromotionIndexComponent () {
const [promoData, setPromoData] = useState([]);
useEffect( () => {
loadPromotions();
}, [])
const loadPromotions = async () => {
const response = await fetch(`${Config.promotionsUrl}`);
const data = await response.json();
setPromoData(data);
}
const deletePromotion = (promoId) => {
fetch(`${Config.promotionsUrl}/${promoId}`, {
method: "DELETE",
})
.then(res => loadPromotions())
.catch(err => console.log("error"))
}
return (
<div>
<div className="promo-container">
<div className="promo-list-container">
<div className="promo-header">
<h1 className="promo-title"> Promotions</h1>
<NavLink className="add-navLink" to='/promos/new'><button className="btn-success">+ New Promotion</button></NavLink>
</div>
<table className="promo-index-list">
<thead className="promo-table-title">
<tr>
<th>
Promotion Id
</th>
<th>
Product SKU
</th>
<th>
Discount
</th>
<th>
Minimum Quanitity
</th>
<th>
</th>
<th>
</th>
</tr>
</thead>
<tbody>
{promoData.map((promo, key) => {
return (
<tr key={key}>
<td>
{promo.promotionId}
</td>
<td>
{promo.productSku}
</td>
<td>
{promo.discountPercentage}%
</td>
<td>
{promo.minimumQuantity}
</td>
<td>
<NavLink className="edit-navLink" to={{
pathname: `/promos/${promo.promotionId}/update`,
state: {promo}
}}>
<button className="btn-primary">Update</button>
</NavLink>
</td>
<td>
<button className="btn-danger btn-sm" onClick={() => deletePromotion(promo.promotionId)}>Delete</button>
</td>
</tr>
)
}).reverse()
}
</tbody>
</table>
</div>
</div>
</div>
)
}
.promo-container {
margin: 30px auto;
padding: 0 16px;
}
.promo-header {
background-color: #212529;
display: flex;
justify-content: space-between;
padding-left: 10px;
padding-right: 10px;
}
.promo-title {
color: white;
padding: 8px;
}
.add-navLink {
align-self: center;
}
table {
border-collapse: collapse;
width: 100%;
}
td,
th {
text-align: left;
padding: 8px;
}
tr td {
height: 40px;
}
tr {
box-sizing: border-box;
}
tr:nth-child(even) {
background-color: #dddddd;
}
thead th {
background-color: #dddddd;
height: 35px;
}
tr:hover {
background-color: lightblue;
}
import { useState } from "react"; import { useState, useEffect } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import "./promoStyle.css"; import "./promoStyle.css";
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import Config from '../../config'; import Config from '../../config';
import { useHistory } from 'react-router' import { useHistory } from 'react-router'
import { Dropdown } from 'semantic-ui-react'
import {getAllProducts} from '../../actions/apiRequests'
export default function PromotionNewFormComponent () {
const { register, handleSubmit, formState: { errors } } = useForm(); export default function PromotionNewFormComponent (props) {
const { register, handleSubmit, setValue, formState: { errors } } = useForm();
const history = useHistory(); const history = useHistory();
const [serverErrors, setErrors] = useState([]); const [serverErrors, setErrors] = useState([]);
const [productData, setproductData] = useState([]);
const onSubmit = (data) => { const onSubmit = (data) => {
console.log(data) console.log(data)
...@@ -24,18 +29,39 @@ export default function PromotionNewFormComponent () { ...@@ -24,18 +29,39 @@ export default function PromotionNewFormComponent () {
.catch(err => setErrors([err.message])) .catch(err => setErrors([err.message]))
}; };
useEffect(() => {
loadProducts();
}, [])
const loadProducts = async (event) => {
const data = await getAllProducts();
setproductData(data);
}
const onChange = (e, data) => {
console.log(data)
setValue('productSku', data.value)
console.log(productSku)
}
const productSku = register('productSku', { required: true })
return ( return (
<div> <div>
<div className="promo-container"> <div className="promo-container">
<div className="promo-form-container"> <div className="promo-form-container">
<h1 className="promo-form-title">Add Promotion</h1> <h1 className="promo-form-title">Add Promotion</h1>
<form className="promo-form" onSubmit={handleSubmit(onSubmit)}> <form className="promo-form" onSubmit={handleSubmit(onSubmit)}>
{serverErrors.length ? <p className="form-error">{serverErrors}</p> : ""} {serverErrors.length ? <p className="form-error">{serverErrors}</p> : ""}
<div className="form-group"> <div className="form-group">
<label>Promotion Id</label> <label>Promotion Id</label>
<input <input
{...register("promotionId", { {...register("promotionId", {
required: "promotion id is required", required: "promotion id is required",
maxLength: { value: 10, message: "You exceeded the maximum value" } maxLength: { value: 10, message: "You exceeded the maximum value" }
...@@ -44,13 +70,14 @@ export default function PromotionNewFormComponent () { ...@@ -44,13 +70,14 @@ export default function PromotionNewFormComponent () {
className="form-control" className="form-control"
placeholder="eg. PROMO-403" placeholder="eg. PROMO-403"
/> />
{errors.promotionId && <p className="form-error">{errors.promotionId.message}</p>} {errors.promotionId && <p className="form-error">{errors.promotionId.message}</p>}
</div> </div>
<div className="form-group"> <div className="form-group">
<label>Product Sku</label> <label>Product Sku</label>
<input {/* <input
{...register("productSku", { {...register("productSku", {
required: "product sku required", required: "product sku required",
maxLength: { value: 10, message: "You exceeded the maximum value" } maxLength: { value: 10, message: "You exceeded the maximum value" }
...@@ -58,7 +85,22 @@ export default function PromotionNewFormComponent () { ...@@ -58,7 +85,22 @@ export default function PromotionNewFormComponent () {
id="productSku" id="productSku"
className="form-control" className="form-control"
placeholder="eg. SKU-39SD" placeholder="eg. SKU-39SD"
/> /> */}
<Dropdown
placeholder='Select Product'
fluid
search
selection
onChange={onChange}
onSearchChange={onChange}
options={productData.map(prod => {
return {
key: prod.sku,
text: prod.sku,
value: prod.sku,
}
})}
/>
{errors.productSku && <p className="form-error">{errors.productSku.message}</p>} {errors.productSku && <p className="form-error">{errors.productSku.message}</p>}
<br></br> <br></br>
</div> </div>
...@@ -66,7 +108,7 @@ export default function PromotionNewFormComponent () { ...@@ -66,7 +108,7 @@ export default function PromotionNewFormComponent () {
<div className="form-group"> <div className="form-group">
<label>Enter % off</label> <label>Enter % off</label>
<div className="input-group"> <div className="input-group">
<div className="input-group-prepend"> <div className="input-group-prepend">
<span className="input-group-text">%</span></div> <span className="input-group-text">%</span></div>
<input <input
...@@ -88,7 +130,7 @@ export default function PromotionNewFormComponent () { ...@@ -88,7 +130,7 @@ export default function PromotionNewFormComponent () {
<div className="form-group"> <div className="form-group">
<label>Applies at Minimum Quantity</label> <label>Applies at Minimum Quantity</label>
<input <input
{...register("minimumQuantity", { {...register("minimumQuantity", {
valueAsNumber: true, valueAsNumber: true,
required: "minimum quantity is required", required: "minimum quantity is required",
...@@ -111,4 +153,3 @@ export default function PromotionNewFormComponent () { ...@@ -111,4 +153,3 @@ export default function PromotionNewFormComponent () {
</div> </div>
); );
} }
import { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import "./promoStyle.css";
import { NavLink } from 'react-router-dom';
import Config from '../../config';
import { useHistory } from 'react-router'
import { Dropdown } from 'semantic-ui-react'
import { getAllProducts } from '../../actions/apiRequests'
export default function PromotionUpdateFormComponent(props) {
const { register, handleSubmit, setValue, formState: { errors } } = useForm();
const history = useHistory();
const [serverErrors, setErrors] = useState([]);
const [productData, setproductData] = useState([]);
const onSubmit = (data) => {
console.log(data)
fetch(`${Config.promotionsUrl}/${data.promotionId}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
})
.then(res => res.ok ? history.push("/promos") : setErrors(["error"]))
.catch(err => setErrors([err.message]))
};
useEffect( () => {
loadProducts();
}, [])
const loadProducts = async (event) => {
const data = await getAllProducts();
setproductData(data);
}
const onChange = (e, data) => {
setValue('productSku', data.value)
}
const productSku = register('productSku', { required: true })
return (
<div>
<div className="promo-container">
<div className="promo-form-container">
<h1 className="promo-form-title">Update Promotion</h1>
<form className="promo-form" onSubmit={handleSubmit(onSubmit)}>
{serverErrors.length ? <p className="form-error">{serverErrors}</p> : ""}
<div className="form-group">
<label>Promotion Id</label>
<input
{...register("promotionId", {
value: props.location.state.promo.promotionId,
required: "promotion id is required",
maxLength: { value: 10, message: "You exceeded the maximum value" },
})}
readOnly
id="promotionId"
className="form-control"
placeholder="eg. PROMO-403"
/>
{errors.promotionId && <p className="form-error">{errors.promotionId.message}</p>}
</div>
<div className="form-group">
<label>Product Sku</label>
<Dropdown
placeholder='Select Product'
fluid
search
selection
defaultValue={props.location.state.promo.productSku}
onChange={onChange}
onSearchChange={onChange}
options={productData.map(prod => {
return {
key: prod.sku,
text: prod.sku,
value: prod.sku,
}
})} />
{errors.productSku && <p className="form-error">{errors.productSku.message}</p>}
<br></br>
</div>
<div className="form-group">
<label>Enter % off</label>
<div className="input-group">
<div className="input-group-prepend">
<span className="input-group-text">%</span></div>
<input
{...register("discountPercentage", {
valueAsNumber: true,
value: props.location.state.promo.discountPercentage,
required: "% off required",
min: { value: 0, message: "% must be greater than or equal to 0" },
max: { value: 100, message: "% must be less than or equal to 100" },
})}
id="discountPercentage"
className="form-control"
placeholder={props.location.state.promo.discountPercentage }
type="number"
/>
</div>
{errors.discountPercentage && <p className="form-error">{errors.discountPercentage.message}</p>}
</div>
<div className="form-group">
<label>Applies at Minimum Quantity</label>
<input
{...register("minimumQuantity", {
valueAsNumber: true,
value: props.location.state.promo.minimumQuantity,
required: "minimum quantity is required",
min: { value: 1, message: "discount percentage must be greater than 0" },
})}
id="minimumQuantity"
className="form-control"
type="number"
min="1"
placeholder={props.location.state.promo.minimumQuantity}
/>
{errors.minimumQuantity && <p className="form-error">{errors.minimumQuantity.message}</p>}
</div>
<input className="promo-submit" type="submit" value="Update Promotion" />
<NavLink className="promo-cancel" to="/promos">Cancel</NavLink>
</form>
</div>
</div>
</div>
);
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment