= (props) => {
}
+
+
+
@@ -70,8 +86,12 @@ const SignsPage: React.FC = () => {
Download Data
+
{newSignError && {newSignError}
}
+ Signs
+
+
{!loading ?
{
diff --git a/frontend/src/services/category.ts b/frontend/src/services/category.ts
new file mode 100755
index 0000000..357b7c9
--- /dev/null
+++ b/frontend/src/services/category.ts
@@ -0,0 +1,85 @@
+import { Category } from "../types/category";
+
+const getCategories = async () => {
+ // get access token from local storage
+ const token = localStorage.getItem('accessToken');
+ // make request to get signs
+ const response = await fetch(`${process.env.REACT_APP_API_URL}/categories/`, {
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ });
+
+ // return the response
+ return response.json();
+};
+
+const addCategory = async (category: string) => {
+ // get access token from local storage
+ const token = localStorage.getItem('accessToken');
+ // make request to get signs
+ const response = await fetch(`${process.env.REACT_APP_API_URL}/categories/`, {
+ method: 'POST',
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ "name": category })
+ });
+
+ // check if error
+ if (response.status !== 201) {
+ throw new Error('Error adding category');
+ }
+
+ // return the response
+ return response.json();
+};
+
+const updateCategory = async (category: Category) => {
+ // get access token from local storage
+ const token = localStorage.getItem('accessToken');
+ // make request to get signs
+ const response = await fetch(`${process.env.REACT_APP_API_URL}/categories/`, {
+ method: 'PUT',
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(category)
+ });
+
+ // check if error
+ if (response.status !== 200) {
+ throw new Error('Error updating category');
+ }
+
+ // return the response
+ return response.json();
+};
+
+const deleteCategory = async (id: number) => {
+ // get access token from local storage
+ const token = localStorage.getItem('accessToken');
+ // make request to get signs
+ const response = await fetch(`${process.env.REACT_APP_API_URL}/categories/${id}`, {
+ method: 'DELETE',
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': 'application/json'
+ }
+ });
+
+ // check if error
+ if (response.status !== 200) {
+ throw new Error('Category must be empty before deleting');
+ }
+
+ // return the response
+ return response.json();
+
+};
+
+
+
+export { getCategories, addCategory, updateCategory, deleteCategory };
\ No newline at end of file
diff --git a/frontend/src/services/signs.ts b/frontend/src/services/signs.ts
index ca4ce1c..8e6ad9a 100644
--- a/frontend/src/services/signs.ts
+++ b/frontend/src/services/signs.ts
@@ -1,8 +1,8 @@
-const getSigns = async () => {
+const getSigns = async (category: string) => {
// get access token from local storage
const token = localStorage.getItem('accessToken');
// make request to get signs
- const response = await fetch(`${process.env.REACT_APP_API_URL}/signs/`, {
+ const response = await fetch(`${process.env.REACT_APP_API_URL}/categories/${category}/signs/`, {
headers: {
Authorization: `Bearer ${token}`
}
@@ -12,7 +12,7 @@ const getSigns = async () => {
return response.json();
};
-const addSign = async (url: string) => {
+const addSign = async (url: string, category: string) => {
// get access token from local storage
const token = localStorage.getItem('accessToken');
// make request to add sign
@@ -22,7 +22,7 @@ const addSign = async (url: string) => {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
- body: JSON.stringify({ "url": url })
+ body: JSON.stringify({ "url": url, "category": category })
});
if (!response.ok) {
diff --git a/frontend/src/types/category.ts b/frontend/src/types/category.ts
new file mode 100755
index 0000000..029718e
--- /dev/null
+++ b/frontend/src/types/category.ts
@@ -0,0 +1,7 @@
+import { Sign } from "./sign";
+
+export interface Category {
+ id: number;
+ name: string;
+ enabled: boolean;
+}
\ No newline at end of file
diff --git a/frontend/src/types/sign.ts b/frontend/src/types/sign.ts
index 7894b3a..70af921 100644
--- a/frontend/src/types/sign.ts
+++ b/frontend/src/types/sign.ts
@@ -9,6 +9,7 @@ export interface Sign {
name: string;
sign_id: string;
video_url: string;
+ category_id: number;
sign_videos: [SignVideo];
}
@@ -16,6 +17,7 @@ export interface SimpleSign {
id: number;
url: string;
name: string;
+ category_id: number;
sign_id: string;
video_url: string;
}
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 56e07d5..7876c25 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -1036,6 +1036,13 @@
dependencies:
regenerator-runtime "^0.13.11"
+"@babel/runtime@^7.19.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
+ integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
+ dependencies:
+ regenerator-runtime "^0.13.11"
+
"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
@@ -1238,6 +1245,11 @@
regenerator-runtime "^0.13.7"
resolve-url "^0.2.1"
+"@heroicons/react@^2.0.16":
+ version "2.0.16"
+ resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.0.16.tgz#562883c19ba2690c83380b42a9a5cce39dcbdb4a"
+ integrity sha512-x89rFxH3SRdYaA+JCXwfe+RkE1SFTo9GcOkZettHer71Y3T7V+ogKmfw5CjTazgS3d0ClJ7p1NA+SP7VQLQcLw==
+
"@humanwhocodes/config-array@^0.11.8":
version "0.11.8"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9"
@@ -1671,6 +1683,21 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
+"@styled-icons/heroicons-solid@^10.47.0":
+ version "10.47.0"
+ resolved "https://registry.yarnpkg.com/@styled-icons/heroicons-solid/-/heroicons-solid-10.47.0.tgz#4457463fe15c8bf8c357bf22dd16d3e579a5e163"
+ integrity sha512-j+tJx2NzLG2tc91IXJVwKNjsI/osxmak+wmLfnfBsB+49srpxMYjuLPMtl9ZY/xgbNsWO36O+/N5Zf5bkgiKcQ==
+ dependencies:
+ "@babel/runtime" "^7.20.7"
+ "@styled-icons/styled-icon" "^10.7.0"
+
+"@styled-icons/styled-icon@^10.7.0":
+ version "10.7.0"
+ resolved "https://registry.yarnpkg.com/@styled-icons/styled-icon/-/styled-icon-10.7.0.tgz#d6960e719b8567c8d0d3a87c40fb6f5b4952a228"
+ integrity sha512-SCrhCfRyoY8DY7gUkpz+B0RqUg/n1Zaqrr2+YKmK/AyeNfCcoHuP4R9N4H0p/NA1l7PTU10ZkAWSLi68phnAjw==
+ dependencies:
+ "@babel/runtime" "^7.19.0"
+
"@surma/rollup-plugin-off-main-thread@^2.2.3":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053"
@@ -2088,6 +2115,13 @@
dependencies:
"@types/react" "*"
+"@types/react-edit-text@^5.0.1":
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@types/react-edit-text/-/react-edit-text-5.0.1.tgz#2907c740c013c17707eb76d1b84688417dff4c27"
+ integrity sha512-Eb2tX+PtSsbSTZPO1mTbTufVVAGddeplMCHsL+RCXQytm3X8bkiKWXMbQ/kaoOuxDHTkarItHRX0dEeo5A2B+w==
+ dependencies:
+ "@types/react" "*"
+
"@types/react-modal@^3.13.1":
version "3.13.1"
resolved "https://registry.yarnpkg.com/@types/react-modal/-/react-modal-3.13.1.tgz#5b9845c205fccc85d9a77966b6e16dc70a60825a"
@@ -3234,7 +3268,7 @@ cjs-module-lexer@^1.0.0:
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
-classnames@^2.2.1:
+classnames@^2.2.1, classnames@^2.2.6:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
@@ -8035,6 +8069,14 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
+react-edit-text@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/react-edit-text/-/react-edit-text-5.0.2.tgz#e1418a16f615cc5b833f455ccffd24d18c566ab2"
+ integrity sha512-V3M4KhgQDbKa1I6F5OLrhqu9w/T4XONFEyC4RijdSxDs+L5srpsCH6V5CSWGNT6pu6f4VG03n736RB3lMCTUkw==
+ dependencies:
+ classnames "^2.2.6"
+ prop-types "^15.8.1"
+
react-error-overlay@^6.0.11:
version "6.0.11"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"