Merge pull request 'redesign' (#32) from redesign into master
Reviewed-on: http://git.plannaplan.pl/y0rune/frontend/pulls/32 Reviewed-by: Maciej <glowackimaciej97@gmail.com>
56
.eslintrc.js
@ -1,28 +1,28 @@
|
||||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: [
|
||||
'plugin:react/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'prettier/@typescript-eslint',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_|^req|^next' }],
|
||||
'@typescript-eslint/no-explicit-any': 0,
|
||||
'@typescript-eslint/explicit-function-return-type': 0,
|
||||
'react/prop-types': 0,
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
};
|
||||
// module.exports = {
|
||||
// parser: '@typescript-eslint/parser',
|
||||
// extends: [
|
||||
// 'plugin:react/recommended',
|
||||
// 'plugin:@typescript-eslint/recommended',
|
||||
// 'prettier/@typescript-eslint',
|
||||
// 'plugin:prettier/recommended',
|
||||
// 'plugin:react-hooks/recommended',
|
||||
// ],
|
||||
// parserOptions: {
|
||||
// ecmaVersion: 2020,
|
||||
// sourceType: 'module',
|
||||
// ecmaFeatures: {
|
||||
// jsx: true,
|
||||
// },
|
||||
// },
|
||||
// rules: {
|
||||
// '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_|^req|^next' }],
|
||||
// '@typescript-eslint/no-explicit-any': 0,
|
||||
// '@typescript-eslint/explicit-function-return-type': 0,
|
||||
// 'react/prop-types': 0,
|
||||
// },
|
||||
// settings: {
|
||||
// react: {
|
||||
// version: 'detect',
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
|
79
package-lock.json
generated
@ -2012,71 +2012,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
|
||||
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
|
||||
},
|
||||
"@typescript-eslint/experimental-utils": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.1.tgz",
|
||||
"integrity": "sha512-lkiZ8iBBaYoyEKhCkkw4SAeatXyBq9Ece5bZXdLe1LWBUwTszGbmbiqmQbwWA8cSYDnjWXp9eDbXpf9Sn0hLAg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.3",
|
||||
"@typescript-eslint/types": "3.9.1",
|
||||
"@typescript-eslint/typescript-estree": "3.9.1",
|
||||
"eslint-scope": "^5.0.0",
|
||||
"eslint-utils": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.9.1.tgz",
|
||||
"integrity": "sha512-y5QvPFUn4Vl4qM40lI+pNWhTcOWtpZAJ8pOEQ21fTTW4xTJkRplMjMRje7LYTXqVKKX9GJhcyweMz2+W1J5bMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint-visitor-keys": "^1.0.0",
|
||||
"@typescript-eslint/experimental-utils": "3.9.1",
|
||||
"@typescript-eslint/types": "3.9.1",
|
||||
"@typescript-eslint/typescript-estree": "3.9.1",
|
||||
"eslint-visitor-keys": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.9.1.tgz",
|
||||
"integrity": "sha512-15JcTlNQE1BsYy5NBhctnEhEoctjXOjOK+Q+rk8ugC+WXU9rAcS2BYhoh6X4rOaXJEpIYDl+p7ix+A5U0BqPTw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.1.tgz",
|
||||
"integrity": "sha512-IqM0gfGxOmIKPhiHW/iyAEXwSVqMmR2wJ9uXHNdFpqVvPaQ3dWg302vW127sBpAiqM9SfHhyS40NKLsoMpN2KA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "3.9.1",
|
||||
"@typescript-eslint/visitor-keys": "3.9.1",
|
||||
"debug": "^4.1.1",
|
||||
"glob": "^7.1.6",
|
||||
"is-glob": "^4.0.1",
|
||||
"lodash": "^4.17.15",
|
||||
"semver": "^7.3.2",
|
||||
"tsutils": "^3.17.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.1.tgz",
|
||||
"integrity": "sha512-zxdtUjeoSh+prCpogswMwVUJfEFmCOjdzK9rpNjNBfm6EyPt99x3RrJoBOGZO23FCt0WPKUCOL5mb/9D5LjdwQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"eslint-visitor-keys": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
@ -8794,6 +8729,15 @@
|
||||
"sort-keys": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"notistack": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/notistack/-/notistack-1.0.1.tgz",
|
||||
"integrity": "sha512-2T1WkokzRCM8N9EdueaXja160IMFIMHVhRu0fGkDje7qCzwBHlTMZY2NULQzB2GFOO6iGVzl5GCX2XrJIzI8bw==",
|
||||
"requires": {
|
||||
"clsx": "^1.1.0",
|
||||
"hoist-non-react-statics": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
@ -10636,6 +10580,11 @@
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"react-click-away-listener": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/react-click-away-listener/-/react-click-away-listener-1.4.3.tgz",
|
||||
"integrity": "sha512-c7d6mfZuHu/rIdnEHnovX/QsScQXlqtdAynSnZUyyH+6kPOAyB40k2c5br56c/qp4KBkHD0JQV4C7rVuAmroMw=="
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz",
|
||||
|
@ -9,7 +9,9 @@
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"axios": "^0.19.2",
|
||||
"notistack": "^1.0.1",
|
||||
"react": "^16.13.1",
|
||||
"react-click-away-listener": "^1.4.3",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-scripts": "3.4.1",
|
||||
"styled-components": "^5.1.1"
|
||||
@ -21,7 +23,6 @@
|
||||
"@types/react": "^16.9.46",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@types/styled-components": "^5.1.2",
|
||||
"@typescript-eslint/parser": "^3.9.1",
|
||||
"prettier": "^2.0.5",
|
||||
"typescript": "^3.9.7"
|
||||
},
|
||||
|
@ -1,22 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/logo.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.svg" />
|
||||
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/logo.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Web site created using create-react-app" />
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.svg" />
|
||||
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@400;700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
|
||||
<title>PlanNaPlan</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>Potrzebujesz włączyć JavaScript, żeby otworzyć tę aplikację</br>You need to enable JavaScript to run this
|
||||
app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
|
||||
<title>PlanNaPlan</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>Potrzebujesz włączyć JavaScript, żeby otworzyć tę aplikację</br>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 11 KiB |
1
src/assets/account.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="512pt" viewBox="0 0 512 512.00019" width="512pt" xmlns="http://www.w3.org/2000/svg"><path d="m256 511.996094c-141.484375 0-256-114.65625-256-255.996094 0-141.488281 114.496094-256 256-256 141.488281 0 255.996094 114.496094 255.996094 256 0 141.476562-114.667969 255.996094-255.996094 255.996094zm0 0" fill="#66a9df"/><path d="m256 0v511.996094c141.328125 0 255.996094-114.519532 255.996094-255.996094 0-141.5-114.507813-256-255.996094-256zm0 0" fill="#4f84cf"/><path d="m256 316c-74.488281 0-145.511719 32.5625-197.417969 102.96875 103.363281 124.941406 294.6875 123.875 396.65625-2.230469-25.179687-25.046875-81.894531-100.738281-199.238281-100.738281zm0 0" fill="#d6f3fe"/><path d="m455.238281 416.738281c-48.140625 59.527344-120.371093 95.257813-199.238281 95.257813v-195.996094c117.347656 0 174.058594 75.699219 199.238281 100.738281zm0 0" fill="#bdecfc"/><path d="m256 271c-49.628906 0-90-40.375-90-90v-30c0-49.625 40.371094-90 90-90 49.625 0 90 40.375 90 90v30c0 49.625-40.375 90-90 90zm0 0" fill="#d6f3fe"/><path d="m256 61v210c49.628906 0 90-40.371094 90-90v-30c0-49.628906-40.371094-90-90-90zm0 0" fill="#bdecfc"/></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/bin.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="Capa_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m256 441.142c8.284 0 15-6.716 15-15v-201.409c0-8.284-6.716-15-15-15s-15 6.716-15 15v201.409c0 8.284 6.716 15 15 15z"/><path d="m173.412 427.552c.78 8.263 8.115 14.303 16.344 13.523 8.248-.779 14.302-8.096 13.523-16.344l-19.018-201.409c-.779-8.247-8.083-14.303-16.344-13.523-8.248.779-14.302 8.096-13.523 16.344z"/><path d="m322.244 441.076c8.238.779 15.564-5.269 16.344-13.523l19.018-201.409c.779-8.248-5.276-15.565-13.523-16.344-8.26-.784-15.565 5.276-16.344 13.523l-19.018 201.409c-.779 8.247 5.276 15.565 13.523 16.344z"/><path d="m57.646 168.875h8.967l43.448 330.083c.982 7.463 7.344 13.042 14.872 13.042h262.135c7.528 0 13.889-5.579 14.872-13.042l43.448-330.083h8.967c8.284 0 15-6.716 15-15v-65.629c0-8.284-6.716-15-15-15h-128.357v-5.911c0-37.128-30.207-67.335-67.335-67.335h-5.325c-37.128 0-67.335 30.207-67.335 67.335v5.911h-128.357c-8.284 0-15 6.716-15 15v65.629c0 8.284 6.715 15 15 15zm316.267 313.125h-235.826l-41.215-313.125h318.257zm-157.911-414.665c0-20.586 16.749-37.335 37.335-37.335h5.325c20.586 0 37.335 16.749 37.335 37.335v5.911h-79.995zm-143.356 35.911h366.709v35.629c-3.207 0-362.709 0-366.709 0z"/></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 535 B |
41
src/assets/expand.svg
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="306px" height="306px" viewBox="0 0 306 306" style="enable-background:new 0 0 306 306;" xml:space="preserve">
|
||||
<g>
|
||||
<g id="expand-more">
|
||||
<polygon points="270.3,58.65 153,175.95 35.7,58.65 0,94.35 153,247.35 306,94.35 "/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 748 B |
42
src/assets/poland.svg
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 473.677 473.677" style="enable-background:new 0 0 473.677 473.677;" xml:space="preserve">
|
||||
<path style="fill:#E4E4E4;" d="M324.752,236.842h148.925C473.677,106.032,367.641,0,236.835,0
|
||||
C302.232,0,324.76,118.425,324.752,236.842z"/>
|
||||
<path style="fill:#F3F4F5;" d="M0,236.842h334.931C334.939,118.425,302.232,0,236.835,0C106.036,0,0,106.032,0,236.842z"/>
|
||||
<path style="fill:#D84141;" d="M319.771,236.842c0,118.417-17.535,236.835-82.936,236.835
|
||||
c130.807,0,236.842-106.036,236.842-236.835H319.771z"/>
|
||||
<path style="fill:#DC4D4E;" d="M334.931,236.842H0c0,130.799,106.036,236.835,236.835,236.835
|
||||
C302.232,473.677,334.931,355.26,334.931,236.842z"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
115
src/assets/united-kingdom.svg
Normal file
@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 473.68 473.68" style="enable-background:new 0 0 473.68 473.68;" xml:space="preserve">
|
||||
<g>
|
||||
<path style="fill:#29337A;" d="M41.712,102.641c-15.273,22.168-26.88,47.059-33.918,73.812h107.734L41.712,102.641z"/>
|
||||
<path style="fill:#29337A;" d="M170.511,9.48c-27.288,7.947-52.56,20.628-74.814,37.168l74.814,74.814V9.48z"/>
|
||||
<path style="fill:#29337A;" d="M101.261,430.982c20.874,14.607,44.195,25.915,69.25,33.211v-102.45L101.261,430.982z"/>
|
||||
<path style="fill:#29337A;" d="M10.512,306.771c7.831,25.366,19.831,48.899,35.167,69.833l69.833-69.833H10.512z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M45.619,97.144c-1.324,1.81-2.629,3.646-3.908,5.501l73.816,73.812H7.793
|
||||
c-1.746,6.645-3.171,13.418-4.345,20.284h141.776L45.619,97.144z"/>
|
||||
<path style="fill:#FFFFFF;" d="M95.767,427.074c1.802,1.343,3.654,2.621,5.493,3.908l69.25-69.242v102.45
|
||||
c6.653,1.945,13.41,3.624,20.284,4.974V332.05L95.767,427.074z"/>
|
||||
<path style="fill:#FFFFFF;" d="M5.25,286.487c1.47,6.873,3.205,13.642,5.258,20.284h105.001l-69.833,69.833
|
||||
c7.595,10.377,16.017,20.115,25.168,29.12L190.08,286.487H5.25L5.25,286.487z"/>
|
||||
<path style="fill:#FFFFFF;" d="M170.511,9.48v111.982l-74.815-74.81c-10.314,7.67-19.955,16.185-28.888,25.403l123.983,123.983
|
||||
V4.506C183.921,5.864,177.164,7.547,170.511,9.48z"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon style="fill:#D32030;" points="170.511,306.056 169.8,306.771 170.511,306.771 "/>
|
||||
<polygon style="fill:#D32030;" points="190.084,286.487 190.794,286.487 190.794,285.773 "/>
|
||||
<polygon style="fill:#D32030;" points="281.229,196.737 280.545,196.737 280.545,197.425 "/>
|
||||
<polygon style="fill:#D32030;" points="171.21,176.457 170.511,175.754 170.511,176.457 "/>
|
||||
<polygon style="fill:#D32030;" points="190.794,196.037 190.794,196.737 191.494,196.737 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#252F6C;" d="M300.825,411.764v53.091c25.381-7.105,49.045-18.305,70.211-32.897l-57.526-57.526
|
||||
C308.913,390.583,307.231,398.933,300.825,411.764z"/>
|
||||
<path style="fill:#252F6C;" d="M313.812,108.471l62.799-62.799C354.05,29.15,328.456,16.559,300.824,8.818v54.538
|
||||
C308.21,78.146,308.831,89.384,313.812,108.471z"/>
|
||||
<path style="fill:#252F6C;" d="M427.029,377.984c15.815-21.275,28.141-45.29,36.147-71.213h-107.36L427.029,377.984z"/>
|
||||
<path style="fill:#252F6C;" d="M465.887,176.457c-7.188-27.318-19.143-52.676-34.898-75.192l-75.2,75.192H465.887z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#E7E7E7;" d="M327.638,290.5l16.275,16.275l77.903,77.903c1.769-2.214,3.526-4.42,5.217-6.69l-71.213-71.213
|
||||
h107.36c2.046-6.638,3.784-13.41,5.25-20.284H329.16C328.932,289.367,327.911,287.643,327.638,290.5z"/>
|
||||
<path style="fill:#E7E7E7;" d="M311.352,120.348l70.607-70.615c-1.769-1.372-3.541-2.737-5.348-4.061l-62.799,62.799
|
||||
C314.463,110.954,310.746,117.805,311.352,120.348z"/>
|
||||
<path style="fill:#E7E7E7;" d="M300.825,58.992V8.814c-6.645-1.862-13.41-3.44-20.284-4.727v24.476
|
||||
C288.088,36.745,294.853,47.022,300.825,58.992z"/>
|
||||
<path style="fill:#E7E7E7;" d="M326.041,196.737h144.195c-1.171-6.866-2.599-13.635-4.345-20.284H355.793l75.2-75.192
|
||||
C423.6,90.7,415.384,80.768,406.409,71.565l-84.702,84.694C323.988,171.622,325.009,180.544,326.041,196.737z"/>
|
||||
<path style="fill:#E7E7E7;" d="M310.088,371.002l60.952,60.959c10.138-6.982,19.685-14.753,28.593-23.189l-80.173-80.177
|
||||
C316.901,343.423,313.865,357.745,310.088,371.002z"/>
|
||||
<path style="fill:#E7E7E7;" d="M280.545,442.301v27.28c6.873-1.279,13.635-2.865,20.284-4.727v-53.091
|
||||
C294.853,423.738,288.088,434.13,280.545,442.301z"/>
|
||||
</g>
|
||||
<path style="fill:#D71F28;" d="M321.707,156.259l84.694-84.694c-7.625-7.831-15.8-15.119-24.446-21.832l-66.55,66.561
|
||||
C318.363,128.657,319.706,142.808,321.707,156.259z"/>
|
||||
<g>
|
||||
<path style="fill:#D32030;" d="M225.019,0.292C228.965,0.101,232.899,0,236.836,0C232.876,0,228.935,0.101,225.019,0.292z"/>
|
||||
<path style="fill:#D32030;" d="M236.836,473.68c-3.938,0-7.872-0.108-11.81-0.299C228.942,473.579,232.876,473.68,236.836,473.68z"
|
||||
/>
|
||||
<path style="fill:#D32030;" d="M236.836,473.68c14.943,0,29.535-1.447,43.708-4.099v-27.28
|
||||
C268.103,455.786,253.549,473.68,236.836,473.68z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#D71F28;" d="M470.232,196.737H327.911c1.885,29.704,1.657,60.249-0.681,89.75h141.2
|
||||
c3.418-16.017,5.25-32.613,5.25-49.643C473.68,223.164,472.461,209.784,470.232,196.737z"/>
|
||||
<path style="fill:#D71F28;" d="M327.638,290.5c-1.316,13.994-5.901,24.898-8.182,38.099l80.173,80.173
|
||||
c7.932-7.517,15.347-15.557,22.183-24.094l-77.9-77.907L327.638,290.5z"/>
|
||||
</g>
|
||||
<path style="fill:#D32030;" d="M280.545,30.324V4.091C266.376,1.447,251.784,0,236.836,0C253.549,0,268.103,16.843,280.545,30.324z"
|
||||
/>
|
||||
<g>
|
||||
<path style="fill:#29337A;" d="M300.825,422.007c6.406-12.834,11.899-27.609,16.499-43.757l-16.499-16.499V422.007z"/>
|
||||
<path style="fill:#29337A;" d="M319.377,102.906c-4.989-19.087-11.166-36.439-18.552-51.229v69.773L319.377,102.906z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M332.234,295.092c0.269-2.857,0.512-5.725,0.744-8.605h-9.349L332.234,295.092z"/>
|
||||
<path style="fill:#FFFFFF;" d="M300.825,121.451V51.674c-5.976-11.97-12.737-22.254-20.284-30.429v129.906l40.735-40.735
|
||||
c-0.613-2.543-1.257-5.034-1.9-7.517L300.825,121.451z"/>
|
||||
<path style="fill:#FFFFFF;" d="M281.229,196.737h52.429c-1.028-16.192-2.666-32.123-4.944-47.482L281.229,196.737z"/>
|
||||
<path style="fill:#FFFFFF;" d="M280.545,452.432c7.547-8.182,14.308-18.459,20.284-30.429v-60.256l16.499,16.499
|
||||
c3.784-13.264,6.959-27.434,9.525-42.261l-46.307-46.304L280.545,452.432L280.545,452.432z"/>
|
||||
</g>
|
||||
<path style="fill:#E51D35;" d="M280.545,452.432V289.681l46.304,46.307c2.277-13.205,4.069-26.899,5.381-40.896l-8.605-8.605h9.349
|
||||
c2.337-29.502,2.565-60.047,0.681-89.75h-52.429l47.482-47.482c-2.001-13.455-4.476-26.469-7.434-38.836l-40.728,40.735V21.248
|
||||
C268.103,7.763,253.549,0,236.836,0c-3.938,0-7.872,0.101-11.817,0.292c-11.649,0.583-23.073,2.016-34.225,4.215v191.531
|
||||
L66.808,72.055c-7.618,7.861-14.704,16.237-21.189,25.089l79.313,79.313l20.291,20.284H3.448C1.227,209.784,0,223.164,0,236.844
|
||||
c0,17.034,1.84,33.626,5.25,49.643h184.834L70.847,405.724c7.808,7.67,16.121,14.813,24.921,21.349l95.023-95.023v137.116
|
||||
c11.151,2.199,22.583,3.631,34.232,4.215c3.938,0.191,7.872,0.299,11.81,0.299C253.549,473.68,268.103,465.917,280.545,452.432z"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 18 KiB |
@ -8,6 +8,8 @@ import styled from 'styled-components';
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
height: calc(100vh - 80px);
|
||||
background-color: #ECEEF4;
|
||||
padding: 20px;
|
||||
`;
|
||||
|
||||
export const App = () => {
|
||||
|
@ -1,72 +1,87 @@
|
||||
import React, { useState, useContext, MouseEvent } from 'react';
|
||||
import Collapse from '@material-ui/core/Collapse';
|
||||
import ExpandIcon from '../assets/expand.png';
|
||||
import { Course, Group, GroupType } from '../types/index';
|
||||
import { ReactComponent as Expand } from '../assets/expand.svg';
|
||||
import { Course, Group } from '../types/index';
|
||||
import { coursesContext } from '../contexts/CoursesProvider';
|
||||
import styled from 'styled-components';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { ReactComponent as CloseIcon } from '../assets/close.svg';
|
||||
import { ReactComponent as Bin } from '../assets/bin.svg';
|
||||
|
||||
interface ClassExandIconProps {
|
||||
isSelected: boolean;
|
||||
}
|
||||
|
||||
const CourseStyled = styled.div`
|
||||
const CourseCardWrapper = styled.div`
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
background-color: rgb(100, 181, 246) !important;
|
||||
background-color: rgb(100, 181, 246);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
box-shadow: 9px 9px 8px -2px rgba(0,0,0,0.59);
|
||||
box-shadow: 9px 9px 8px -2px rgba(0, 0, 0, 0.59);
|
||||
`;
|
||||
|
||||
const CourseNameStyled = styled.div`
|
||||
padding-top:20px;
|
||||
padding-bottom:10px;
|
||||
padding-left:35px;
|
||||
padding-right:35px;
|
||||
|
||||
const TitleWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
`
|
||||
|
||||
const BinIcon = styled(Bin)`
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
max-width: 20px;
|
||||
min-width: 20px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
fill: white;
|
||||
}
|
||||
`;
|
||||
|
||||
interface ClassGroupProps {
|
||||
groupType: GroupType;
|
||||
}
|
||||
const CourseName = styled.div`
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
font-size: 16px;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const ClassGroupStyled = styled.div`
|
||||
position:relative;
|
||||
position: relative;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
:hover {
|
||||
cursor: pointer;
|
||||
background-color:#9ED3FF;
|
||||
background-color: #9ed3ff;
|
||||
}
|
||||
`;
|
||||
|
||||
const ClassExandIconStyled = styled.img<ClassExandIconProps>`
|
||||
margin-top: 5px;
|
||||
interface ExpandIconProps {
|
||||
isSelected: boolean;
|
||||
}
|
||||
|
||||
const ExpandIcon = styled(Expand) <ExpandIconProps>`
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
max-width: 20px;
|
||||
min-width: 20px;
|
||||
transition: 0.2s;
|
||||
transform: ${(props) => (props.isSelected ? 'scaleY(-1);' : 'scaleY(1);')};
|
||||
transform: ${({ isSelected }) => (isSelected ? 'scaleY(-1);' : 'scaleY(1);')};
|
||||
`;
|
||||
|
||||
const TypeClass = styled.div`
|
||||
font-size:12px;
|
||||
position:absolute;
|
||||
border-radius:15px;
|
||||
background-color:#00506B;
|
||||
border:2px solid;
|
||||
min-width:45px;
|
||||
top:5px;
|
||||
left:5px;
|
||||
color:white;
|
||||
font-weight:bold;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
border-radius: 15px;
|
||||
background-color: #00506b;
|
||||
border: 2px solid;
|
||||
min-width: 45px;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
`;
|
||||
|
||||
const useStyles = makeStyles({
|
||||
@ -87,16 +102,7 @@ const useStyles = makeStyles({
|
||||
},
|
||||
});
|
||||
|
||||
const DeleteFromBasketIcon = styled(CloseIcon)`
|
||||
width: 20px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
left: 230px;
|
||||
top: -5px;
|
||||
&:hover {
|
||||
fill: white;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
interface CourseCardProps {
|
||||
course: Course;
|
||||
@ -111,24 +117,24 @@ export const CourseCard = ({ course }: CourseCardProps) => {
|
||||
const onGroupClick = (group: Group, id: number) => addGroup(group, id);
|
||||
|
||||
return (
|
||||
<CourseStyled>
|
||||
<DeleteFromBasketIcon onClick={() => deleteFromBasket(course.id)}></DeleteFromBasketIcon>
|
||||
<CourseNameStyled onClick={() => setSelected(!isSelected)}>{course.name}</CourseNameStyled>
|
||||
<CourseCardWrapper>
|
||||
<TitleWrapper>
|
||||
<BinIcon onClick={() => deleteFromBasket(course.id)}></BinIcon>
|
||||
<CourseName onClick={() => setSelected(!isSelected)}>{course.name}</CourseName>
|
||||
<ExpandIcon onClick={() => setSelected(!isSelected)} isSelected={isSelected} />
|
||||
</TitleWrapper>
|
||||
<Collapse className={classes.expanded} in={isSelected} timeout="auto" unmountOnExit>
|
||||
{groups
|
||||
.sort((a, b) => b.type.localeCompare(a.type))
|
||||
.map((group, index) => (
|
||||
<ClassGroupStyled key={index} onClick={() => onGroupClick(group, course.id)}>
|
||||
<TypeClass>{group.type==="CLASS"? "Ćw." : "Wyk."}</TypeClass>
|
||||
<TypeClass>{group.type === 'CLASS' ? 'Ćw.' : 'Wyk.'}</TypeClass>
|
||||
<p>
|
||||
{group.time} {group.room} <br></br> {group.lecturer}
|
||||
</p>
|
||||
</ClassGroupStyled>
|
||||
))}
|
||||
</Collapse>
|
||||
<div onClick={() => setSelected(!isSelected)}>
|
||||
<ClassExandIconStyled isSelected={isSelected} alt="expand" src={ExpandIcon} />
|
||||
</div>
|
||||
</CourseStyled>
|
||||
</CourseCardWrapper>
|
||||
);
|
||||
};
|
||||
|
@ -1,20 +1,19 @@
|
||||
import React, { useState, useContext, useEffect, MouseEvent, ChangeEvent } from 'react';
|
||||
import axios from 'axios';
|
||||
import { Input } from '@material-ui/core';
|
||||
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
|
||||
import React, { useState, useContext, useEffect, MouseEvent, forwardRef } from 'react';
|
||||
import { coursesContext } from '../contexts/CoursesProvider';
|
||||
import { Course, Basket } from '../types';
|
||||
import { Course } from '../types';
|
||||
import styled from 'styled-components';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
const DropdownStyled = styled.div`
|
||||
|
||||
|
||||
const DropdownContainer = styled.div`
|
||||
position: relative;
|
||||
z-index: 99999999;
|
||||
max-height: 420px;
|
||||
border-radius: 3px;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0.05em 0.2em 0.6em rgba(0, 0, 0, 0.2);
|
||||
scroll-snap-type: y mandatory;
|
||||
scroll-behavior: smooth;
|
||||
z-index: 100;
|
||||
position: relative;
|
||||
border-radius:0px 0px 0px 15px;
|
||||
::-webkit-scrollbar-track {
|
||||
border-radius: 10px;
|
||||
background-color: #f5f5f5;
|
||||
@ -25,70 +24,69 @@ const DropdownStyled = styled.div`
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background-color: #d4b851;
|
||||
background-color: black;
|
||||
border: 1px solid;
|
||||
}
|
||||
`;
|
||||
|
||||
const CourseStyled = styled.div`
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
const CourseContainer = styled.div`
|
||||
padding: 5px;
|
||||
padding-left: 20px;
|
||||
background-color: #e6c759;
|
||||
background-color: #f2f4f7;
|
||||
font-size: 18px;
|
||||
font-family: Lato;
|
||||
font-weight: 500;
|
||||
scroll-snap-align: end;
|
||||
border-bottom:1px solid;
|
||||
:hover {
|
||||
background-color: #d4b851;
|
||||
background-color: #eceef4;
|
||||
cursor: pointer;
|
||||
}
|
||||
`;
|
||||
|
||||
const useStyles = makeStyles({
|
||||
topbarInput: {
|
||||
marginTop: '8px',
|
||||
width: '100%',
|
||||
},
|
||||
});
|
||||
|
||||
interface DropdownProps {
|
||||
clearInput: boolean;
|
||||
handleClearInput: () => void;
|
||||
open: boolean;
|
||||
input: string;
|
||||
handleCloseDropdown: () => void;
|
||||
}
|
||||
|
||||
export const Dropdown = ({ clearInput, handleClearInput }: DropdownProps) => {
|
||||
const classes = useStyles();
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [input, setInput] = useState<string>('');
|
||||
|
||||
export const Dropdown = forwardRef(({ open, input, handleCloseDropdown }: DropdownProps, ref: any) => {
|
||||
//courses - choosenCourses
|
||||
const [filteredCourses, setFilteredCourses] = useState<Array<Course>>([]);
|
||||
|
||||
const { courses, basket, addToBasket } = useContext(coursesContext)!;
|
||||
|
||||
useEffect(() => {
|
||||
console.log('wut');
|
||||
}, [open, input, handleCloseDropdown]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('input is: ', input);
|
||||
}, [input]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('is open: ', open);
|
||||
}, [open]);
|
||||
|
||||
useEffect(() => {
|
||||
const filterCourses = (input: string) => {
|
||||
const choosenCoursesNames = basket.map(({ name }) => name.trim());
|
||||
const filteredCourses = courses.filter(
|
||||
({ name }) => name.toLowerCase().includes(input.toLowerCase()) && !choosenCoursesNames.includes(name),
|
||||
({ name }) =>
|
||||
name
|
||||
.toLowerCase()
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.includes(
|
||||
input
|
||||
.toLowerCase()
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, ''),
|
||||
) && !choosenCoursesNames.includes(name),
|
||||
);
|
||||
setFilteredCourses(filteredCourses);
|
||||
};
|
||||
console.log("filtering courses");
|
||||
filterCourses(input);
|
||||
}, [input, open, basket]);
|
||||
|
||||
useEffect(() => {
|
||||
clearInput && (setInput(''), handleClearInput());
|
||||
}, [clearInput]);
|
||||
|
||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => setInput(event.target.value);
|
||||
|
||||
const handleClick = () => setOpen(true);
|
||||
|
||||
const handleClickAway = () => setOpen(false);
|
||||
}, [open, input, basket]);
|
||||
|
||||
const onCourseClick = async (event: MouseEvent) => {
|
||||
const target = event.currentTarget;
|
||||
@ -97,31 +95,21 @@ export const Dropdown = ({ clearInput, handleClearInput }: DropdownProps) => {
|
||||
console.log('added course is');
|
||||
console.log(course);
|
||||
addToBasket(course);
|
||||
setOpen(false);
|
||||
handleCloseDropdown();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ClickAwayListener onClickAway={handleClickAway}>
|
||||
<div>
|
||||
<Input
|
||||
placeholder="Wyszukaj..."
|
||||
inputProps={{ 'aria-label': 'description' }}
|
||||
className={classes.topbarInput}
|
||||
onChange={handleChange}
|
||||
onClick={handleClick}
|
||||
value={input}
|
||||
/>
|
||||
{open && (
|
||||
<DropdownStyled>
|
||||
{filteredCourses.map(({ name, id }, index) => (
|
||||
<CourseStyled key={index} id={id.toString()} onClick={onCourseClick}>
|
||||
<p>{name} </p>
|
||||
</CourseStyled>
|
||||
))}
|
||||
</DropdownStyled>
|
||||
)}
|
||||
</div>
|
||||
</ClickAwayListener>
|
||||
<DropdownContainer>
|
||||
{open && (
|
||||
<>
|
||||
{filteredCourses.map(({ name, id }, index) => (
|
||||
<CourseContainer key={index} id={id.toString()} onClick={onCourseClick}>
|
||||
<p>{name} </p>
|
||||
</CourseContainer>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</DropdownContainer>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -12,9 +12,8 @@ export const Profile = ({ anchorEl, handleClose }: ProfileProps) => {
|
||||
|
||||
return (
|
||||
<Menu anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
|
||||
<MenuItem>Profile</MenuItem>
|
||||
<MenuItem>My account</MenuItem>
|
||||
<MenuItem onClick={logout}>Logout</MenuItem>
|
||||
<MenuItem>Profil</MenuItem>
|
||||
<MenuItem onClick={logout}>Wyloguj</MenuItem>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,14 @@
|
||||
import React, { useContext } from 'react';
|
||||
import Snackbar from '@material-ui/core/Snackbar';
|
||||
import { CourseCard } from './CourseCard';
|
||||
import { coursesContext } from '../contexts/CoursesProvider';
|
||||
import MuiAlert, { AlertProps } from '@material-ui/lab/Alert';
|
||||
import styled from 'styled-components';
|
||||
import { debounce } from "lodash";
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
const RightbarStyled = styled.div`
|
||||
padding-top: 10px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
text-align: center;
|
||||
font-family: Lato;
|
||||
height: 100%;
|
||||
width: 300px;
|
||||
overflow-y: scroll;
|
||||
@ -25,40 +22,32 @@ const RightbarStyled = styled.div`
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background-color: #d4b851;
|
||||
background-color: black;
|
||||
border: 1px solid;
|
||||
}
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
box-shadow: 3px 3px 3px -2px rgba(0, 0, 0, 0.59);
|
||||
`;
|
||||
const RightbarTextStyled = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const SaveButton = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #417cab !important;
|
||||
user-select: none;
|
||||
background-color: #417cab;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
background-color: red;
|
||||
margin-bottom: 10px;
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
box-shadow: 6px 6px 6px -2px rgba(0,0,0,0.59);
|
||||
box-shadow: 6px 6px 6px -2px rgba(0, 0, 0, 0.59);
|
||||
`;
|
||||
|
||||
function Alert(props: AlertProps) {
|
||||
return <MuiAlert elevation={6} variant="filled" {...props} />;
|
||||
}
|
||||
|
||||
export const Rightbar = () => {
|
||||
const { courses, basket, saveBasket } = useContext(coursesContext)!;
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const getBasketGroups = () => {
|
||||
const names = basket.map(({ name }) => name);
|
||||
return courses.filter(({ name }) => names.includes(name));
|
||||
@ -66,38 +55,15 @@ export const Rightbar = () => {
|
||||
|
||||
const filteredCourses = getBasketGroups();
|
||||
|
||||
const save = debounce(() => {
|
||||
saveBasket();
|
||||
setOpen(true);
|
||||
console.log("zmiana")
|
||||
},500);
|
||||
|
||||
const handleClose = (event?: React.SyntheticEvent, reason?: string) => {
|
||||
if (reason === 'clickaway') {
|
||||
return;
|
||||
}
|
||||
|
||||
setOpen(false);
|
||||
};
|
||||
const handleSave = debounce(() => saveBasket(), 500);
|
||||
|
||||
//need to insert student name from db and course maybe based on current time or from db too
|
||||
return (
|
||||
<RightbarStyled>
|
||||
<RightbarTextStyled>
|
||||
<p>
|
||||
Hubert Wrzesiński<br></br>
|
||||
Semestr zimowy 2020/2021
|
||||
</p>
|
||||
<SaveButton onClick={save}>ZAPISZ</SaveButton>
|
||||
</RightbarTextStyled>
|
||||
<SaveButton onClick={handleSave}>ZAPISZ</SaveButton>
|
||||
{filteredCourses.map((course, index) => (
|
||||
<CourseCard course={course} key={index} />
|
||||
))}
|
||||
<Snackbar open={open} autoHideDuration={5000} onClose={handleClose}>
|
||||
<Alert onClose={handleClose} severity="success">
|
||||
Zapisano plan!
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
</RightbarStyled>
|
||||
);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, MouseEvent, useRef } from 'react';
|
||||
import React, { useEffect, MouseEvent, useRef, useCallback, useLayoutEffect } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { SchedulerEvents } from './SchedulerEvents';
|
||||
import { days, hours } from '../constants/index';
|
||||
@ -6,74 +6,93 @@ import styled from 'styled-components/macro';
|
||||
|
||||
const SchedulerWrapper = styled.div`
|
||||
border-collapse: collapse;
|
||||
flex-grow: 1;
|
||||
flex: 1;
|
||||
background-color: white;
|
||||
padding: 10px 40px 25px 10px;
|
||||
border-radius: 5px;
|
||||
margin-right: 20px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 3px 3px 3px -2px rgba(0, 0, 0, 0.59);
|
||||
`;
|
||||
|
||||
const TableBody = styled.div`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% * 25 / 26);
|
||||
`;
|
||||
|
||||
const TableRow = styled.div`
|
||||
display: flex;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const TableHead = styled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: calc(100% / 26);
|
||||
`;
|
||||
|
||||
interface TableCellProps {
|
||||
height: number;
|
||||
cellHeight?: number;
|
||||
isHourColumn?: boolean;
|
||||
}
|
||||
|
||||
const TableCell = styled.div<TableCellProps>`
|
||||
height: ${({ height }) => height}px;
|
||||
border: 1px solid #ddd;
|
||||
border-width: ${({ isHourColumn }) => !isHourColumn && '2px'};
|
||||
border-style: ${({ isHourColumn }) => !isHourColumn && 'none solid dotted none'};
|
||||
border-color: rgb(242, 243, 245);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
font-size: 1.25vw;
|
||||
`;
|
||||
|
||||
const T = styled.table`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: ${({ isHourColumn }) => (isHourColumn ? 'flex-end' : 'center')};
|
||||
flex: ${({ isHourColumn }) => (isHourColumn ? '1' : '5')};
|
||||
margin-right: ${({ isHourColumn }) => (isHourColumn ? '10px' : '0px')};
|
||||
margin-top: ${({ isHourColumn, cellHeight }) => (isHourColumn ? `-${cellHeight}px` : '0px')};
|
||||
font-size: 0.75vw;
|
||||
user-select: none;
|
||||
border-collapse: collapse;
|
||||
:nth-child(2) {
|
||||
border-left: 2px solid rgb(242, 243, 245);
|
||||
}
|
||||
font-weight: bold;
|
||||
`;
|
||||
|
||||
export const Scheduler = () => {
|
||||
const cellRef = useRef<HTMLDivElement>(null);
|
||||
const [cellWidth, setCellWidth] = useState(0);
|
||||
const [cellTop, setCellTop] = useState(0);
|
||||
const [cellHeight, setCellHeight] = useState(0);
|
||||
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const [wrapperHeight, setWrapperHeight] = useState(0);
|
||||
console.log('cell height: ', cellHeight);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
if (cellRef.current && wrapperRef.current) {
|
||||
if (cellRef.current) {
|
||||
setCellWidth(cellRef.current.getBoundingClientRect().width);
|
||||
setCellTop(cellRef.current.getBoundingClientRect().top);
|
||||
setWrapperHeight(wrapperRef.current.getBoundingClientRect().height);
|
||||
setCellHeight(cellRef.current.getBoundingClientRect().height);
|
||||
cellRef.current.style.backgroundColor = 'blue';
|
||||
}
|
||||
};
|
||||
handleResize();
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SchedulerWrapper ref={wrapperRef}>
|
||||
<SchedulerWrapper>
|
||||
<TableHead>
|
||||
{days.map((day, indexCell) =>
|
||||
indexCell === 0 ? (
|
||||
<TableCell /* style={{ flexGrow: 1 }} */ height={wrapperHeight / 13} key={indexCell} ref={cellRef}>
|
||||
<TableCell isHourColumn={true} key={indexCell}>
|
||||
{day}
|
||||
</TableCell>
|
||||
) : (
|
||||
<TableCell /* style={{ flexGrow: 3 }} */ height={wrapperHeight / 13} key={indexCell} ref={cellRef}>
|
||||
<TableCell style={{ borderStyle: 'none none solid none' }} key={indexCell}>
|
||||
{day}
|
||||
</TableCell>
|
||||
),
|
||||
@ -84,19 +103,31 @@ export const Scheduler = () => {
|
||||
<TableRow key={indexRow}>
|
||||
{[hour, '', '', '', '', ''].map((value, indexCell) =>
|
||||
indexCell === 0 ? (
|
||||
<TableCell /* style={{ flexGrow: 1 }} */ height={wrapperHeight / 13} key={`${indexRow}${indexCell}`}>
|
||||
<TableCell isHourColumn={true} cellHeight={cellHeight} key={`${indexRow}${indexCell}`}>
|
||||
{value}
|
||||
</TableCell>
|
||||
) : indexRow === 0 && indexCell === 1 ? (
|
||||
<TableCell ref={cellRef} key={`${indexRow}${indexCell}`}>
|
||||
{value}
|
||||
</TableCell>
|
||||
) : indexRow === 23 ? (
|
||||
<TableCell style={{ borderBottom: '2px solid rgb(242, 243, 245)' }} key={`${indexRow}${indexCell}`}>
|
||||
{value}
|
||||
</TableCell>
|
||||
) : indexCell === 5 ? (
|
||||
<TableCell key={`${indexRow}${indexCell}`}>{value}</TableCell>
|
||||
) : indexRow % 2 !== 0 ? (
|
||||
<TableCell style={{ borderBottom: '2px solid rgb(242, 243, 245)' }} key={`${indexRow}${indexCell}`}>
|
||||
{value}
|
||||
</TableCell>
|
||||
) : (
|
||||
<TableCell /* style={{ flexGrow: 3 }} */ height={wrapperHeight / 13} key={`${indexRow}${indexCell}`}>
|
||||
{value}
|
||||
</TableCell>
|
||||
<TableCell key={`${indexRow}${indexCell}`}>{value}</TableCell>
|
||||
),
|
||||
)}
|
||||
</TableRow>
|
||||
))}
|
||||
<SchedulerEvents cellTop={cellTop} cellWidth={cellWidth} cellHeight={cellHeight} />
|
||||
</TableBody>
|
||||
<SchedulerEvents cellTop={cellTop} cellWidth={cellWidth} cellHeight={wrapperHeight / 13} />
|
||||
</SchedulerWrapper>
|
||||
</>
|
||||
);
|
||||
|
@ -11,13 +11,10 @@ interface SchedulerEventsProps {
|
||||
|
||||
export const SchedulerEvents = ({ cellTop, cellWidth, cellHeight }: SchedulerEventsProps) => {
|
||||
const { basket } = useContext(coursesContext)!;
|
||||
|
||||
console.log(`values: cellTop: ${cellTop}, cellWidth: ${cellWidth}, cellHeight: ${cellHeight}`);
|
||||
const [choosenGroupsMappedToEvents, setChoosenGroupsMappedToEvents] = useState<any>([]);
|
||||
|
||||
interface GroupTimeToEventRowMapping {
|
||||
[time: string]: number;
|
||||
}
|
||||
const groupTimeToEventRowMapping: GroupTimeToEventRowMapping = {
|
||||
const groupTimeToEventRowMapping: { [time: string]: number } = {
|
||||
'8.15': 0,
|
||||
'10.00': 1,
|
||||
'11.45': 2,
|
||||
@ -33,7 +30,7 @@ export const SchedulerEvents = ({ cellTop, cellWidth, cellHeight }: SchedulerEve
|
||||
const merged = [...classes, ...lectures];
|
||||
|
||||
//deleted if statement, maybe it is needed
|
||||
const groupsMapped = merged.map(({ id, day, lecturer, room, time, name,type }) => ({
|
||||
const groupsMapped = merged.map(({ id, day, lecturer, room, time, name, type }) => ({
|
||||
id,
|
||||
day,
|
||||
lecturer,
|
||||
@ -56,17 +53,17 @@ export const SchedulerEvents = ({ cellTop, cellWidth, cellHeight }: SchedulerEve
|
||||
indexRow={index}
|
||||
cellTop={
|
||||
index === 0
|
||||
? cellTop + (cellHeight + cellHeight * 2 * index + cellHeight / 4)
|
||||
? cellHeight / 2
|
||||
: index === 1
|
||||
? cellTop + (cellHeight + cellHeight * 2 * index)
|
||||
? cellHeight * 4
|
||||
: index === 2
|
||||
? cellTop + (cellHeight + cellHeight * 2 * index - cellHeight / 4)
|
||||
? cellHeight * 7.5
|
||||
: index === 3
|
||||
? cellTop + (cellHeight + cellHeight * 2 * index - cellHeight / 4)
|
||||
? cellHeight * 11.5
|
||||
: index === 4
|
||||
? cellTop + (cellHeight + cellHeight * 2 * index - cellHeight / 2)
|
||||
? cellHeight * 15
|
||||
: index === 5
|
||||
? cellTop + (cellHeight + cellHeight * 2 * index - (cellHeight * 3) / 4)
|
||||
? cellHeight * 18.5
|
||||
: 0
|
||||
}
|
||||
cellWidth={cellWidth}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { MouseEvent, useEffect, useState } from 'react';
|
||||
import React, { MouseEvent, useState } from 'react';
|
||||
import { Group, GroupType } from '../types';
|
||||
import styled from 'styled-components/macro';
|
||||
import Popover from '@material-ui/core/Popover';
|
||||
@ -18,44 +18,41 @@ const useStyles = makeStyles((theme: Theme) =>
|
||||
}),
|
||||
);
|
||||
|
||||
interface SchedulerEventProps {
|
||||
interface ClassesWrapperProps {
|
||||
eventIndex: number;
|
||||
cellTop: number;
|
||||
cellWidth: number;
|
||||
cellHeight: number;
|
||||
}
|
||||
|
||||
const SchedulerEvent = styled.div<SchedulerEventProps>`
|
||||
const ClassesWrapper = styled.div<ClassesWrapperProps>`
|
||||
position: absolute;
|
||||
display: flex;
|
||||
top: ${({ cellTop }) => cellTop}px;
|
||||
left: ${({ cellWidth, eventIndex }) => cellWidth + 5 + cellWidth * eventIndex}px;
|
||||
width: ${({ cellWidth }) => (cellWidth * 2.5) / 3}px;
|
||||
height: ${({ cellHeight }) => (cellHeight * 2 * 3) / 4}px;
|
||||
left: ${({ cellWidth, eventIndex }) => (cellWidth * 1) / 5 + 15 + cellWidth * eventIndex}px;
|
||||
width: ${({ cellWidth }) => cellWidth - 10}px;
|
||||
height: ${({ cellHeight }) => cellHeight * 3}px;
|
||||
z-index: 2;
|
||||
padding-left: 10px;
|
||||
`;
|
||||
|
||||
interface ClassesProps{
|
||||
cellWidth: number;
|
||||
interface ClassesProps {
|
||||
cellHeight: number;
|
||||
groupType: GroupType;
|
||||
}
|
||||
|
||||
const Classes = styled.div<ClassesProps>`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
border-radius: 10px;
|
||||
|
||||
font-size:0.90vw;
|
||||
/* background-color: rgb(100, 181, 246); */
|
||||
width: ${({ cellWidth }) => (cellWidth * 2.5) / 3}px;
|
||||
height: ${({ cellHeight }) => (cellHeight * 2 * 3) / 4}px;
|
||||
height: ${({ cellHeight }) => cellHeight * 3}px;
|
||||
margin-right: 5px;
|
||||
text-align: center;
|
||||
background-color:${({groupType})=>groupType === "CLASS" ? "#FFDC61" : "#A68820"};
|
||||
box-shadow: 9px 9px 8px -2px rgba(0,0,0,0.59);
|
||||
text-align: left;
|
||||
background-color: ${({ groupType }) => (groupType === 'CLASS' ? '#FFDC61' : '#9ed3ff')};
|
||||
box-shadow: 9px 9px 8px -2px rgba(0, 0, 0, 0.59);
|
||||
`;
|
||||
|
||||
interface SchedulerRowProps {
|
||||
@ -85,9 +82,9 @@ export const SchedulerRow = ({ groups, indexRow, cellTop, cellWidth, cellHeight
|
||||
const open = Boolean(anchorEl);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{[...Array(5)].map((_, eventIndex) => (
|
||||
<SchedulerEvent
|
||||
<ClassesWrapper
|
||||
eventIndex={eventIndex}
|
||||
cellTop={cellTop}
|
||||
cellWidth={cellWidth}
|
||||
@ -100,8 +97,10 @@ export const SchedulerRow = ({ groups, indexRow, cellTop, cellWidth, cellHeight
|
||||
group.day === eventIndex && (
|
||||
<>
|
||||
<Classes
|
||||
onClick={() => {
|
||||
console.log('group: ', group);
|
||||
}}
|
||||
groupType={group.type}
|
||||
cellWidth={cellWidth}
|
||||
cellHeight={cellHeight}
|
||||
id={`eventRow${indexRow}eventCol${eventIndex}${index}`}
|
||||
key={index}
|
||||
@ -110,11 +109,10 @@ export const SchedulerRow = ({ groups, indexRow, cellTop, cellWidth, cellHeight
|
||||
onMouseEnter={(e) => handlePopoverOpen(e)}
|
||||
onMouseLeave={handlePopoverClose}
|
||||
>
|
||||
<p>
|
||||
{groups[index].name}
|
||||
<br></br>
|
||||
{groups[index].room}
|
||||
</p>
|
||||
<div>
|
||||
<p style={{ fontWeight: 700 }}>{groups[index].name}</p>
|
||||
<p>{groups[index].room}</p>
|
||||
</div>
|
||||
</Classes>
|
||||
<Popover
|
||||
id={`mouse-over-popover`}
|
||||
@ -144,8 +142,8 @@ export const SchedulerRow = ({ groups, indexRow, cellTop, cellWidth, cellHeight
|
||||
</>
|
||||
),
|
||||
)}
|
||||
</SchedulerEvent>
|
||||
</ClassesWrapper>
|
||||
))}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,80 +1,111 @@
|
||||
import React, { useState, MouseEvent } from 'react';
|
||||
import React, { useState, MouseEvent, ChangeEvent, useEffect } from 'react';
|
||||
import Transfer from '../assets/transfer.png';
|
||||
import Search from '../assets/search.svg';
|
||||
import UK from '../assets/UK.png';
|
||||
import PL from '../assets/PL.png';
|
||||
import User from '../assets/user.png';
|
||||
import CloseIcon from '../assets/close.svg';
|
||||
import { ReactComponent as Close } from '../assets/close.svg';
|
||||
import ProfileIcon from '../assets/account.svg';
|
||||
import { Profile } from './Profile';
|
||||
import { Dropdown } from './Dropdown';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const TopbarTextStyled = styled.div`
|
||||
@media only screen and (max-width: 670px) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
import PolishIcon from '../assets/poland.svg';
|
||||
import EnglishIcon from '../assets/united-kingdom.svg';
|
||||
import styled from 'styled-components/macro';
|
||||
import ClickAwayListener from 'react-click-away-listener';
|
||||
|
||||
const Topbar = styled.div`
|
||||
background-color: #ffdc61;
|
||||
background-color: #E3E5ED;
|
||||
height: 80px;
|
||||
padding: 5px;
|
||||
font-family: comic sans MS;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
const TopbarLogoWrapperStyled = styled.div`
|
||||
const LogoWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 0.5;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex: 2;
|
||||
margin-left: 10px;
|
||||
`;
|
||||
|
||||
const TopbarLogoStyled = styled.img`
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
const Logo = styled.img`
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
@media only screen and (max-width: 670px) {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TopbarInputStyled = styled.div`
|
||||
width: 70%;
|
||||
const Text = styled.div`
|
||||
margin-left: 10px;
|
||||
font-size: 1.4rem;
|
||||
user-select: none;
|
||||
@media only screen and (max-width: 670px) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const FlexboxColumn = styled.div`
|
||||
display: flex;
|
||||
flex-grow: 3;
|
||||
flex-direction: column;
|
||||
flex: 12;
|
||||
`;
|
||||
|
||||
const TopbarInputFieldStyled = styled.div`
|
||||
width: 96%;
|
||||
margin-top: 10px;
|
||||
const InputWrapper = styled.div`
|
||||
display: flex;
|
||||
margin-top: 15px;
|
||||
background-color: #f2f4f7;
|
||||
border-radius: 6px;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const TopbarInputIconStyled = styled.img`
|
||||
width: 35px;
|
||||
const Input = styled.input`
|
||||
background-color: #f1f2f5;
|
||||
font-size: 20px;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
margin-left: 5px;
|
||||
border-top-left-radius: 6px;
|
||||
border-bottom-left-radius: 6px;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const CloseIcon = styled(Close)`
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-right: 5px;
|
||||
@media only screen and (max-width: 670px) {
|
||||
width: 25px;
|
||||
}
|
||||
cursor: pointer;
|
||||
:hover {
|
||||
fill: grey;
|
||||
}
|
||||
`;
|
||||
|
||||
const TopbarIcon = styled.img`
|
||||
width: 50px;
|
||||
const IconWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
width: 335px;
|
||||
`;
|
||||
|
||||
const Icon = styled.img`
|
||||
width: 40px;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
@media only screen and (max-width: 670px) {
|
||||
width: 35px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TopbarIconBox = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
flex-grow: 1.5;
|
||||
`;
|
||||
|
||||
|
||||
|
||||
|
||||
interface TopbarProps {
|
||||
handleTransfer: (e: MouseEvent) => void;
|
||||
@ -84,6 +115,8 @@ export default function ({ handleTransfer }: TopbarProps) {
|
||||
const [clearInput, setClearInput] = useState(false);
|
||||
const [isPolish, setIsPolish] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLImageElement | null>(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [input, setInput] = useState('');
|
||||
|
||||
const onLangChange = () => setIsPolish(!isPolish);
|
||||
|
||||
@ -93,25 +126,41 @@ export default function ({ handleTransfer }: TopbarProps) {
|
||||
|
||||
const handleClearInput = () => setClearInput(!clearInput);
|
||||
|
||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => setInput(event.target.value);
|
||||
|
||||
const handleClick = () => setOpen(true);
|
||||
|
||||
const handleCloseDropdown = () => setOpen(false);
|
||||
|
||||
const handleClickAway = () => setOpen(false);
|
||||
|
||||
useEffect(() => {
|
||||
clearInput && (setInput(''), handleClearInput());
|
||||
}, [clearInput]);
|
||||
|
||||
return (
|
||||
<Topbar>
|
||||
<TopbarLogoWrapperStyled>
|
||||
<TopbarLogoStyled alt="logo" src="https://plannaplan.pl/img/logo.svg" />
|
||||
<TopbarTextStyled> plan na plan </TopbarTextStyled>
|
||||
</TopbarLogoWrapperStyled>
|
||||
<TopbarInputStyled>
|
||||
<TopbarInputIconStyled alt="search" src={Search} />
|
||||
<TopbarInputFieldStyled>
|
||||
<Dropdown clearInput={clearInput} handleClearInput={handleClearInput} />
|
||||
</TopbarInputFieldStyled>
|
||||
<TopbarInputIconStyled alt="close" src={CloseIcon} onClick={handleClearInput} />
|
||||
</TopbarInputStyled>
|
||||
<TopbarIconBox>
|
||||
<TopbarIcon alt="transfer" src={Transfer} onClick={handleTransfer} />
|
||||
<TopbarIcon alt="change_language" src={isPolish ? UK : PL} onClick={onLangChange} />
|
||||
<TopbarIcon alt="profile" src={User} onClick={handleProfile} />
|
||||
<LogoWrapper>
|
||||
<Logo alt="logo" src="https://plannaplan.pl/img/logo.svg" />
|
||||
<Text> plan na plan </Text>
|
||||
</LogoWrapper>
|
||||
<FlexboxColumn>
|
||||
<ClickAwayListener onClickAway={handleClickAway}>
|
||||
<InputWrapper>
|
||||
<Input placeholder="Wyszukaj przedmiot..." onChange={handleChange} onClick={handleClick} value={input} />
|
||||
<CloseIcon onClick={handleClearInput} />
|
||||
</InputWrapper>
|
||||
<Dropdown open={open} input={input} handleCloseDropdown={handleCloseDropdown} />
|
||||
</ClickAwayListener>
|
||||
</FlexboxColumn>
|
||||
|
||||
<IconWrapper>
|
||||
{/* <Text>Maciej Głowacki</Text> */}
|
||||
{/* <Icon alt="transfer" src={Transfer} onClick={handleTransfer} /> */}
|
||||
<Icon alt="change_language" src={isPolish ? EnglishIcon : PolishIcon} onClick={onLangChange} />
|
||||
<Icon alt="profile" src={ProfileIcon} onClick={handleProfile} />
|
||||
<Profile anchorEl={anchorEl} handleClose={handleClose} />
|
||||
</TopbarIconBox>
|
||||
</IconWrapper>
|
||||
</Topbar>
|
||||
);
|
||||
}
|
||||
|
@ -53,7 +53,6 @@ const TransferReceiveStyled = styled.div`
|
||||
`;
|
||||
|
||||
const TransferTextStyled = styled.div`
|
||||
font-family: Lato;
|
||||
font-size: 30px;
|
||||
margin-bottom: 10px;
|
||||
`;
|
||||
|
@ -8,15 +8,30 @@ export const days = [
|
||||
];
|
||||
export const hours = [
|
||||
"8:00",
|
||||
"",
|
||||
"9:00",
|
||||
"",
|
||||
"10:00",
|
||||
"",
|
||||
"11:00",
|
||||
"",
|
||||
"12:00",
|
||||
"",
|
||||
"13:00",
|
||||
"",
|
||||
"14:00",
|
||||
"",
|
||||
"15:00",
|
||||
"",
|
||||
"16:00",
|
||||
"",
|
||||
"17:00",
|
||||
"",
|
||||
"18:00",
|
||||
"",
|
||||
"19:00",
|
||||
"",
|
||||
];
|
||||
|
||||
|
||||
export const MONDAY_TO_FRIDAY = 5;
|
@ -1,7 +1,8 @@
|
||||
import React, { useState, createContext, useEffect, ReactNode, useContext } from 'react';
|
||||
import { Course, Group, Basket, GroupType } from '../types';
|
||||
import axios from 'axios';
|
||||
import { CASContext, CASProvider } from './CASProvider';
|
||||
import { CASContext } from './CASProvider';
|
||||
import { useSnackbar } from 'notistack';
|
||||
|
||||
interface CourseContext {
|
||||
courses: Array<Course>;
|
||||
@ -22,44 +23,73 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
|
||||
const [courses, setCourses] = useState<Array<Course>>([]);
|
||||
const [basket, setBasket] = useState<Array<Basket>>([]);
|
||||
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const { closeSnackbar } = useSnackbar();
|
||||
|
||||
const CAS = useContext(CASContext)!;
|
||||
const token = CAS?.user?.token;
|
||||
|
||||
const selectBasketIds = (basket: Array<Basket>) => {
|
||||
const classesIds = basket.map((course) => course.classes.id);
|
||||
const lecturesIds = basket.map((course) => course?.lecture?.id);
|
||||
|
||||
return lecturesIds[0] === undefined ? classesIds : [...classesIds, ...lecturesIds];
|
||||
};
|
||||
|
||||
const addToBasket = (course: Course) => {
|
||||
const courseToBasket = {
|
||||
const courseToBasket: Basket = {
|
||||
name: course.name,
|
||||
id: course.id,
|
||||
classes: course.classes[0],
|
||||
lecture: course.lectures !== undefined ? course.lectures[0] : undefined,
|
||||
} as Basket;
|
||||
};
|
||||
setBasket([...basket, courseToBasket]);
|
||||
};
|
||||
|
||||
const deleteFromBasket = (id: number) => setBasket(basket.filter((course) => course.id !== id));
|
||||
|
||||
const saveBasket = async () => {
|
||||
const basketIds = selectBasketIds(basket);
|
||||
|
||||
const config = {
|
||||
method: 'post' as const,
|
||||
url: `${process.env.REACT_APP_API_URL}/api/v1/commisions/add?`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify(basketIds),
|
||||
};
|
||||
|
||||
const action = (key: any) => (
|
||||
<>
|
||||
<button
|
||||
onClick={() => {
|
||||
closeSnackbar(key);
|
||||
}}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
|
||||
try {
|
||||
let data = [7, 43, 54];
|
||||
let json = JSON.stringify(data);
|
||||
let post_data = { json_data: json };
|
||||
const ech = await axios.post<Array<number>>(
|
||||
`${process.env.REACT_APP_API_URL}/api/v1/commisions/add?`,
|
||||
[7, 43, 54],
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
console.log('api response;', ech);
|
||||
await axios.request(config);
|
||||
enqueueSnackbar('Plan został zapisany', {
|
||||
variant: 'success',
|
||||
action,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
enqueueSnackbar('Zapisywanie planu nie powiodło się', {
|
||||
variant: 'error',
|
||||
action,
|
||||
});
|
||||
}
|
||||
console.log('saving to basket');
|
||||
};
|
||||
|
||||
const addGroup = (choosenGroup: Group, id: number) => {
|
||||
const basketCourse = basket.filter((course) => course.id === id)[0];
|
||||
const type = choosenGroup.type;
|
||||
const { type } = choosenGroup;
|
||||
if (type === GroupType.CLASS) {
|
||||
setBasket(
|
||||
basket.map((basket) => (basket.id === basketCourse.id ? { ...basket, classes: choosenGroup } : basket)),
|
||||
@ -71,23 +101,43 @@ export const CoursesProvider = ({ children }: CoursesProviderProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const { data } = await axios.get<Array<{ id: string; name: string; groups: Array<Group> }>>(
|
||||
const getNewestTimetable = async () => {
|
||||
const config = {
|
||||
method: 'get' as const,
|
||||
url: `${process.env.REACT_APP_API_URL}/api/v1/assignments/getCurrentAssignments`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
};
|
||||
try {
|
||||
let { data: basket } = await axios.request(config);
|
||||
if (basket === '') {
|
||||
basket = [];
|
||||
}
|
||||
setBasket(basket);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchClasses = async () => {
|
||||
try {
|
||||
const { data: courses } = await axios.get<Array<Course>>(
|
||||
`${process.env.REACT_APP_API_URL}/api/v1/courses/getCoursesWithGroups`,
|
||||
);
|
||||
const courses = data.map(({ id, name, groups }) => ({
|
||||
id: parseInt(id),
|
||||
name,
|
||||
lectures: groups.filter(({ type }) => type === GroupType.LECTURE),
|
||||
classes: groups.filter(({ type }) => type === GroupType.CLASS),
|
||||
})) as Array<Course>;
|
||||
courses.sort((a: Course, b: Course) => (a.name > b.name ? 1 : -1));
|
||||
|
||||
courses.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
setCourses(courses);
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchClasses();
|
||||
if (token) {
|
||||
getNewestTimetable();
|
||||
}
|
||||
}, [token]);
|
||||
|
||||
return (
|
||||
<coursesContext.Provider value={{ courses, basket, addToBasket, addGroup, deleteFromBasket, saveBasket }}>
|
||||
|
@ -4,15 +4,24 @@ import { App } from './components/App';
|
||||
import { CASProvider } from './contexts/CASProvider';
|
||||
import { CoursesProvider } from './contexts/CoursesProvider';
|
||||
import { GlobalStyles } from './styles/GlobalStyles';
|
||||
import { SnackbarProvider } from 'notistack';
|
||||
|
||||
ReactDOM.render(
|
||||
<>
|
||||
<CASProvider>
|
||||
<CoursesProvider>
|
||||
<GlobalStyles />
|
||||
<App />
|
||||
</CoursesProvider>
|
||||
</CASProvider>
|
||||
<SnackbarProvider
|
||||
maxSnack={3}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
}}
|
||||
>
|
||||
<CASProvider>
|
||||
<CoursesProvider>
|
||||
<GlobalStyles />
|
||||
<App />
|
||||
</CoursesProvider>
|
||||
</CASProvider>
|
||||
</SnackbarProvider>
|
||||
</>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
|
@ -11,7 +11,7 @@ export const GlobalStyles = createGlobalStyle`
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 24px;
|
||||
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar {
|
||||
|