Merge pull request 'Admin' (#35) from Admin into master

Reviewed-on: http://git.plannaplan.pl/y0rune/frontend/pulls/35
Reviewed-by: Marcin Woźniak <y0rune@aol.com>
This commit is contained in:
Marcin Woźniak 2020-12-14 15:53:26 +01:00
commit 274d50fac3
24 changed files with 12535 additions and 125 deletions

1
decs.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare module 'react-loading-overlay';

213
package-lock.json generated
View File

@ -1239,6 +1239,40 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
}, },
"@emotion/cache": {
"version": "10.0.29",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
"integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==",
"requires": {
"@emotion/sheet": "0.9.4",
"@emotion/stylis": "0.8.5",
"@emotion/utils": "0.11.3",
"@emotion/weak-memoize": "0.2.5"
}
},
"@emotion/core": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.1.1.tgz",
"integrity": "sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==",
"requires": {
"@babel/runtime": "^7.5.5",
"@emotion/cache": "^10.0.27",
"@emotion/css": "^10.0.27",
"@emotion/serialize": "^0.11.15",
"@emotion/sheet": "0.9.4",
"@emotion/utils": "0.11.3"
}
},
"@emotion/css": {
"version": "10.0.27",
"resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz",
"integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==",
"requires": {
"@emotion/serialize": "^0.11.15",
"@emotion/utils": "0.11.3",
"babel-plugin-emotion": "^10.0.27"
}
},
"@emotion/hash": { "@emotion/hash": {
"version": "0.8.0", "version": "0.8.0",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
@ -1257,6 +1291,30 @@
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
}, },
"@emotion/serialize": {
"version": "0.11.16",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz",
"integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==",
"requires": {
"@emotion/hash": "0.8.0",
"@emotion/memoize": "0.7.4",
"@emotion/unitless": "0.7.5",
"@emotion/utils": "0.11.3",
"csstype": "^2.5.7"
},
"dependencies": {
"csstype": {
"version": "2.6.14",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.14.tgz",
"integrity": "sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A=="
}
}
},
"@emotion/sheet": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz",
"integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA=="
},
"@emotion/stylis": { "@emotion/stylis": {
"version": "0.8.5", "version": "0.8.5",
"resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
@ -1267,6 +1325,16 @@
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
}, },
"@emotion/utils": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz",
"integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw=="
},
"@emotion/weak-memoize": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
"integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
},
"@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",
@ -3172,6 +3240,23 @@
"object.assign": "^4.1.0" "object.assign": "^4.1.0"
} }
}, },
"babel-plugin-emotion": {
"version": "10.0.33",
"resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz",
"integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@emotion/hash": "0.8.0",
"@emotion/memoize": "0.7.4",
"@emotion/serialize": "^0.11.16",
"babel-plugin-macros": "^2.0.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^1.0.5",
"find-root": "^1.1.0",
"source-map": "^0.5.7"
}
},
"babel-plugin-istanbul": { "babel-plugin-istanbul": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz",
@ -4027,12 +4112,6 @@
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
} }
}, },
"fsevents": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
"optional": true
},
"is-number": { "is-number": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@ -4488,6 +4567,17 @@
} }
} }
}, },
"create-emotion": {
"version": "10.0.27",
"resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-10.0.27.tgz",
"integrity": "sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg==",
"requires": {
"@emotion/cache": "^10.0.27",
"@emotion/serialize": "^0.11.15",
"@emotion/sheet": "0.9.4",
"@emotion/utils": "0.11.3"
}
},
"create-hash": { "create-hash": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@ -5334,6 +5424,15 @@
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
}, },
"emotion": {
"version": "10.0.27",
"resolved": "https://registry.npmjs.org/emotion/-/emotion-10.0.27.tgz",
"integrity": "sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g==",
"requires": {
"babel-plugin-emotion": "^10.0.27",
"create-emotion": "^10.0.27"
}
},
"encodeurl": { "encodeurl": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -6542,6 +6641,11 @@
"pkg-dir": "^3.0.0" "pkg-dir": "^3.0.0"
} }
}, },
"find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
},
"find-up": { "find-up": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -6781,14 +6885,10 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
}, },
"fsevents": { "fsevents": {
"version": "1.2.13", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
"optional": true, "optional": true
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
}, },
"function-bind": { "function-bind": {
"version": "1.1.1", "version": "1.1.1",
@ -8117,6 +8217,18 @@
"micromatch": "^3.1.10", "micromatch": "^3.1.10",
"sane": "^4.0.3", "sane": "^4.0.3",
"walker": "^1.0.7" "walker": "^1.0.7"
},
"dependencies": {
"fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
}
} }
}, },
"jest-jasmine2": { "jest-jasmine2": {
@ -11530,6 +11642,42 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}, },
"react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-loading-overlay": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/react-loading-overlay/-/react-loading-overlay-1.0.1.tgz",
"integrity": "sha512-aUjtZ8tNXBSx+MbD2SQs0boPbeTAGTh+I5U9nWjDzMasKlYr58RJpr57c8W7uApeLpOkAGbInExRi6GamNC2bA==",
"requires": {
"emotion": "^10.0.1",
"prop-types": "^15.6.2",
"react-transition-group": "^2.5.0"
},
"dependencies": {
"dom-helpers": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
"integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
"requires": {
"@babel/runtime": "^7.1.2"
}
},
"react-transition-group": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
"integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
"requires": {
"dom-helpers": "^3.4.0",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2",
"react-lifecycles-compat": "^3.0.4"
}
}
}
},
"react-scripts": { "react-scripts": {
"version": "3.4.1", "version": "3.4.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
@ -11774,12 +11922,6 @@
"pinkie-promise": "^2.0.0" "pinkie-promise": "^2.0.0"
} }
}, },
"fsevents": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
"integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
"optional": true
},
"path-exists": { "path-exists": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
@ -11806,10 +11948,13 @@
} }
} }
}, },
"react-tiny-popover": { "react-spinners": {
"version": "6.0.0-beta.2", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/react-tiny-popover/-/react-tiny-popover-6.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.9.0.tgz",
"integrity": "sha512-Skx6InxhIbnBgoEia6oTWD4eH+VQC6TjGlm+tEj289bt1l8jcVUYNR52RtQx+3fFOin6aKJGp3LtjHUB2NiPYA==" "integrity": "sha512-+x6eD8tn/aYLdxZjNW7fSR1uoAXLb9qq6TFYZR1dFweJvckcf/HfP8Pa/cy5HOvB/cvI4JgrYXTjh2Me3S6Now==",
"requires": {
"@emotion/core": "^10.0.15"
}
}, },
"react-transition-group": { "react-transition-group": {
"version": "4.4.1", "version": "4.4.1",
@ -14122,6 +14267,16 @@
"upath": "^1.1.1" "upath": "^1.1.1"
} }
}, },
"fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"glob-parent": { "glob-parent": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
@ -14429,6 +14584,16 @@
} }
} }
}, },
"fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"get-caller-file": { "get-caller-file": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",

View File

@ -11,7 +11,9 @@
"react": "16.8.0", "react": "16.8.0",
"react-click-away-listener": "^1.4.3", "react-click-away-listener": "^1.4.3",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-loading-overlay": "^1.0.1",
"react-scripts": "3.4.1", "react-scripts": "3.4.1",
"react-spinners": "^0.9.0",
"styled-components": "^5.1.1" "styled-components": "^5.1.1"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,13 +1,12 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="pl">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="https://plannaplan.pl/img/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta
name="description" name="description"
content="Web site created using create-react-app" content="Aplikacja do zapisów na zajęcia"
/> />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!-- <!--
@ -23,7 +22,7 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>React App</title> <title>PlanNaPlan</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>

View File

@ -12,6 +12,8 @@ const LeftSide = styled.div`
flex: 1; flex: 1;
flex-direction: column; flex-direction: column;
background-color: white; background-color: white;
text-align: center;
border-radius:5px;
`; `;
const Wrap = styled.div` const Wrap = styled.div`
@ -41,8 +43,14 @@ const LeftPanelElement = styled.div<LeftPanelElement>`
//box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.75); //box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.75);
padding: 20px; padding: 20px;
cursor: pointer; cursor: pointer;
box-shadow: ${({ isCurrentTab }) => (isCurrentTab === true ? `inset 0px 0px 26px 0px rgba(0,0,0,0.55)` : '')}; box-shadow: ${({ isCurrentTab }) => (isCurrentTab === true ? `inset 0px 0px 11px 0px rgba(0,0,0,0.30)` : '')};
border-bottom: 1px solid #979797; border-bottom: 1px solid #979797;
:first-child{
border-radius:0px 5px 0px 0px;
}
:last-child{
border-radius:0px 0px 5px 0px;
}
`; `;
const HistoryDiv = styled.div` const HistoryDiv = styled.div`
@ -89,7 +97,7 @@ const Icon = styled.img`
`; `;
export const Admin = () => { export const Admin = () => {
const [currentTab, setCurrentTab] = useState<null | number>(null); const [currentTab, setCurrentTab] = useState<null | number>(1);
const handleClick = (e: MouseEvent<HTMLDivElement>) => { const handleClick = (e: MouseEvent<HTMLDivElement>) => {
setCurrentTab(Number(e.currentTarget.id)); setCurrentTab(Number(e.currentTarget.id));

View File

@ -1,11 +1,13 @@
import React, { useState } from 'react'; import React, { ElementType, useContext, useState } from 'react';
import Topbar from './Topbar'; import Topbar from './Topbar';
import { Transfer } from './Transfer'; import { Transfer } from './Transfer';
import { Admin } from './Admin'; import { Admin } from './Admin';
import { Scheduler } from './Scheduler'; import { Scheduler } from './Scheduler';
import { Rightbar } from './Rightbar'; import { Rightbar } from './Rightbar';
import styled from 'styled-components'; import styled from 'styled-components';
import { coursesContext } from '../contexts/CoursesProvider';
import LoadingOverlay from 'react-loading-overlay';
import { SyncLoader } from 'react-spinners';
const Wrapper = styled.div` const Wrapper = styled.div`
display: flex; display: flex;
height: calc(100vh - 80px); height: calc(100vh - 80px);
@ -16,21 +18,31 @@ const Wrapper = styled.div`
`; `;
export const App = () => { export const App = () => {
const { isDataLoading } = useContext(coursesContext)!;
const [isOpenTransfer, setOpenTransfer] = useState(false); const [isOpenTransfer, setOpenTransfer] = useState(false);
const handleTransfer = () => { const handleTransfer = () => {
setOpenTransfer(!isOpenTransfer); setOpenTransfer(!isOpenTransfer);
}; };
const userPrivilige = localStorage.getItem('userPrivilige');
return ( return (
<> <>
<Topbar handleTransfer={handleTransfer} /> <LoadingOverlay active={isDataLoading} spinner={<SyncLoader />}>
<Transfer isOpen={isOpenTransfer} handleClose={handleTransfer} /> <Topbar handleTransfer={handleTransfer} />
<Wrapper> <Transfer isOpen={isOpenTransfer} handleClose={handleTransfer} />
{/* <Admin/> */} <Wrapper>
<Scheduler /> {userPrivilige === 'STUDENT' ? (
<Rightbar /> <>
</Wrapper> <Scheduler />
<Rightbar />
</>
) : (
<Admin />
)}
</Wrapper>
</LoadingOverlay>
</> </>
); );
}; };

View File

@ -7,6 +7,8 @@ import styled, { css } from 'styled-components';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import DeleteIcon from '@material-ui/icons/Delete'; import DeleteIcon from '@material-ui/icons/Delete';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { createClassTime } from '../utils';
import { dayMapping } from '../constants';
const CourseCardWrapper = styled.div` const CourseCardWrapper = styled.div`
position: relative; position: relative;
@ -20,7 +22,7 @@ const CourseCardWrapper = styled.div`
border-radius: 10px; border-radius: 10px;
cursor: pointer; cursor: pointer;
align-items: stretch; align-items: stretch;
box-shadow: 9px 9px 8px -2px rgba(0, 0, 0, 0.59); box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.75);
`; `;
const TitleWrapper = styled.div` const TitleWrapper = styled.div`
@ -48,17 +50,31 @@ const CourseName = styled.div`
user-select: none; user-select: none;
`; `;
const ClassGroupStyled = styled.div` type ClassGroupProps = {
isSelected: boolean;
};
const ClassGroupStyled = styled.div<ClassGroupProps>`
position: relative; position: relative;
padding-top: 1px; padding-top: 10px;
padding-bottom: 5px; padding-bottom: 10px;
transition: color 0.3s, background-color 0.3s;
:hover { :hover {
cursor: pointer; cursor: pointer;
background-color: #9ed3ff; ${({ isSelected }) =>
!isSelected &&
css`
background-color: rgba(223, 238, 245, 0.308);
`}
} }
:last-child { :last-child {
border-radius: 0 0 10px 10px; border-radius: 0 0 10px 10px;
} }
${({ isSelected }) =>
isSelected &&
css`
background-color: #85aec2;
`}
`; `;
interface ExpandIconProps { interface ExpandIconProps {
@ -102,7 +118,7 @@ type FlexItemProps = {
const FlexItem = styled.div<FlexItemProps>` const FlexItem = styled.div<FlexItemProps>`
display: flex; display: flex;
font-size: 14px; font-size: 14px;
font-weight: 600; font-weight: 500;
${({ justifyContent }) => ${({ justifyContent }) =>
justifyContent && justifyContent &&
css` css`
@ -141,12 +157,12 @@ export const CourseCard = ({ course }: CourseCardProps) => {
selectBasketCourseGroups, selectBasketCourseGroups,
changeHoveredGroup, changeHoveredGroup,
} = useContext(coursesContext)!; } = useContext(coursesContext)!;
const [isSelected, setSelected] = useState(false); const [isSelected, setSelected] = useState(true);
const groups = [...course.lectures!, ...course.classes!]; const groups = [...course.lectures!, ...course.classes!];
const basketCourseGroups = useMemo(() => selectBasketCourseGroups(course.id), []); const basketCourseGroups = useMemo(() => selectBasketCourseGroups(course.id), []);
const [previous, setPrevious] = useState(basketCourseGroups); const [previous, setPrevious] = useState(basketCourseGroups);
// console.log('lecture is: ', courseLecture);
// console.log('class is: ', courseClasses); console.log('course is: ', course);
const onGroupClick = (group: Group, courseId: number) => { const onGroupClick = (group: Group, courseId: number) => {
setPrevious((prev) => (group.type === GroupType.CLASS ? { ...prev, classes: group } : { ...prev, lecture: group })); setPrevious((prev) => (group.type === GroupType.CLASS ? { ...prev, classes: group } : { ...prev, lecture: group }));
changeGroupInBasket(group, courseId); changeGroupInBasket(group, courseId);
@ -168,16 +184,15 @@ export const CourseCard = ({ course }: CourseCardProps) => {
<Collapse className={classes.expanded} in={isSelected} timeout="auto" unmountOnExit> <Collapse className={classes.expanded} in={isSelected} timeout="auto" unmountOnExit>
{groups.map((group: Group, index) => ( {groups.map((group: Group, index) => (
<ClassGroupStyled <ClassGroupStyled
isSelected={group.id === previous?.classes?.id || group.id === previous?.lecture?.id ? true : false}
key={index} key={index}
onClick={() => onGroupClick(group, course.id)} onClick={() => onGroupClick(group, course.id)}
onMouseEnter={() => { onMouseEnter={() => {
if (group.type === GroupType.CLASS) { if (group.type === GroupType.CLASS) {
changeGroupInBasket(group, course.id); changeGroupInBasket(group, course.id);
// setTimeout(()=> { changeHoveredGroup(courseClasses)},[500])
} }
if (group.type === GroupType.LECTURE) { if (group.type === GroupType.LECTURE) {
changeGroupInBasket(group, course.id); changeGroupInBasket(group, course.id);
// setTimeout(()=> { changeHoveredGroup(courseLecture)},[500])
} }
}} }}
onMouseLeave={() => { onMouseLeave={() => {
@ -203,8 +218,14 @@ export const CourseCard = ({ course }: CourseCardProps) => {
{group.lecturer.replace('UAM', '')} {group.lecturer.replace('UAM', '')}
</FlexItem> </FlexItem>
)} )}
<FlexItem style={{ justifyContent: 'center', margin: '0 50px' }}> <FlexItem style={{ justifyContent: 'center', flexDirection: 'column' }}>
<span>{/*group.time*/}</span> <span> Sala: {group.room}</span> {/* <span>
{dayMapping[group.day]} {createClassTime(group.time)[0]} - {createClassTime(group.time)[1]}
</span> */}
<div>{dayMapping[group.day]}</div>
<div>
{createClassTime(group.time)[0]} - {createClassTime(group.time)[1]}
</div>
</FlexItem> </FlexItem>
</FlexboxWrapper> </FlexboxWrapper>
</ClassGroupStyled> </ClassGroupStyled>

View File

@ -1,6 +1,7 @@
import React, { useState, useContext, useEffect, MouseEvent, useMemo } from 'react'; import React, { useState, useContext, useEffect, MouseEvent, useMemo } from 'react';
import { coursesContext } from '../contexts/CoursesProvider'; import { coursesContext } from '../contexts/CoursesProvider';
import { Course } from '../types'; import { studentsContext } from '../contexts/StudentsProvider';
import { Course, Student } from '../types';
import styled from 'styled-components'; import styled from 'styled-components';
const DropdownContainer = styled.div` const DropdownContainer = styled.div`
@ -45,12 +46,17 @@ interface DropdownProps {
open: boolean; open: boolean;
input: string; input: string;
handleCloseDropdown: () => void; handleCloseDropdown: () => void;
selectedOption: string;
} }
export const Dropdown = ({ open, input, handleCloseDropdown }: DropdownProps) => { export const Dropdown = ({ open, input, handleCloseDropdown, selectedOption }: DropdownProps) => {
const { courses, selectBasketNames, addCourseToBasket } = useContext(coursesContext)!; const { courses, selectBasketNames, addCourseToBasket, changeStudent } = useContext(
coursesContext,
)!;
const { students } = useContext(studentsContext)!;
const basketNames = useMemo(() => selectBasketNames(), [selectBasketNames]); const basketNames = useMemo(() => selectBasketNames(), [selectBasketNames]);
const [filteredCourses, setFilteredCourses] = useState<Array<Course>>([]); const [filteredCourses, setFilteredCourses] = useState<Array<Course>>([]);
const [filteredStudents, setFilteredStudents] = useState<Array<Student>>([]);
const onCourseClick = (event: MouseEvent) => { const onCourseClick = (event: MouseEvent) => {
const target = event.currentTarget; const target = event.currentTarget;
@ -61,6 +67,12 @@ export const Dropdown = ({ open, input, handleCloseDropdown }: DropdownProps) =>
} }
}; };
const onUserClick = (event: MouseEvent) => {
const target = event.currentTarget;
changeStudent(target.id);
handleCloseDropdown();
};
useEffect(() => { useEffect(() => {
const filterCourses = (input: string) => { const filterCourses = (input: string) => {
const filteredCourses = courses.filter( const filteredCourses = courses.filter(
@ -81,15 +93,48 @@ export const Dropdown = ({ open, input, handleCloseDropdown }: DropdownProps) =>
filterCourses(input); filterCourses(input);
}, [basketNames, courses, input]); }, [basketNames, courses, input]);
useEffect(() => {
const filterUsers = (input: string) => {
const filteredUsers = students.filter(({ name, surname }) =>
(name + surname)
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.includes(
input
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, ''),
),
);
setFilteredStudents(filteredUsers);
};
filterUsers(input);
}, [students, input]);
return ( return (
<DropdownContainer> <DropdownContainer>
{open && ( {open && (
<> <>
{filteredCourses.map(({ name, id }, index) => ( {selectedOption === 'studenci' ? (
<CourseContainer key={index} id={id.toString()} onClick={onCourseClick}> <div>
<p>{name} </p> {filteredStudents.map(({ name, surname, id }, index) => (
</CourseContainer> <CourseContainer key={index} id={id.toString()} onClick={onUserClick}>
))} <p>
{name} {surname}
</p>
</CourseContainer>
))}
</div>
) : (
<div>
{filteredCourses.map(({ name, id }, index) => (
<CourseContainer key={index} id={id.toString()} onClick={onCourseClick}>
<p>{name} </p>
</CourseContainer>
))}
</div>
)}
</> </>
)} )}
</DropdownContainer> </DropdownContainer>

View File

@ -44,14 +44,14 @@ const SaveButton = styled.div`
background-color: #54c457; background-color: #54c457;
} }
box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.24); box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.75);
`; `;
export const Rightbar = () => { export const Rightbar = () => {
const { selectBasketCourses, saveBasket } = useContext(coursesContext)!; const { selectBasketCourses, saveBasket, userID } = useContext(coursesContext)!;
const basketCourses = selectBasketCourses(); const basketCourses = selectBasketCourses();
const handleSave = debounce(() => saveBasket(), 500); const handleSave = debounce(() => saveBasket(userID), 500);
return ( return (
<RightbarWrapper> <RightbarWrapper>
<SaveButton onClick={handleSave}>ZAPISZ</SaveButton> <SaveButton onClick={handleSave}>ZAPISZ</SaveButton>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useLayoutEffect, useRef } from 'react';
import { useState } from 'react'; import { useState } from 'react';
import { SchedulerEvents } from './SchedulerEvents'; import { SchedulerEvents } from './SchedulerEvents';
import { days, hours } from '../constants/index'; import { days, hours } from '../constants/index';
@ -66,7 +66,7 @@ export const Scheduler = () => {
const [cellWidth, setCellWidth] = useState(0); const [cellWidth, setCellWidth] = useState(0);
const [cellHeight, setCellHeight] = useState(0); const [cellHeight, setCellHeight] = useState(0);
useEffect(() => { useLayoutEffect(() => {
const handleResize = () => { const handleResize = () => {
if (cellRef.current) { if (cellRef.current) {
setCellWidth(cellRef.current.getBoundingClientRect().width); setCellWidth(cellRef.current.getBoundingClientRect().width);

View File

@ -1,4 +1,4 @@
import React, { Fragment, MouseEvent, useState, useEffect, useContext } from 'react'; import React, { Fragment, MouseEvent, useState, useEffect, useContext } from 'react';
import { GroupType, SchedulerEvent } from '../types'; import { GroupType, SchedulerEvent } from '../types';
import styled, { css } from 'styled-components/macro'; import styled, { css } from 'styled-components/macro';
import Popover from '@material-ui/core/Popover'; import Popover from '@material-ui/core/Popover';
@ -65,12 +65,19 @@ const StyledSchedulerEvent = styled.div<SchedulerEventProps>`
text-align: center; text-align: center;
background-color: ${({ groupType, isHovered }) => { background-color: ${({ groupType, isHovered }) => {
if (isHovered) { if (isHovered) {
return groupType === 'CLASS' ? '#ffefb5' : '#d4ecff'; return groupType === 'CLASS' ? '#FFE485' : '#D2EBFF';
} else { } else {
return groupType === 'CLASS' ? '#FFDC61' : '#9ed3ff'; return groupType === 'CLASS' ? '#FFDC61' : '#9ed3ff';
} }
}}; }};
${({ isHovered }) =>
isHovered &&
css`
transition: background-color ease-in 0.4s;
`}
transition: background-color ease-out 0.4s;
box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.75); box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.75);
cursor:pointer;
`; `;
const threeStyles = () => { const threeStyles = () => {
@ -134,7 +141,6 @@ export const SchedulerRow = ({ groups, indexRow, rowTop, cellWidth, cellHeight }
const [popoverId, setPopoverId] = useState<string | null>(null); const [popoverId, setPopoverId] = useState<string | null>(null);
//looks weird //looks weird
const handlePopoverOpen = (event: MouseEvent<HTMLDivElement, globalThis.MouseEvent>) => { const handlePopoverOpen = (event: MouseEvent<HTMLDivElement, globalThis.MouseEvent>) => {
console.log('I was clicked!!!!');
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
setPopoverId(event.currentTarget.id); setPopoverId(event.currentTarget.id);
}; };
@ -212,12 +218,7 @@ export const SchedulerRow = ({ groups, indexRow, rowTop, cellWidth, cellHeight }
onClose={handlePopoverClose} onClose={handlePopoverClose}
disableRestoreFocus disableRestoreFocus
> >
<div <div style={{ display: 'flex', flexDirection: 'column', zIndex: 20000 }} onClick={() => {}}>
style={{ display: 'flex', flexDirection: 'column', zIndex: 20000 }}
onClick={() => {
console.log('XDD');
}}
>
<p style={{ margin: '7px 0 7px 0', fontWeight: 'bold' }}>{groups[index].name}</p> <p style={{ margin: '7px 0 7px 0', fontWeight: 'bold' }}>{groups[index].name}</p>
<p style={{ margin: '2px 0 2px 0' }}> <p style={{ margin: '2px 0 2px 0' }}>
<PopoverSpan>Prowadzący:</PopoverSpan> {groups[index].lecturer} <PopoverSpan>Prowadzący:</PopoverSpan> {groups[index].lecturer}

View File

@ -15,6 +15,7 @@ const Wrapper = styled.div`
color: black; color: black;
border-top-left-radius: 6px; border-top-left-radius: 6px;
border-bottom-left-radius: 6px; border-bottom-left-radius: 6px;
&:focus { &:focus {
outline: none; outline: none;
} }
@ -64,16 +65,23 @@ const ExpandIconSelect = styled(ExpandIcon)`
width: 10px; width: 10px;
height: 10px; height: 10px;
`; `;
export const SelectMenu = () => {
interface SelectMenuProps {
changeSelectedOption: (option: string) => void;
changeDropdownOpen: (dropdownState: boolean) => void;
selectedOption:string;
}
export const SelectMenu = ({changeSelectedOption,changeDropdownOpen, selectedOption}:SelectMenuProps) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState('przedmioty');
return ( return (
<ClickAwayListener <ClickAwayListener
onClickAway={() => { onClickAway={() => {
setIsOpen(false); setIsOpen(false);
}} }}
> >
<Wrapper> <Wrapper onClick={() => {changeDropdownOpen(false)}}>
<Header <Header
onClick={() => { onClick={() => {
console.log('clicked'); console.log('clicked');
@ -87,7 +95,7 @@ export const SelectMenu = () => {
<List> <List>
<ListItem <ListItem
onClick={() => { onClick={() => {
setSelectedOption('przedmioty'); changeSelectedOption('przedmioty');
setIsOpen(false); setIsOpen(false);
}} }}
> >
@ -95,7 +103,7 @@ export const SelectMenu = () => {
</ListItem> </ListItem>
<ListItem <ListItem
onClick={() => { onClick={() => {
setSelectedOption('studenci'); changeSelectedOption('studenci');
setIsOpen(false); setIsOpen(false);
}} }}
> >

View File

@ -54,13 +54,17 @@ const FlexboxColumn = styled.div`
flex: 12; flex: 12;
`; `;
const InputWrapper = styled.div` type InputWrapperProps = {
isStudent: boolean;
};
const InputWrapper = styled.div<InputWrapperProps>`
width: 100%; width: 100%;
display: flex; display: flex;
margin-top: 15px; margin-top: 15px;
max-height: 40px; max-height: 40px;
background-color: #f2f4f7; background-color: #f2f4f7;
border-radius: 6px 6px 6px 6px; border-radius: ${({ isStudent }) => (isStudent ? ` 6px 6px 6px 6px` : ` 0px 6px 6px 0px`)};
padding-left: 6px; padding-left: 6px;
&:hover { &:hover {
background-color: #ffffff; background-color: #ffffff;
@ -123,11 +127,16 @@ interface TopbarProps {
} }
export default function ({ handleTransfer }: TopbarProps) { export default function ({ handleTransfer }: TopbarProps) {
const userPrivilige = localStorage.getItem('userPrivilige');
const [clearInput, setClearInput] = useState(false); const [clearInput, setClearInput] = useState(false);
const [isPolish, setIsPolish] = useState(false); const [isPolish, setIsPolish] = useState(false);
const [anchorEl, setAnchorEl] = useState<HTMLImageElement | null>(null); const [anchorEl, setAnchorEl] = useState<HTMLImageElement | null>(null);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [input, setInput] = useState(''); const [input, setInput] = useState('');
const [selectedOption, setSelectedOption] = useState('przedmioty');
const changeSelectedOption = (option: string) => setSelectedOption(option);
const onLangChange = () => setIsPolish(!isPolish); const onLangChange = () => setIsPolish(!isPolish);
@ -159,15 +168,16 @@ export default function ({ handleTransfer }: TopbarProps) {
<FlexboxColumn> <FlexboxColumn>
<ClickAwayListener onClickAway={handleCloseDropdown}> <ClickAwayListener onClickAway={handleCloseDropdown}>
<Flexbox> <Flexbox>
{/* <SelectMenu /> */} {userPrivilige !== 'STUDENT' && (
<SelectMenu
<InputWrapper> changeSelectedOption={changeSelectedOption}
{/* <SelectSearch value={value} onChange={Change}> selectedOption={selectedOption}
<SelectOption value="przedmiot">Przedmiot</SelectOption> changeDropdownOpen={setOpen}
<SelectOption value="student">Student</SelectOption> />
</SelectSearch> */} )}
<InputWrapper isStudent={userPrivilige === 'STUDENT'}>
<Input <Input
placeholder={`Wyszukaj...`} placeholder={`Wyszukaj ${selectedOption === 'studenci' ? 'studentów...' : 'przedmioty...'}`}
onChange={handleChange} onChange={handleChange}
value={input} value={input}
onFocus={() => { onFocus={() => {
@ -177,14 +187,19 @@ export default function ({ handleTransfer }: TopbarProps) {
<CloseIcon onClick={handleClearInput} /> <CloseIcon onClick={handleClearInput} />
</InputWrapper> </InputWrapper>
</Flexbox> </Flexbox>
<Dropdown open={open} input={input} handleCloseDropdown={handleCloseDropdown} /> <Dropdown
open={open}
input={input}
handleCloseDropdown={handleCloseDropdown}
selectedOption={selectedOption}
/>
</ClickAwayListener> </ClickAwayListener>
</FlexboxColumn> </FlexboxColumn>
<IconWrapper> <IconWrapper>
{/* <Text>Maciej Głowacki</Text> */} {/* <Text>Maciej Głowacki</Text> */}
{/* <Icon alt="transfer" src={Transfer} onClick={handleTransfer} /> */} {/* <Icon alt="transfer" src={Transfer} onClick={handleTransfer} /> */}
<Icon alt="change_language" src={isPolish ? EnglishIcon : PolishIcon} onClick={onLangChange} /> {/* <Icon alt="change_language" src={isPolish ? EnglishIcon : PolishIcon} onClick={onLangChange} /> */}
<Icon alt="profile" src={ProfileIcon} onClick={handleProfile} /> <Icon alt="profile" src={ProfileIcon} onClick={handleProfile} />
<Profile anchorEl={anchorEl} handleClose={handleCloseProfile} /> <Profile anchorEl={anchorEl} handleClose={handleCloseProfile} />
</IconWrapper> </IconWrapper>

View File

@ -42,3 +42,12 @@ export const courseStartTimeToEventRow: { [time: string]: number } = {
//groupTimeToEventRowMapping - 1; //groupTimeToEventRowMapping - 1;
export const ROWS_COUNT = 6; export const ROWS_COUNT = 6;
export const dayMapping: { [key: number]: string } = {
0: 'poniedziałek',
1: 'wtorek',
2: 'środa',
3: 'czwartek',
4: 'piątek',
5: 'sobota',
6: 'niedziela',
};

View File

@ -1,11 +1,11 @@
import React, { useState, useEffect, createContext, ReactNode } from 'react'; import React, { useState, useEffect, createContext, ReactNode } from 'react';
import { User } from '../types'; import { LoggedUser } from '../types';
import { axiosInstance } from '../utils/axiosInstance'; import { axiosInstance } from '../utils/axiosInstance';
export interface CASContext { export interface CASContext {
user?: User; user: LoggedUser | undefined;
logout: () => void; logout: () => void;
token?: string | null; token: string | undefined;
} }
export const CASContext = createContext<CASContext | undefined>(undefined); export const CASContext = createContext<CASContext | undefined>(undefined);
@ -15,8 +15,8 @@ export interface CASProviderProps {
} }
export const CASProvider = ({ children }: CASProviderProps) => { export const CASProvider = ({ children }: CASProviderProps) => {
const [user, setUser] = useState<User | undefined>(undefined); const [user, setUser] = useState<LoggedUser>();
const [token, setToken] = useState<string | null>(null); const [token, setToken] = useState<string | undefined>();
useEffect(() => { useEffect(() => {
const login = async () => { const login = async () => {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
@ -25,12 +25,16 @@ export const CASProvider = ({ children }: CASProviderProps) => {
redirectToCASLoginService(); redirectToCASLoginService();
} }
try { try {
if (!sessionStorage.getItem('userToken')) { if (!localStorage.getItem('userToken')) {
const { data: token } = await axiosInstance.get(`${process.env.REACT_APP_API_URL}/token?ticket=${ticket}`); const { data: user } = await axiosInstance.get<LoggedUser & { token: string }>(
sessionStorage.setItem('userToken', token); `${process.env.REACT_APP_API_URL}/token?ticket=${ticket}`,
);
setUser({ authorityRole: user.authorityRole, email: user.email, id: user.id });
localStorage.setItem('userToken', user.token);
localStorage.setItem('userPrivilige', user.authorityRole);
} }
const token = sessionStorage.getItem('userToken'); const token = localStorage.getItem('userToken');
setToken(token); token && setToken(token);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} }
@ -39,6 +43,7 @@ export const CASProvider = ({ children }: CASProviderProps) => {
}, []); }, []);
function logout() { function logout() {
localStorage.removeItem('userToken');
redirectToCASLogoutService(); redirectToCASLogoutService();
} }

View File

@ -18,16 +18,21 @@ interface CourseContext {
courses: Array<Course>; courses: Array<Course>;
basket: Array<Basket>; basket: Array<Basket>;
hoveredGroup: Group | undefined | null; hoveredGroup: Group | undefined | null;
userID: string;
isDataLoading: boolean;
addCourseToBasket: (courses: Course) => void; addCourseToBasket: (courses: Course) => void;
changeHoveredGroup: (group: Group | null) => void; changeHoveredGroup: (group: Group | null) => void;
changeGroupInBasket: (group: Group, courseId: number) => void; changeGroupInBasket: (group: Group, courseId: number) => void;
restoreGroupInBasket: (restoreGroup: Group, courseId: number) => void; restoreGroupInBasket: (restoreGroup: Group, courseId: number) => void;
deleteFromBasket: (id: number) => void; deleteFromBasket: (id: number) => void;
saveBasket: () => void; saveBasket: (userID: string) => Promise<void>;
changeStudent: (studentId: string) => void;
selectSchedulerEvents: () => Array<SchedulerEvent>; selectSchedulerEvents: () => Array<SchedulerEvent>;
selectBasketNames: () => Array<string>; selectBasketNames: () => Array<string>;
selectBasketCourses: () => Array<Course>; selectBasketCourses: () => Array<Course>;
selectBasketCourseGroups: (courseId: number) => { lecture: Group | undefined; classes: Group | undefined }; selectBasketCourseGroups: (courseId: number) => { lecture: Group | undefined; classes: Group | undefined };
getNewestStudentTimetable: (studentId: string) => void;
changeDataLoading: (isLoading: boolean) => void;
} }
export const coursesContext = createContext<CourseContext | undefined>(undefined); export const coursesContext = createContext<CourseContext | undefined>(undefined);
@ -42,7 +47,10 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
//fetch courses with groups //fetch courses with groups
const [courses, setCourses] = useState<Array<Course>>([]); const [courses, setCourses] = useState<Array<Course>>([]);
const [basket, setBasket] = useState<Array<Basket>>([]); const [basket, setBasket] = useState<Array<Basket>>([]);
const [userID, setUserID] = useState('');
const [hoveredGroup, setHoveredGroup] = useState<Group | undefined | null>(null); const [hoveredGroup, setHoveredGroup] = useState<Group | undefined | null>(null);
const [isDataLoading, setIsDataLoading] = useState(false);
const selectBasketIds = () => { const selectBasketIds = () => {
const classesIds = basket.map((course) => course?.classes?.id).filter((course) => course !== undefined); const classesIds = basket.map((course) => course?.classes?.id).filter((course) => course !== undefined);
const lecturesIds = basket.map((course) => course?.lecture?.id).filter((course) => course !== undefined); const lecturesIds = basket.map((course) => course?.lecture?.id).filter((course) => course !== undefined);
@ -85,6 +93,8 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
const changeHoveredGroup = (group: Group | null) => setHoveredGroup(group); const changeHoveredGroup = (group: Group | null) => setHoveredGroup(group);
const changeDataLoading = (isLoading: boolean) => setIsDataLoading(isLoading);
const addCourseToBasket = (course: Course) => { const addCourseToBasket = (course: Course) => {
const courseToBasket: Basket = { const courseToBasket: Basket = {
name: course.name, name: course.name,
@ -97,7 +107,14 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
const deleteFromBasket = (id: number) => setBasket(basket.filter((course) => course.id !== id)); const deleteFromBasket = (id: number) => setBasket(basket.filter((course) => course.id !== id));
const saveBasket = async () => { const changeStudent = async (studentId: string) => {
setUserID(studentId);
setTimeout(() => {
getNewestStudentTimetable(studentId);
}, 100);
};
const saveBasket = async (userID: string) => {
const basketIds = selectBasketIds(); const basketIds = selectBasketIds();
const action = (key: any) => ( const action = (key: any) => (
<> <>
@ -110,7 +127,10 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
); );
try { try {
await axiosInstance.post(`${process.env.REACT_APP_API_URL}/api/v1/commisions/user`, JSON.stringify(basketIds)); await axiosInstance.post(
`${process.env.REACT_APP_API_URL}/api/v1/commisions/user/${userID}`,
JSON.stringify(basketIds),
);
enqueueSnackbar('Plan został zapisany', { enqueueSnackbar('Plan został zapisany', {
variant: 'success', variant: 'success',
action, action,
@ -154,9 +174,19 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
}; };
const getNewestTimetable = async () => { const getNewestTimetable = async () => {
try {
const { data } = await axiosInstance.get(`${process.env.REACT_APP_API_URL}/api/v1/commisions/user/schedule`);
const basket = data === '' ? [] : data;
setBasket(basket);
} catch (e) {
console.log(e);
}
};
const getNewestStudentTimetable = async (studentId: string) => {
try { try {
const { data } = await axiosInstance.get( const { data } = await axiosInstance.get(
`${process.env.REACT_APP_API_URL}/api/v1/assignments/user`, `${process.env.REACT_APP_API_URL}/api/v1/commisions/user/${studentId}/schedule`,
); );
const basket = data === '' ? [] : data; const basket = data === '' ? [] : data;
setBasket(basket); setBasket(basket);
@ -178,18 +208,22 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
}; };
useEffect(() => { useEffect(() => {
setIsDataLoading(true);
setTimeout(() => { setTimeout(() => {
fetchCourses(); fetchCourses();
getNewestTimetable(); getNewestTimetable();
}, 200); setIsDataLoading(false);
}, 500);
}, []); }, []);
return ( return (
<coursesContext.Provider <coursesContext.Provider
value={{ value={{
userID,
courses, courses,
basket, basket,
hoveredGroup, hoveredGroup,
isDataLoading,
addCourseToBasket, addCourseToBasket,
changeHoveredGroup, changeHoveredGroup,
changeGroupInBasket, changeGroupInBasket,
@ -200,6 +234,9 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
selectBasketNames, selectBasketNames,
selectBasketCourses, selectBasketCourses,
selectBasketCourseGroups, selectBasketCourseGroups,
getNewestStudentTimetable,
changeStudent,
changeDataLoading,
}} }}
> >
{children} {children}

View File

@ -0,0 +1,51 @@
import React, { useState, createContext, useEffect, ReactNode, useRef, useContext } from 'react';
import { Student } from '../types';
import { axiosInstance } from '../utils/axiosInstance';
import { CASContext } from './CASProvider';
interface StudentContext {
students: Array<Student>;
}
export const studentsContext = createContext<StudentContext | undefined>(undefined);
interface StudentsProviderProps {
children: ReactNode;
}
export const StudentsProvider = ({ children }: StudentsProviderProps) => {
const [students, setStudents] = useState<Array<Student>>([]);
//not working currently
const userPrivilige = localStorage.getItem('userPrivilige');
const { user } = useContext(CASContext)!;
const getStudents = async () => {
try {
const { data } = await axiosInstance.get<Array<Student>>(
`${process.env.REACT_APP_API_URL}/api/v1/users/students`,
);
setStudents(data);
console.log(data);
} catch (e) {
console.log(e);
}
};
useEffect(() => {
setTimeout(() => {
// user?.authorityRole === 'DEANERY' &&
getStudents();
}, 500);
}, []);
return (
<studentsContext.Provider
value={{
students,
}}
>
{children}
</studentsContext.Provider>
);
};

View File

@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import { App } from './components/App'; import { App } from './components/App';
import { CASProvider } from './contexts/CASProvider'; import { CASProvider } from './contexts/CASProvider';
import { CoursesProvider } from './contexts/CoursesProvider'; import { CoursesProvider } from './contexts/CoursesProvider';
import { StudentsProvider } from './contexts/StudentsProvider';
import { GlobalStyles } from './styles/GlobalStyles'; import { GlobalStyles } from './styles/GlobalStyles';
import { SnackbarProvider } from 'notistack'; import { SnackbarProvider } from 'notistack';
@ -16,10 +17,12 @@ ReactDOM.render(
}} }}
> >
<CASProvider> <CASProvider>
<CoursesProvider> <StudentsProvider>
<GlobalStyles /> <CoursesProvider>
<App /> <GlobalStyles />
</CoursesProvider> <App />
</CoursesProvider>
</StudentsProvider>
</CASProvider> </CASProvider>
</SnackbarProvider> </SnackbarProvider>
</>, </>,

View File

@ -27,9 +27,17 @@ export interface Course {
classes?: Array<Group>; classes?: Array<Group>;
} }
export interface User { export interface LoggedUser {
name?: string; authorityRole: string;
surname?: string; email: string;
id: number;
}
export interface Student {
email: string;
id: number;
name: string;
surname: string;
} }
export interface SchedulerEvent { export interface SchedulerEvent {

View File

@ -4,9 +4,9 @@ export const axiosInstance = axios.create();
axiosInstance.interceptors.request.use( axiosInstance.interceptors.request.use(
(config) => { (config) => {
const token = sessionStorage.getItem('userToken'); const token = localStorage.getItem('userToken');
config.headers['Authorization'] = 'Bearer ' + token;
config.headers['Content-Type'] = 'application/json'; config.headers['Content-Type'] = 'application/json';
config.headers['Authorization'] = token ? `Bearer ${token}` : '';
return config; return config;
}, },
(error) => { (error) => {

View File

@ -13,6 +13,10 @@ export const selectGroupsToShow = (schedulerEvents: Array<SchedulerEvent>, index
return schedulerEvents.filter(({ time }: { time: [string, string] }) => courseStartTimeToEventRow[time[0]] === index); return schedulerEvents.filter(({ time }: { time: [string, string] }) => courseStartTimeToEventRow[time[0]] === index);
}; };
//debounce declaration and implementation
type Procedure = (...args: any[]) => any; type Procedure = (...args: any[]) => any;
interface Debounce { interface Debounce {

View File

@ -15,5 +15,5 @@
"noEmit": true, "noEmit": true,
"jsx": "react" "jsx": "react"
}, },
"include": ["src"] "include": ["src", "decs.d.ts"]
} }

11882
yarn-error.log Normal file

File diff suppressed because it is too large Load Diff

150
yarn.lock
View File

@ -1153,7 +1153,7 @@
dependencies: dependencies:
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7": "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7":
version "7.12.5" version "7.12.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
@ -1251,7 +1251,38 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18" resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg== integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
"@emotion/hash@^0.8.0": "@emotion/cache@^10.0.27":
version "10.0.29"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0"
integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==
dependencies:
"@emotion/sheet" "0.9.4"
"@emotion/stylis" "0.8.5"
"@emotion/utils" "0.11.3"
"@emotion/weak-memoize" "0.2.5"
"@emotion/core@^10.0.15":
version "10.1.1"
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3"
integrity sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==
dependencies:
"@babel/runtime" "^7.5.5"
"@emotion/cache" "^10.0.27"
"@emotion/css" "^10.0.27"
"@emotion/serialize" "^0.11.15"
"@emotion/sheet" "0.9.4"
"@emotion/utils" "0.11.3"
"@emotion/css@^10.0.27":
version "10.0.27"
resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c"
integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==
dependencies:
"@emotion/serialize" "^0.11.15"
"@emotion/utils" "0.11.3"
babel-plugin-emotion "^10.0.27"
"@emotion/hash@0.8.0", "@emotion/hash@^0.8.0":
version "0.8.0" version "0.8.0"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
@ -1268,16 +1299,42 @@
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
"@emotion/stylis@^0.8.4": "@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16":
version "0.11.16"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad"
integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==
dependencies:
"@emotion/hash" "0.8.0"
"@emotion/memoize" "0.7.4"
"@emotion/unitless" "0.7.5"
"@emotion/utils" "0.11.3"
csstype "^2.5.7"
"@emotion/sheet@0.9.4":
version "0.9.4"
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5"
integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==
"@emotion/stylis@0.8.5", "@emotion/stylis@^0.8.4":
version "0.8.5" version "0.8.5"
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
"@emotion/unitless@^0.7.4": "@emotion/unitless@0.7.5", "@emotion/unitless@^0.7.4":
version "0.7.5" version "0.7.5"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
"@emotion/utils@0.11.3":
version "0.11.3"
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924"
integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==
"@emotion/weak-memoize@0.2.5":
version "0.2.5"
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
"@hapi/address@2.x.x": "@hapi/address@2.x.x":
version "2.1.4" version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@ -2572,6 +2629,22 @@ babel-plugin-dynamic-import-node@^2.3.3:
dependencies: dependencies:
object.assign "^4.1.0" object.assign "^4.1.0"
babel-plugin-emotion@^10.0.27:
version "10.0.33"
resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz#ce1155dcd1783bbb9286051efee53f4e2be63e03"
integrity sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@emotion/hash" "0.8.0"
"@emotion/memoize" "0.7.4"
"@emotion/serialize" "^0.11.16"
babel-plugin-macros "^2.0.0"
babel-plugin-syntax-jsx "^6.18.0"
convert-source-map "^1.5.0"
escape-string-regexp "^1.0.5"
find-root "^1.1.0"
source-map "^0.5.7"
babel-plugin-istanbul@^5.1.0: babel-plugin-istanbul@^5.1.0:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854"
@ -2589,7 +2662,7 @@ babel-plugin-jest-hoist@^24.9.0:
dependencies: dependencies:
"@types/babel__traverse" "^7.0.6" "@types/babel__traverse" "^7.0.6"
babel-plugin-macros@2.8.0: babel-plugin-macros@2.8.0, babel-plugin-macros@^2.0.0:
version "2.8.0" version "2.8.0"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138"
integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==
@ -3483,7 +3556,7 @@ content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.7.0: convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0:
version "1.7.0" version "1.7.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
@ -3587,6 +3660,16 @@ create-ecdh@^4.0.0:
bn.js "^4.1.0" bn.js "^4.1.0"
elliptic "^6.5.3" elliptic "^6.5.3"
create-emotion@^10.0.27:
version "10.0.27"
resolved "https://registry.yarnpkg.com/create-emotion/-/create-emotion-10.0.27.tgz#cb4fa2db750f6ca6f9a001a33fbf1f6c46789503"
integrity sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg==
dependencies:
"@emotion/cache" "^10.0.27"
"@emotion/serialize" "^0.11.15"
"@emotion/sheet" "0.9.4"
"@emotion/utils" "0.11.3"
create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
@ -3885,7 +3968,7 @@ cssstyle@^1.0.0, cssstyle@^1.1.1:
dependencies: dependencies:
cssom "0.3.x" cssom "0.3.x"
csstype@^2.5.2: csstype@^2.5.2, csstype@^2.5.7:
version "2.6.14" version "2.6.14"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.14.tgz#004822a4050345b55ad4dcc00be1d9cf2f4296de" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.14.tgz#004822a4050345b55ad4dcc00be1d9cf2f4296de"
integrity sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A== integrity sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A==
@ -4153,6 +4236,13 @@ dom-converter@^0.2:
dependencies: dependencies:
utila "~0.4" utila "~0.4"
dom-helpers@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
dependencies:
"@babel/runtime" "^7.1.2"
dom-helpers@^5.0.1: dom-helpers@^5.0.1:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
@ -4310,6 +4400,14 @@ emojis-list@^3.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
emotion@^10.0.1:
version "10.0.27"
resolved "https://registry.yarnpkg.com/emotion/-/emotion-10.0.27.tgz#f9ca5df98630980a23c819a56262560562e5d75e"
integrity sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g==
dependencies:
babel-plugin-emotion "^10.0.27"
create-emotion "^10.0.27"
encodeurl@~1.0.2: encodeurl@~1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@ -5069,6 +5167,11 @@ find-cache-dir@^3.2.0, find-cache-dir@^3.3.1:
make-dir "^3.0.2" make-dir "^3.0.2"
pkg-dir "^4.1.0" pkg-dir "^4.1.0"
find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
find-up@4.1.0, find-up@^4.0.0: find-up@4.1.0, find-up@^4.0.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
@ -9344,6 +9447,20 @@ react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-loading-overlay@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/react-loading-overlay/-/react-loading-overlay-1.0.1.tgz#ee3b1ad56c45bb2f1ba46d4820ba0d06cd319a91"
integrity sha512-aUjtZ8tNXBSx+MbD2SQs0boPbeTAGTh+I5U9nWjDzMasKlYr58RJpr57c8W7uApeLpOkAGbInExRi6GamNC2bA==
dependencies:
emotion "^10.0.1"
prop-types "^15.6.2"
react-transition-group "^2.5.0"
react-scripts@3.4.1: react-scripts@3.4.1:
version "3.4.1" version "3.4.1"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a"
@ -9404,6 +9521,23 @@ react-scripts@3.4.1:
optionalDependencies: optionalDependencies:
fsevents "2.1.2" fsevents "2.1.2"
react-spinners@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.9.0.tgz#b22c38acbfce580cd6f1b04a4649e812370b1fb8"
integrity sha512-+x6eD8tn/aYLdxZjNW7fSR1uoAXLb9qq6TFYZR1dFweJvckcf/HfP8Pa/cy5HOvB/cvI4JgrYXTjh2Me3S6Now==
dependencies:
"@emotion/core" "^10.0.15"
react-transition-group@^2.5.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
dependencies:
dom-helpers "^3.4.0"
loose-envify "^1.4.0"
prop-types "^15.6.2"
react-lifecycles-compat "^3.0.4"
react-transition-group@^4.4.0: react-transition-group@^4.4.0:
version "4.4.1" version "4.4.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
@ -10269,7 +10403,7 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.5.0, source-map@^0.5.6: source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7:
version "0.5.7" version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=