From 09ec4ca10c708a466425501c65a1148668d69e01 Mon Sep 17 00:00:00 2001 From: Michael M Date: Thu, 7 Apr 2022 23:03:57 +0200 Subject: [PATCH 01/91] feat: add start of projects page layout --- frontend/components/Header.tsx | 52 ++++++++ frontend/pages/projects.tsx | 214 +++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 frontend/components/Header.tsx create mode 100644 frontend/pages/projects.tsx diff --git a/frontend/components/Header.tsx b/frontend/components/Header.tsx new file mode 100644 index 000000000..df8501829 --- /dev/null +++ b/frontend/components/Header.tsx @@ -0,0 +1,52 @@ +import Link from "next/link"; +import { useRouter } from "next/router"; +import { PropsWithChildren } from "react"; + +type HeaderProps = PropsWithChildren; + +const Header: React.FC = () => { + + const router = useRouter(); + const current_path = router.pathname; + + return ( +
+
+ The OSOC logo +

+ Selections +

+
+ +
+ ) +} + +export default Header; \ No newline at end of file diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx new file mode 100644 index 000000000..2597dac26 --- /dev/null +++ b/frontend/pages/projects.tsx @@ -0,0 +1,214 @@ +import type { NextPage } from 'next'; +import Header from '../components/Header'; + +// Header +// +// Sidebar +// Searchbar + filter control button +// Filter panel +// students list +// +// +// Main +// searchbar +// Project tiles +// top information thing +// assigned people list + +const Projects: NextPage = () => { + return ( +
+
+ +
+ {/* Holds the sidebar with search, filter and student results */} +
+ {/* holds searchbar + hide filter button */} +
+ {/* The students searchbar */} +
+
+ +
+
+ + {/* Show/hide filter button */} + +
+ + {/* Holds the filter controls */} +
+ {/* holds drowndown, deselect all, clear all filters */} +
+
+ {/* TODO fix this dropdown later */} + {/* This button controls the dropdown */} + + + +
+ +
+ + {/* holds the toggles */} +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +

Filter on status

+ + {/* holds the filter buttons */} +
+ + + + +
+
+ + {/* TODO add something for x/y shown */} + +
+ + {/* TODO here should be the student tiles */} +
+ + {/* Holds the projects searchbar + project tiles */} +
+ {/* This is the projects searchbar */} +
+
+ +
+
+ + {/* This contains the project tiles */} +
{/* TODO */}
+
+
+
+ ); +}; + +export default Projects; From 562cebfbf33da3c84a212ae0b430fcea0045e6ee Mon Sep 17 00:00:00 2001 From: Michael M Date: Fri, 8 Apr 2022 13:56:12 +0200 Subject: [PATCH 02/91] feat: fixed most of filter controls layout --- frontend/pages/projects.tsx | 79 ++++++++++++++----------------------- frontend/styles/line.css | 11 ++++++ 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx index 2597dac26..96c06dbe5 100644 --- a/frontend/pages/projects.tsx +++ b/frontend/pages/projects.tsx @@ -65,13 +65,13 @@ const Projects: NextPage = () => { {/* Holds the filter controls */}
{/* holds drowndown, deselect all, clear all filters */} -
-
+
+
{/* TODO fix this dropdown later */} {/* This button controls the dropdown */} -
-
{/* holds the toggles */} -
-
-
- - -
+
+
+
+ +
-
-
- - + +
+ +
+
+ +
+
-
-
- - + +
+
+ +
+
@@ -166,7 +144,8 @@ const Projects: NextPage = () => {
- {/* TODO add something for x/y shown */} + {/* TODO add something real for x/y shown */} +

shown 10/10

diff --git a/frontend/styles/line.css b/frontend/styles/line.css index bea920639..e34a64b1d 100644 --- a/frontend/styles/line.css +++ b/frontend/styles/line.css @@ -14,3 +14,14 @@ line-height: 0px; margin: 0px 8px; } + + + +.toggle-checkbox:checked { + right: 0; + border-color: #24a0ed; + } +.toggle-checkbox:checked + .toggle-label { + background-color: #24a0ed; +} + From 6f88e437fa66fe8814501d952f7960fcc95e6615 Mon Sep 17 00:00:00 2001 From: Michael M Date: Fri, 8 Apr 2022 15:19:58 +0200 Subject: [PATCH 03/91] feat: fix some buttons, add some test data --- frontend/pages/projects.tsx | 83 ++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx index 96c06dbe5..e4511e985 100644 --- a/frontend/pages/projects.tsx +++ b/frontend/pages/projects.tsx @@ -1,5 +1,66 @@ import type { NextPage } from 'next'; import Header from '../components/Header'; +import {useState} from "react"; +// import react minimal pie chart + +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; +const magnifying_glass = ; +// const eyeSlash = ; +// + +// Temporary fake data to test with +const students = [ + { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Undecided', + statusSuggestions: [ + { + coachId: '100', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: true + }, + { + id: '2', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Undecided', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false + } +] + // Header // @@ -16,6 +77,7 @@ import Header from '../components/Header'; // assigned people list const Projects: NextPage = () => { + const [showFilter, setShowFilter] = useState(true); return (
@@ -27,7 +89,7 @@ const Projects: NextPage = () => {
{/* The students searchbar */}
-
+
+ {/* TODO add actual onclick search */} + } + >{magnifying_glass}
@@ -57,13 +124,14 @@ const Projects: NextPage = () => {
{/* Holds the filter controls */} -
+
{/* holds drowndown, deselect all, clear all filters */}
@@ -127,7 +195,7 @@ const Projects: NextPage = () => { className="toggle-checkbox absolute w-3 h-3 rounded-full bg-gray-300 appearance-none cursor-pointer m-1"/>
- +
@@ -147,7 +215,7 @@ const Projects: NextPage = () => { {/* TODO add something real for x/y shown */}

shown 10/10

-
+
{/* TODO here should be the student tiles */} @@ -156,7 +224,7 @@ const Projects: NextPage = () => {
{/* This is the projects searchbar */}
-
+
+ {/* TODO add actual onclick search */} + } + >{magnifying_glass}
From 06e2630fcf388ffc48fc70cdbb7fe17ddade13c3 Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 9 Apr 2022 15:27:16 +0200 Subject: [PATCH 04/91] feat: add basic student tiles w piechart --- frontend/components/students/StudentTile.tsx | 84 +++++++++++++++++++ frontend/components/students/StudentTiles.tsx | 29 +++++++ frontend/package.json | 7 ++ frontend/pages/projects.tsx | 82 ++++++++++++++++-- frontend/styles/line.css | 6 +- frontend/yarn.lock | 47 ++++++++++- 6 files changed, 248 insertions(+), 7 deletions(-) create mode 100644 frontend/components/students/StudentTile.tsx create mode 100644 frontend/components/students/StudentTiles.tsx diff --git a/frontend/components/students/StudentTile.tsx b/frontend/components/students/StudentTile.tsx new file mode 100644 index 000000000..cbf355a02 --- /dev/null +++ b/frontend/components/students/StudentTile.tsx @@ -0,0 +1,84 @@ +import { PieChart } from 'react-minimal-pie-chart'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faCheck, faQuestion, faXmark } from "@fortawesome/free-solid-svg-icons"; +import { Icon } from '@iconify/react'; +const check_mark = ; +const question_mark = ; +const x_mark = ; +const tilde_mark = ; + +export type Student = { + id: string, + firstName: string, + lastName: string, + status: string, + statusSuggestions: StatusSuggestion[], + alumn: boolean +}; + +type StatusSuggestion = { + coachId: string, + status: string, + motivation: string +} + +type StudentProp = { + student: Student; +} + +const StudentTile: React.FC = ({ student }: StudentProp) => { + + let myLabel = tilde_mark; + let myColor = "text-gray-400"; + if (student.status == "Yes"){ + myLabel = check_mark; + myColor = "text-green-400"; + } else if (student.status == "No") { + myLabel = x_mark; + myColor = "text-red-400"; + } else if (student.status == "Maybe") { + myLabel = question_mark; + myColor = "text-orange-400"; + } + + let yes = 0; + let no = 0; + let maybe = 0; + student.statusSuggestions.forEach( (suggestion) => { + console.log(suggestion); + if (suggestion.status == 'Yes') { + yes += 1; + } else if (suggestion.status == 'No') { + no += 1; + } else { + maybe += 1; + } + }) + + return ( + + + { student.firstName + " " + student.lastName } + + {/* TODO Add the alumni thing */} + +
+ + {/* TODO fix this size to not be hardcoded */} + {myLabel} +
+ + + ) +} + +export default StudentTile; \ No newline at end of file diff --git a/frontend/components/students/StudentTiles.tsx b/frontend/components/students/StudentTiles.tsx new file mode 100644 index 000000000..e5a8b3c86 --- /dev/null +++ b/frontend/components/students/StudentTiles.tsx @@ -0,0 +1,29 @@ +import StudentTile, { Student } from './StudentTile'; + +type StudentTableProps = { + students: Student[] +} + +const StudentTiles: React.FC = ({ students }: StudentTableProps) => { + + return ( + + + + {/* TODO outline right does not want to work */} + + + + + { + students.map((student) => ) + } + +
+ {/* TODO this should be something else once endpoint is dont */} + { students.length + "/" + students.length + " shown" } +
+ ) +} + +export default StudentTiles; \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index ee19561fe..aab419c40 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,11 +9,18 @@ "prettier:write": "yarn prettier --write ." }, "dependencies": { + "@fortawesome/fontawesome-free": "^6.1.1", + "@fortawesome/fontawesome-svg-core": "^6.1.1", + "@fortawesome/free-solid-svg-icons": "^6.1.1", + "@fortawesome/react-fontawesome": "^0.1.18", "@heroicons/react": "^1.0.6", + "@iconify/react": "^3.2.1", + "font-awesome": "^4.7.0", "next": "latest", "react": "^17.0.2", "react-dom": "^17.0.2", "react-hot-toast": "^2.2.0", + "react-minimal-pie-chart": "^8.2.0", "react-preloader-icon": "^1.0.0", "recoil": "^0.6.1", "uuid": "^8.3.2" diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx index e4511e985..48ec7b296 100644 --- a/frontend/pages/projects.tsx +++ b/frontend/pages/projects.tsx @@ -1,13 +1,11 @@ import type { NextPage } from 'next'; import Header from '../components/Header'; import {useState} from "react"; -// import react minimal pie chart +import StudentTiles from '../components/students/StudentTiles'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; const magnifying_glass = ; -// const eyeSlash = ; -// // Temporary fake data to test with const students = [ @@ -58,6 +56,78 @@ const students = [ } ], alumn: false + }, + { + id: '3', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Yes', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false + }, + { + id: '4', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'No', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false + }, + { + id: '5', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Maybe', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false } ] @@ -213,9 +283,11 @@ const Projects: NextPage = () => {
{/* TODO add something real for x/y shown */} -

shown 10/10

+ {/*

shown 10/10

*/} + + {/*
*/} -
+ {/* TODO here should be the student tiles */}
diff --git a/frontend/styles/line.css b/frontend/styles/line.css index e34a64b1d..bd8c37f41 100644 --- a/frontend/styles/line.css +++ b/frontend/styles/line.css @@ -16,7 +16,6 @@ } - .toggle-checkbox:checked { right: 0; border-color: #24a0ed; @@ -25,3 +24,8 @@ background-color: #24a0ed; } + +.chart-label { + transform: translate(-50%, -50%); +} + diff --git a/frontend/yarn.lock b/frontend/yarn.lock index c7b3bf3b3..b21ed548e 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -38,6 +38,37 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@fortawesome/fontawesome-common-types@6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.1.tgz#7dc996042d21fc1ae850e3173b5c67b0549f9105" + integrity sha512-wVn5WJPirFTnzN6tR95abCx+ocH+3IFLXAgyavnf9hUmN0CfWoDjPT/BAWsUVwSlYYVBeCLJxaqi7ZGe4uSjBA== + +"@fortawesome/fontawesome-free@^6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz#bf5d45611ab74890be386712a0e5d998c65ee2a1" + integrity sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg== + +"@fortawesome/fontawesome-svg-core@^6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.1.tgz#3424ec6182515951816be9b11665d67efdce5b5f" + integrity sha512-NCg0w2YIp81f4V6cMGD9iomfsIj7GWrqmsa0ZsPh59G7PKiGN1KymZNxmF00ssuAlo/VZmpK6xazsGOwzKYUMg== + dependencies: + "@fortawesome/fontawesome-common-types" "6.1.1" + +"@fortawesome/free-solid-svg-icons@^6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.1.tgz#3369e673f8fe8be2fba30b1ec274d47490a830a6" + integrity sha512-0/5exxavOhI/D4Ovm2r3vxNojGZioPwmFrKg0ZUH69Q68uFhFPs6+dhAToh6VEQBntxPRYPuT5Cg1tpNa9JUPg== + dependencies: + "@fortawesome/fontawesome-common-types" "6.1.1" + +"@fortawesome/react-fontawesome@^0.1.18": + version "0.1.18" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.18.tgz#dae37f718a24e14d7a99a5496c873d69af3fbd73" + integrity sha512-RwLIB4TZw0M9gvy5u+TusAA0afbwM4JQIimNH/j3ygd6aIvYPQLqXMhC9ErY26J23rDPyDZldIfPq/HpTTJ/tQ== + dependencies: + prop-types "^15.8.1" + "@heroicons/react@^1.0.6": version "1.0.6" resolved "https://registry.npmjs.org/@heroicons/react/-/react-1.0.6.tgz" @@ -57,6 +88,11 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@iconify/react@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@iconify/react/-/react-3.2.1.tgz#d18da31cec58c1aa8fdf4def451cc7e3196d88de" + integrity sha512-yKzixjC9ct9RC/aSGo1OGxkG2rpfhlr/urRz6k2YZlIBzn92PBTlqtSx8o8dFYEorr3eUFSCBZFzBy1yw5jsAA== + "@microsoft/tsdoc-config@0.15.2": version "0.15.2" resolved "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz" @@ -876,6 +912,11 @@ flatted@^3.1.0: resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== +font-awesome@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" + integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM= + fraction.js@^4.1.2: version "4.1.3" resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.3.tgz" @@ -1264,7 +1305,6 @@ minimatch@^3.0.4, minimatch@^3.1.2: brace-expansion "^1.1.7" minimist@^1.1.1: - version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -1566,6 +1606,11 @@ react-is@^16.13.1: resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-minimal-pie-chart@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/react-minimal-pie-chart/-/react-minimal-pie-chart-8.2.0.tgz#22b53af2363f040d818331721658dfa7a1ea847a" + integrity sha512-RhrHzprJt3KfBe4L3sE0Ha6fj4kYcwQtesQgscnld9Umf64+nZnxxInycnbimKsbIjxJONv77JIZp+qRbJD+bA== + react-preloader-icon@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/react-preloader-icon/-/react-preloader-icon-1.0.0.tgz" From 9525f708df7860d02e4324f8c729096d88792625 Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 9 Apr 2022 16:51:25 +0200 Subject: [PATCH 05/91] feat: finished sidebar for normal screen size --- frontend/components/StudentSidebar.tsx | 258 ++++++++++++++++ frontend/components/students/StudentTile.tsx | 28 +- frontend/components/students/StudentTiles.tsx | 3 +- frontend/pages/projects.tsx | 284 +----------------- 4 files changed, 280 insertions(+), 293 deletions(-) create mode 100644 frontend/components/StudentSidebar.tsx diff --git a/frontend/components/StudentSidebar.tsx b/frontend/components/StudentSidebar.tsx new file mode 100644 index 000000000..7bc800446 --- /dev/null +++ b/frontend/components/StudentSidebar.tsx @@ -0,0 +1,258 @@ +import {PropsWithChildren, useState} from "react"; +import StudentTiles from "./students/StudentTiles"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; +const magnifying_glass = ; + +type StudentsSidebarProps = PropsWithChildren; + +// TODO no actual functionality implemented yet +// TODO fix mobile view +const StudentSidebar: React.FC = () => { + const [showFilter, setShowFilter] = useState(true); + return ( + // TODO test with a long list for autoscroll etc this should be separate from projects scroll +
+ {/* holds searchbar + hide filter button */} +
+ {/* The students searchbar */} +
+
+ + {/* TODO add actual onclick search */} + } + >{magnifying_glass} +
+
+ + {/* Show/hide filter button */} + +
+ + {/* Holds the filter controls */} + + + {/* These are the student tiles */} + +
+ ) +} + +export default StudentSidebar; + + +// Temporary fake data to test with +const students = [ + { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Undecided', + statusSuggestions: [ + { + coachId: '100', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: true + }, + { + id: '2', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Undecided', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false + }, + { + id: '3', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Yes', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false + }, + { + id: '4', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'No', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false + }, + { + id: '5', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Maybe', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe' + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes' + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no' + } + ], + alumn: false + } +] \ No newline at end of file diff --git a/frontend/components/students/StudentTile.tsx b/frontend/components/students/StudentTile.tsx index cbf355a02..a6f8600cb 100644 --- a/frontend/components/students/StudentTile.tsx +++ b/frontend/components/students/StudentTile.tsx @@ -45,7 +45,6 @@ const StudentTile: React.FC = ({ student }: StudentProp) => { let no = 0; let maybe = 0; student.statusSuggestions.forEach( (suggestion) => { - console.log(suggestion); if (suggestion.status == 'Yes') { yes += 1; } else if (suggestion.status == 'No') { @@ -56,26 +55,33 @@ const StudentTile: React.FC = ({ student }: StudentProp) => { }) return ( - - - { student.firstName + " " + student.lastName } - - {/* TODO Add the alumni thing */} - -
+ + +
+ +
+
+

+ Alumn +

+
+

{student.firstName + " " + student.lastName}

+
+
- {/* TODO fix this size to not be hardcoded */} + {/* TODO fix this text size to not be hardcoded */} {myLabel}
+
) diff --git a/frontend/components/students/StudentTiles.tsx b/frontend/components/students/StudentTiles.tsx index e5a8b3c86..9e2c156a2 100644 --- a/frontend/components/students/StudentTiles.tsx +++ b/frontend/components/students/StudentTiles.tsx @@ -10,8 +10,7 @@ const StudentTiles: React.FC = ({ students }: StudentTablePro - {/* TODO outline right does not want to work */} - diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx index 48ec7b296..1b9645dda 100644 --- a/frontend/pages/projects.tsx +++ b/frontend/pages/projects.tsx @@ -1,136 +1,12 @@ import type { NextPage } from 'next'; import Header from '../components/Header'; import {useState} from "react"; -import StudentTiles from '../components/students/StudentTiles'; +import StudentSidebar from '../components/StudentSidebar'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; const magnifying_glass = ; -// Temporary fake data to test with -const students = [ - { - id: '1', - firstName: 'FNaam1', - lastName: 'LNaam1', - status: 'Undecided', - statusSuggestions: [ - { - coachId: '100', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: true - }, - { - id: '2', - firstName: 'FNaam2', - lastName: 'LNaam2', - status: 'Undecided', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - }, - { - id: '3', - firstName: 'FNaam2', - lastName: 'LNaam2', - status: 'Yes', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - }, - { - id: '4', - firstName: 'FNaam2', - lastName: 'LNaam2', - status: 'No', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - }, - { - id: '5', - firstName: 'FNaam2', - lastName: 'LNaam2', - status: 'Maybe', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - } -] - // Header // @@ -147,150 +23,14 @@ const students = [ // assigned people list const Projects: NextPage = () => { - const [showFilter, setShowFilter] = useState(true); + return (
{/* Holds the sidebar with search, filter and student results */} -
- {/* holds searchbar + hide filter button */} -
- {/* The students searchbar */} -
-
- - {/* TODO add actual onclick search */} - } - >{magnifying_glass} -
-
- - {/* Show/hide filter button */} - -
- - {/* Holds the filter controls */} -
- {/* holds drowndown, deselect all, clear all filters */} -
-
- {/* TODO fix this dropdown later */} - {/* This button controls the dropdown */} - - - -
- -
- - {/* holds the toggles */} -
-
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
-
- -

Filter on status

- - {/* holds the filter buttons */} -
- - - - -
-
- - {/* TODO add something real for x/y shown */} - {/*

shown 10/10

*/} - - {/*
*/} - - - - {/* TODO here should be the student tiles */} -
+ {/* Holds the projects searchbar + project tiles */}
@@ -299,23 +39,7 @@ const Projects: NextPage = () => {
From 14c9855372451e6c3e4a64bc70cb9bd1c363e767 Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 9 Apr 2022 17:07:53 +0200 Subject: [PATCH 06/91] chore: commiting to merge development --- frontend/components/projects/ProjectTile.tsx | 21 ++++++++++++++ frontend/components/projects/ProjectTiles.tsx | 28 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 frontend/components/projects/ProjectTile.tsx create mode 100644 frontend/components/projects/ProjectTiles.tsx diff --git a/frontend/components/projects/ProjectTile.tsx b/frontend/components/projects/ProjectTile.tsx new file mode 100644 index 000000000..3fc69d956 --- /dev/null +++ b/frontend/components/projects/ProjectTile.tsx @@ -0,0 +1,21 @@ +export type Project = { + id: string + name: string + client: string + // coaches* [...] + // desc* string + // studentRoles* [...] +}; + +type ProjectProp = { + project: Project; +} + +const ProjectTile: React.FC = ({ project }: ProjectProp) => { + + return ( +
+ ) +} + +export default ProjectTile; \ No newline at end of file diff --git a/frontend/components/projects/ProjectTiles.tsx b/frontend/components/projects/ProjectTiles.tsx new file mode 100644 index 000000000..2d25bb4ea --- /dev/null +++ b/frontend/components/projects/ProjectTiles.tsx @@ -0,0 +1,28 @@ +import ProjectTile, { Project } from './ProjectTile'; + +type ProjectTableProps = { + projects: Project[] +} + +const ProjectTiles: React.FC = ({ projects }: ProjectTableProps) => { + + return ( +
+ {/* TODO this should be something else once endpoint is dont */} { students.length + "/" + students.length + " shown" }
+ + + + + + + { + projects.map((project) => ) + } + +
+ {/* TODO this should be something else once endpoint is dont */} + {/*{ students.length + "/" + students.length + " shown" }*/} +
+ ) +} + +export default ProjectTiles; \ No newline at end of file From 83e7179871b88ae539f2dc8dcba8c09add19a515 Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 9 Apr 2022 19:25:52 +0200 Subject: [PATCH 07/91] feat: finished normal size projects page --- frontend/.eslintignore | 1 + frontend/.prettierignore | 3 +- frontend/components/Header.tsx | 95 ++-- frontend/components/StudentSidebar.tsx | 484 ++++++++++-------- frontend/components/projects/ProjectTile.tsx | 142 ++++- frontend/components/projects/ProjectTiles.tsx | 37 +- frontend/components/students/StudentTile.tsx | 157 +++--- frontend/components/students/StudentTiles.tsx | 47 +- frontend/pages/projects.tsx | 414 ++++++++++++++- frontend/styles/line.css | 25 +- frontend/tailwind.config.js | 2 + 11 files changed, 986 insertions(+), 421 deletions(-) diff --git a/frontend/.eslintignore b/frontend/.eslintignore index 31915a21c..10be7b39a 100644 --- a/frontend/.eslintignore +++ b/frontend/.eslintignore @@ -29,3 +29,4 @@ frontend/* !styles/ !lib/ !atoms/ +!components/ diff --git a/frontend/.prettierignore b/frontend/.prettierignore index e1520e617..7535b8c84 100644 --- a/frontend/.prettierignore +++ b/frontend/.prettierignore @@ -31,4 +31,5 @@ frontend/* !src/ !styles/ !lib/ -!atoms/ \ No newline at end of file +!atoms/ +!components/ \ No newline at end of file diff --git a/frontend/components/Header.tsx b/frontend/components/Header.tsx index df8501829..32fe38ae5 100644 --- a/frontend/components/Header.tsx +++ b/frontend/components/Header.tsx @@ -1,52 +1,55 @@ -import Link from "next/link"; -import { useRouter } from "next/router"; -import { PropsWithChildren } from "react"; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { PropsWithChildren } from 'react'; type HeaderProps = PropsWithChildren; const Header: React.FC = () => { + const router = useRouter(); + const current_path = router.pathname; - const router = useRouter(); - const current_path = router.pathname; + return ( +
+
+ The OSOC logo +

+ Selections +

+
+ +
+ ); +}; - return ( -
-
- The OSOC logo -

- Selections -

-
- -
- ) -} - -export default Header; \ No newline at end of file +export default Header; diff --git a/frontend/components/StudentSidebar.tsx b/frontend/components/StudentSidebar.tsx index 7bc800446..b096e0e9e 100644 --- a/frontend/components/StudentSidebar.tsx +++ b/frontend/components/StudentSidebar.tsx @@ -1,7 +1,7 @@ -import {PropsWithChildren, useState} from "react"; -import StudentTiles from "./students/StudentTiles"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; +import { PropsWithChildren, useState } from 'react'; +import StudentTiles from './students/StudentTiles'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons'; const magnifying_glass = ; type StudentsSidebarProps = PropsWithChildren; @@ -9,250 +9,280 @@ type StudentsSidebarProps = PropsWithChildren; // TODO no actual functionality implemented yet // TODO fix mobile view const StudentSidebar: React.FC = () => { - const [showFilter, setShowFilter] = useState(true); - return ( + const [showFilter, setShowFilter] = useState(true); + return ( // TODO test with a long list for autoscroll etc this should be separate from projects scroll -
- {/* holds searchbar + hide filter button */} -
- {/* The students searchbar */} -
-
- - {/* TODO add actual onclick search */} - } - >{magnifying_glass} -
-
+
+ {/* holds searchbar + hide filter button */} +
+ {/* The students searchbar */} +
+
+ + {/* TODO add actual onclick search */} + } + > + {magnifying_glass} + +
+
- {/* Show/hide filter button */} + {/* Show/hide filter button */} + +
+ + {/* Holds the filter controls */} +
- ) -} + ); +}; export default StudentSidebar; - // Temporary fake data to test with const students = [ - { - id: '1', - firstName: 'FNaam1', - lastName: 'LNaam1', - status: 'Undecided', - statusSuggestions: [ - { - coachId: '100', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: true - }, - { - id: '2', - firstName: 'FNaam2', - lastName: 'LNaam2', - status: 'Undecided', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - }, - { - id: '3', - firstName: 'FNaam2', - lastName: 'LNaam2', + { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Undecided', + statusSuggestions: [ + { + coachId: '100', status: 'Yes', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - }, - { - id: '4', - firstName: 'FNaam2', - lastName: 'LNaam2', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no', + }, + ], + alumn: true, + }, + { + id: '2', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Undecided', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe', + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no', + }, + ], + alumn: false, + }, + { + id: '3', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Yes', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe', + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no', + }, + ], + alumn: false, + }, + { + id: '4', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'No', + statusSuggestions: [ + { + coachId: '100', + status: 'Maybe', + motivation: 'Dit is een motivatie voor maybe', + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '102', status: 'No', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - }, - { - id: '5', - firstName: 'FNaam2', - lastName: 'LNaam2', + motivation: 'Dit is een motivatie voor no', + }, + ], + alumn: false, + }, + { + id: '5', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Maybe', + statusSuggestions: [ + { + coachId: '100', status: 'Maybe', - statusSuggestions: [ - { - coachId: '100', - status: 'Maybe', - motivation: 'Dit is een motivatie voor maybe' - }, - { - coachId: '101', - status: 'Yes', - motivation: 'Dit is een motivatie voor yes' - }, - { - coachId: '102', - status: 'No', - motivation: 'Dit is een motivatie voor no' - } - ], - alumn: false - } -] \ No newline at end of file + motivation: 'Dit is een motivatie voor maybe', + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no', + }, + ], + alumn: false, + }, +]; diff --git a/frontend/components/projects/ProjectTile.tsx b/frontend/components/projects/ProjectTile.tsx index 3fc69d956..e4519d4f2 100644 --- a/frontend/components/projects/ProjectTile.tsx +++ b/frontend/components/projects/ProjectTile.tsx @@ -1,21 +1,137 @@ +import { Student } from '../students/StudentTile'; +import { Icon } from '@iconify/react'; +const speech_bubble = ; +const xmark_circle = ; + export type Project = { - id: string - name: string - client: string - // coaches* [...] - // desc* string - // studentRoles* [...] + id: string; + name: string; + clientName: string; + description: string; + coaches: User[]; + positions: Position[]; + assignments: Assignment[]; +}; + +type User = { + id: string; + username: string; + email: string; + // other stuff doesn't matter for now +}; + +type Position = { + id: string; + skill: string; + amount: number; +}; + +type Assignment = { + id: string; + student: Student; + position: Position; + suggester: User; + reason: string; }; type ProjectProp = { - project: Project; -} + project: Project; +}; + +type UserProp = { + user: User; +}; + +type PositionProp = { + position: Position; +}; + +type AssignmentProp = { + assignment: Assignment; +}; const ProjectTile: React.FC = ({ project }: ProjectProp) => { + return ( +
+ {/* project info top */} +
+ {/* left part of header */} +
+

{project.name}

+

{project.clientName}

+
+ {project.coaches.map((user) => ( + + ))} +
+
+ + {/* right part of header */} +
+ {project.positions.map((position) => ( + + ))} +
+
+ + {/* assigned students list */} +
+ {project.assignments.map((assignment) => ( + + ))} +
+
+ ); +}; - return ( -
- ) -} +const ProjectCoachesList: React.FC = ({ user }: UserProp) => { + return

{user.username}

; +}; + +const ProjectPositionsList: React.FC = ({ + position, +}: PositionProp) => { + return ( +
+

+ {position.amount + 'x ' + position.skill} +

+
+ ); +}; + +const ProjectAssignmentsList: React.FC = ({ + assignment, +}: AssignmentProp) => { + return ( +
+
+
+

+ {assignment.student.firstName + ' ' + assignment.student.lastName} +

+
+ {speech_bubble} + {/* TODO Make this tooltip look nicer */} + + {assignment.reason} + +
+
+

+ {' '} + {assignment.position.skill}{' '} +

+

+ {' '} + Suggested by {assignment.suggester.username}{' '} +

+
+
+ {xmark_circle} +
+
+ ); +}; -export default ProjectTile; \ No newline at end of file +export default ProjectTile; diff --git a/frontend/components/projects/ProjectTiles.tsx b/frontend/components/projects/ProjectTiles.tsx index 2d25bb4ea..bc3352961 100644 --- a/frontend/components/projects/ProjectTiles.tsx +++ b/frontend/components/projects/ProjectTiles.tsx @@ -1,28 +1,19 @@ import ProjectTile, { Project } from './ProjectTile'; type ProjectTableProps = { - projects: Project[] -} + projects: Project[]; +}; -const ProjectTiles: React.FC = ({ projects }: ProjectTableProps) => { +const ProjectTiles: React.FC = ({ + projects, +}: ProjectTableProps) => { + return ( +
+ {projects.map((project) => ( + + ))} +
+ ); +}; - return ( - - - - - - - - { - projects.map((project) => ) - } - -
- {/* TODO this should be something else once endpoint is dont */} - {/*{ students.length + "/" + students.length + " shown" }*/} -
- ) -} - -export default ProjectTiles; \ No newline at end of file +export default ProjectTiles; diff --git a/frontend/components/students/StudentTile.tsx b/frontend/components/students/StudentTile.tsx index a6f8600cb..84403c7c7 100644 --- a/frontend/components/students/StudentTile.tsx +++ b/frontend/components/students/StudentTile.tsx @@ -1,6 +1,10 @@ import { PieChart } from 'react-minimal-pie-chart'; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faCheck, faQuestion, faXmark } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { + faCheck, + faQuestion, + faXmark, +} from '@fortawesome/free-solid-svg-icons'; import { Icon } from '@iconify/react'; const check_mark = ; const question_mark = ; @@ -8,83 +12,94 @@ const x_mark = ; const tilde_mark = ; export type Student = { - id: string, - firstName: string, - lastName: string, - status: string, - statusSuggestions: StatusSuggestion[], - alumn: boolean + id: string; + firstName: string; + lastName: string; + status: string; + statusSuggestions: StatusSuggestion[]; + alumn: boolean; }; type StatusSuggestion = { - coachId: string, - status: string, - motivation: string -} + coachId: string; + status: string; + motivation: string; +}; type StudentProp = { - student: Student; -} + student: Student; +}; const StudentTile: React.FC = ({ student }: StudentProp) => { + let myLabel = tilde_mark; + let myColor = 'text-gray-400'; + if (student.status == 'Yes') { + myLabel = check_mark; + myColor = 'text-green-400'; + } else if (student.status == 'No') { + myLabel = x_mark; + myColor = 'text-red-400'; + } else if (student.status == 'Maybe') { + myLabel = question_mark; + myColor = 'text-orange-400'; + } - let myLabel = tilde_mark; - let myColor = "text-gray-400"; - if (student.status == "Yes"){ - myLabel = check_mark; - myColor = "text-green-400"; - } else if (student.status == "No") { - myLabel = x_mark; - myColor = "text-red-400"; - } else if (student.status == "Maybe") { - myLabel = question_mark; - myColor = "text-orange-400"; + let yes = 0; + let no = 0; + let maybe = 0; + student.statusSuggestions.forEach((suggestion) => { + if (suggestion.status == 'Yes') { + yes += 1; + } else if (suggestion.status == 'No') { + no += 1; + } else { + maybe += 1; } + }); - let yes = 0; - let no = 0; - let maybe = 0; - student.statusSuggestions.forEach( (suggestion) => { - if (suggestion.status == 'Yes') { - yes += 1; - } else if (suggestion.status == 'No') { - no += 1; - } else { - maybe += 1; - } - }) - - return ( - - -
- -
-
-

- Alumn -

-
-

{student.firstName + " " + student.lastName}

-
-
- - {/* TODO fix this text size to not be hardcoded */} - {myLabel} -
-
- - - ) -} + return ( + + +
+
+
+

+ Alumn +

+
+

+ {' '} + {student.firstName + ' ' + student.lastName}{' '} +

+
+
+ + {/* TODO fix this text size to not be hardcoded */} + + {myLabel} + +
+
+ + + ); +}; -export default StudentTile; \ No newline at end of file +export default StudentTile; diff --git a/frontend/components/students/StudentTiles.tsx b/frontend/components/students/StudentTiles.tsx index 9e2c156a2..fd88e55c6 100644 --- a/frontend/components/students/StudentTiles.tsx +++ b/frontend/components/students/StudentTiles.tsx @@ -1,28 +1,29 @@ import StudentTile, { Student } from './StudentTile'; type StudentTableProps = { - students: Student[] -} + students: Student[]; +}; -const StudentTiles: React.FC = ({ students }: StudentTableProps) => { +const StudentTiles: React.FC = ({ + students, +}: StudentTableProps) => { + return ( + + + + + + + + {students.map((student) => ( + + ))} + +
+ {/* TODO this should be something else once endpoint is dont */} + {students.length + '/' + students.length + ' shown'} +
+ ); +}; - return ( - - - - - - - - { - students.map((student) => ) - } - -
- {/* TODO this should be something else once endpoint is dont */} - { students.length + "/" + students.length + " shown" } -
- ) -} - -export default StudentTiles; \ No newline at end of file +export default StudentTiles; diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx index 1b9645dda..9539a0284 100644 --- a/frontend/pages/projects.tsx +++ b/frontend/pages/projects.tsx @@ -1,13 +1,12 @@ import type { NextPage } from 'next'; import Header from '../components/Header'; -import {useState} from "react"; import StudentSidebar from '../components/StudentSidebar'; +import ProjectTiles from '../components/projects/ProjectTiles'; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons'; const magnifying_glass = ; - // Header // // Sidebar @@ -23,17 +22,16 @@ const magnifying_glass = ; // assigned people list const Projects: NextPage = () => { - return (
{/* Holds the sidebar with search, filter and student results */} - + {/* Holds the projects searchbar + project tiles */} -
+
{/* This is the projects searchbar */}
@@ -45,14 +43,16 @@ const Projects: NextPage = () => { /> {/* TODO add actual onclick search */} } - >{magnifying_glass} + className="absolute bottom-1.5 right-2 opacity-20" + // onClick={() => } + > + {magnifying_glass} +
{/* This contains the project tiles */} -
{/* TODO */}
+
@@ -60,3 +60,395 @@ const Projects: NextPage = () => { }; export default Projects; + +// Test data +// Skill will probably not work when actual data is used +const projects = [ + { + id: '1', + name: 'some project', + clientName: 'some client name', + description: 'some description', + coaches: [ + { + id: '101', + username: 'coach 101', + email: 'coach101@smnt.com', + }, + { + id: '104', + username: 'coach 104', + email: 'coach104@smnt.com', + }, + ], + positions: [ + { + id: '1001', + skill: 'Full Stack dev', + amount: 2, + }, + { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + { + id: '1004', + skill: 'Skill4', + amount: 1, + }, + { + id: '1005', + skill: 'Skill5', + amount: 1, + }, + { + id: '1006', + skill: 'Skill6', + amount: 1, + }, + ], + assignments: [ + { + id: '10001', + student: { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Yes', + statusSuggestions: [], + alumn: true, + }, + position: { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'A reason for doing something I hate creating fake data', + }, + { + id: '10002', + student: { + id: '2', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Maybe', + statusSuggestions: [], + alumn: false, + }, + position: { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'Another reason for doing something I hate creating fake data', + }, + ], + }, + + { + id: '2', + name: 'some project', + clientName: 'some client name', + description: 'some description', + coaches: [ + { + id: '101', + username: 'coach 101', + email: 'coach101@smnt.com', + }, + { + id: '104', + username: 'coach 104', + email: 'coach104@smnt.com', + }, + ], + positions: [ + { + id: '1001', + skill: 'Full Stack dev', + amount: 2, + }, + { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + { + id: '1004', + skill: 'Skill4', + amount: 1, + }, + { + id: '1005', + skill: 'Skill5', + amount: 1, + }, + { + id: '1006', + skill: 'Skill6', + amount: 1, + }, + ], + assignments: [ + { + id: '10001', + student: { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Yes', + statusSuggestions: [], + alumn: true, + }, + position: { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'A reason for doing something I hate creating fake data', + }, + { + id: '10002', + student: { + id: '2', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Maybe', + statusSuggestions: [], + alumn: false, + }, + position: { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'Another reason for doing something I hate creating fake data', + }, + ], + }, + + { + id: '3', + name: 'some project', + clientName: 'some client name', + description: 'some description', + coaches: [ + { + id: '101', + username: 'coach 101', + email: 'coach101@smnt.com', + }, + { + id: '104', + username: 'coach 104', + email: 'coach104@smnt.com', + }, + ], + positions: [ + { + id: '1001', + skill: 'Full Stack dev', + amount: 2, + }, + { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + { + id: '1004', + skill: 'Skill4', + amount: 1, + }, + { + id: '1005', + skill: 'Skill5', + amount: 1, + }, + { + id: '1006', + skill: 'Skill6', + amount: 1, + }, + ], + assignments: [ + { + id: '10001', + student: { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Yes', + statusSuggestions: [], + alumn: true, + }, + position: { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'A reason for doing something I hate creating fake data', + }, + { + id: '10002', + student: { + id: '2', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Maybe', + statusSuggestions: [], + alumn: false, + }, + position: { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'Another reason for doing something I hate creating fake data', + }, + ], + }, + + { + id: '4', + name: 'some project', + clientName: 'some client name', + description: 'some description', + coaches: [ + { + id: '101', + username: 'coach 101', + email: 'coach101@smnt.com', + }, + { + id: '104', + username: 'coach 104', + email: 'coach104@smnt.com', + }, + ], + positions: [ + { + id: '1001', + skill: 'Full Stack dev', + amount: 2, + }, + { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + { + id: '1004', + skill: 'Skill4', + amount: 1, + }, + { + id: '1005', + skill: 'Skill5', + amount: 1, + }, + { + id: '1006', + skill: 'Skill6', + amount: 1, + }, + ], + assignments: [ + { + id: '10001', + student: { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Yes', + statusSuggestions: [], + alumn: true, + }, + position: { + id: '1002', + skill: 'Skill2', + amount: 3, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'A reason for doing something I hate creating fake data', + }, + { + id: '10002', + student: { + id: '2', + firstName: 'FNaam2', + lastName: 'LNaam2', + status: 'Maybe', + statusSuggestions: [], + alumn: false, + }, + position: { + id: '1003', + skill: 'UI UX Guy', + amount: 1, + }, + suggester: { + id: '102', + username: 'coach 102', + email: 'coach102@smnt.com', + }, + reason: 'Another reason for doing something I hate creating fake data', + }, + ], + }, +]; diff --git a/frontend/styles/line.css b/frontend/styles/line.css index bd8c37f41..386006260 100644 --- a/frontend/styles/line.css +++ b/frontend/styles/line.css @@ -15,17 +15,30 @@ margin: 0px 8px; } - .toggle-checkbox:checked { - right: 0; - border-color: #24a0ed; - } + right: 0; + border-color: #24a0ed; +} .toggle-checkbox:checked + .toggle-label { background-color: #24a0ed; } - .chart-label { - transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.icon-speech-blue > svg > path { + fill: #3b82f6; +} +.icon-xcircle-red > svg > g { + stroke: #ef4444; } +.tooltip .tooltiptext { + visibility: hidden; + position: absolute; + z-index: 1; +} +.tooltip:hover .tooltiptext { + visibility: visible; +} diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 778d68385..e7e52fbb0 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -10,6 +10,8 @@ module.exports = { 'osoc-yellow': '#FCB70F', 'osoc-green': '#44DBA4', 'osoc-red': '#F14A3B', + 'osoc-bg': '#86efac', + 'osoc-neutral-bg': '#fafafa', 'osoc-btn-primary': '#1DE1AE' }, }, From 131f864492a2b7493b752633e8257ee859aa54af Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 9 Apr 2022 22:35:11 +0200 Subject: [PATCH 08/91] feat: finish mobile layout --- frontend/components/StudentSidebar.tsx | 49 ++++++++----- frontend/components/projects/ProjectTile.tsx | 2 +- frontend/pages/projects.tsx | 72 ++++++++++++++------ 3 files changed, 85 insertions(+), 38 deletions(-) diff --git a/frontend/components/StudentSidebar.tsx b/frontend/components/StudentSidebar.tsx index b096e0e9e..d8842aacd 100644 --- a/frontend/components/StudentSidebar.tsx +++ b/frontend/components/StudentSidebar.tsx @@ -12,12 +12,12 @@ const StudentSidebar: React.FC = () => { const [showFilter, setShowFilter] = useState(true); return ( // TODO test with a long list for autoscroll etc this should be separate from projects scroll -
- {/* holds searchbar + hide filter button */} -
+ // holds searchbar + hide filter button +
+
{/* The students searchbar */} -
-
+
+
= () => { {/* Show/hide filter button */} -
-
@@ -102,7 +103,7 @@ const StudentSidebar: React.FC = () => { className="toggle-label block h-5 cursor-pointer overflow-hidden rounded-full border-2 border-gray-300 bg-white" />
-
@@ -120,7 +121,7 @@ const StudentSidebar: React.FC = () => { className="toggle-label block h-5 cursor-pointer overflow-hidden rounded-full border-2 border-gray-300 bg-white" />
-
@@ -138,7 +139,7 @@ const StudentSidebar: React.FC = () => { className="toggle-label block h-5 cursor-pointer overflow-hidden rounded-full border-2 border-gray-300 bg-white" />
-
@@ -147,17 +148,29 @@ const StudentSidebar: React.FC = () => {

Filter on status

{/* holds the filter buttons */} -
- - - - +
+
+ + +
+
+ + +
{/* These are the student tiles */} -
+
); }; diff --git a/frontend/components/projects/ProjectTile.tsx b/frontend/components/projects/ProjectTile.tsx index e4519d4f2..cbbbbfe7f 100644 --- a/frontend/components/projects/ProjectTile.tsx +++ b/frontend/components/projects/ProjectTile.tsx @@ -52,7 +52,7 @@ type AssignmentProp = { const ProjectTile: React.FC = ({ project }: ProjectProp) => { return ( -
+
{/* project info top */}
{/* left part of header */} diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx index 9539a0284..87b65c4f6 100644 --- a/frontend/pages/projects.tsx +++ b/frontend/pages/projects.tsx @@ -2,10 +2,13 @@ import type { NextPage } from 'next'; import Header from '../components/Header'; import StudentSidebar from '../components/StudentSidebar'; import ProjectTiles from '../components/projects/ProjectTiles'; - +import { Icon } from '@iconify/react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons'; +import { useState } from 'react'; const magnifying_glass = ; +const arrow_out = ; +const arrow_in = ; // Header // @@ -22,32 +25,63 @@ const magnifying_glass = ; // assigned people list const Projects: NextPage = () => { + const [showSidebar, setShowSidebar] = useState(false); + return (
{/* Holds the sidebar with search, filter and student results */} - +
+ {/* button to close sidebar on mobile */} +
+ setShowSidebar(!showSidebar)}>{arrow_in} +
+ +
{/* Holds the projects searchbar + project tiles */} -
- {/* This is the projects searchbar */} -
-
- - {/* TODO add actual onclick search */} - } - > - {magnifying_glass} - +
+
+ {/* button to open sidebar on mobile */} +
+ setShowSidebar(!showSidebar)}>{arrow_out} +
+ + {/* This is the projects searchbar */} +
+
+ + {/* TODO add actual onclick search */} + } + > + {magnifying_glass} + +
From 9fc1e76b37380ceb68cd9bf4d5cbc45eed1be510 Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 9 Apr 2022 22:43:22 +0200 Subject: [PATCH 09/91] chore: fix search bar layout overflow --- frontend/components/StudentSidebar.tsx | 2 +- frontend/pages/projects.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/components/StudentSidebar.tsx b/frontend/components/StudentSidebar.tsx index d8842aacd..c6b863d32 100644 --- a/frontend/components/StudentSidebar.tsx +++ b/frontend/components/StudentSidebar.tsx @@ -40,7 +40,7 @@ const StudentSidebar: React.FC = () => { type="submit" onClick={() => setShowFilter(!showFilter)} > - Hide Filters + {showFilter ? 'Hide Filters' : 'Show Filters'}
diff --git a/frontend/pages/projects.tsx b/frontend/pages/projects.tsx index 87b65c4f6..84c728608 100644 --- a/frontend/pages/projects.tsx +++ b/frontend/pages/projects.tsx @@ -28,7 +28,7 @@ const Projects: NextPage = () => { const [showSidebar, setShowSidebar] = useState(false); return ( -
+
@@ -55,7 +55,7 @@ const Projects: NextPage = () => { showSidebar ? 'hidden' : 'visible' } mt-[30px] w-full flex-initial md:visible md:block md:w-[calc(100%-350px)] lg:w-[calc(100%-450px)] xl:w-2/3 2xl:w-[70%]`} > -
+
{/* button to open sidebar on mobile */}
{
{/* This is the projects searchbar */} -
+
Date: Sat, 9 Apr 2022 23:49:01 +0200 Subject: [PATCH 10/91] feat: start student + add fake tally data --- frontend/components/student/StudentView.tsx | 193 ++++++++++++++++++++ frontend/pages/students.tsx | 118 ++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 frontend/components/student/StudentView.tsx create mode 100644 frontend/pages/students.tsx diff --git a/frontend/components/student/StudentView.tsx b/frontend/components/student/StudentView.tsx new file mode 100644 index 000000000..f26184e64 --- /dev/null +++ b/frontend/components/student/StudentView.tsx @@ -0,0 +1,193 @@ +export type Student = { + id: string; + firstName: string; + lastName: string; + status: string; + statusSuggestions: StatusSuggestion[]; + alumn: boolean; + tallyForm: TallyForm; +}; + +type StatusSuggestion = { + coachId: string; + status: string; + motivation: string; +}; + +// this is bad mkay +type TallyForm = { + livingBelgium: boolean, + workTime: number, // 1-4 cba this + workJuly: boolean, + responsibilities: string, + birthName: string, + lastName: string, + // different name whatever + gender: string, + // pronouns stuff + language: string, + englishLevel: number, // 1-5 + phoneNumber: string, + email: string, + // Skipping cv, portfolio, motivation + studies: string[], + diploma: string, + diplomaYears: string, + diplomaYear: string, + school: string, + role: string[], + bestSkill: string, + participated: boolean, + studentCoach: boolean +} + +type StudentProp = { + student: Student; +}; + +const StudentView: React.FC = ({ student }: StudentProp) => { + return ( +
+ +
+ ); +}; + +export default StudentView; + + + +/* +Practical Questions + +Will you live in Belgium in july 2022 yes/no + +Are you able to work 128 hours with a student employment agreement, or as a volunteer? + yes, I can work with a student employment agreement in Belgium + yes, I can work as a volunteer in Belgium + No, but I would like to join this experience for free + No, I won't be able to work as a student, as a volunteer or for free + +Can you work during the month of July, Monday through Thursday (~09:00 to 17:00)? + yes + no, I wouldn't be able to work for the majority of days + +Are there any responsibilities you might have which could hinder you during the day? + open field question, can be empty + + + +Personal details + +Birth name +Last name + +Would you like to be called by a different name than your birth name? + no + yes -> new field + How would you like to be called? + open text field + +What is your gender? + female + male + transgender + rather not say + +Would you like to add your pronouns? + no + yes -> new question + Which pronouns do you prefer? + she/her/hers + he/him/his + they/them/their + ze/hir/hir + by firstname + by call name + other -> new open field question + Enter your pronouns + +What language are you most fluent in? + Dutch + English + French + German + Other -> new open field question + What language are you most fluent in? + +How would you rate your English? + * + ** + .. + ***** + +Phone number + open field + +Your email address + open field + + + +About you + +CV upload / link +portfolio upload / link +motivation upload / link + +Add a fun fact about yourself + open text field + + + +Studies & Experience + +What do/did you study? (max 2) + Backend development + Business management + Communication Sciences + Computer Sciences + Design + Frontend development + Marketing + Photography + Videography + Other -> new open text field + +What kind of diploma are you currently going for? (one max) + A professional Bachelor + An academic Bachelor + An associate degree + A master's degree + Doctoral degree + No diploma, I am self taught + Other -> new open text field + +How many years does your degree take?µ + open text field + +Which year of your degree are you in? + +What is the name of your college or university? + +Which role are you applying for? (max 2) + Front-end developer + Back-end developer + UX / UI designer + Graphic designer + Business Modeller + Storyteller + Marketer + Copywriter + Video editor + Photographer + Other -> new open text field + +Which skill would you list as your best one? + open text field + +Have you participated in osoc before? + no + yes -> Would you like to be a student coach this year? + yes / no + */ diff --git a/frontend/pages/students.tsx b/frontend/pages/students.tsx new file mode 100644 index 000000000..0f685a0d2 --- /dev/null +++ b/frontend/pages/students.tsx @@ -0,0 +1,118 @@ +import type { NextPage } from 'next'; +import Header from '../components/Header'; +import StudentSidebar from '../components/StudentSidebar'; +import StudentView from "../components/student/StudentView"; +import { Icon } from '@iconify/react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons'; +import { useState } from 'react'; +const magnifying_glass = ; +const arrow_out = ; +const arrow_in = ; + +const Students: NextPage = () => { + const [showSidebar, setShowSidebar] = useState(false); + + return ( +
+
+ +
+ {/* Holds the sidebar with search, filter and student results */} +
+ {/* button to close sidebar on mobile */} +
+ setShowSidebar(!showSidebar)}>{arrow_in} +
+ +
+ + {/* */} +
+
+ {/* button to open sidebar on mobile */} +
+ setShowSidebar(!showSidebar)}>{arrow_out} +
+
+ + {/* This contains the actual student info */} +
+ +
+ +
+
+
+ ); +}; + +export default Students; + +// Temporary fake data to test with +const student = + { + id: '1', + firstName: 'FNaam1', + lastName: 'LNaam1', + status: 'Undecided', + statusSuggestions: [ + { + coachId: '100', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '101', + status: 'Yes', + motivation: 'Dit is een motivatie voor yes', + }, + { + coachId: '102', + status: 'No', + motivation: 'Dit is een motivatie voor no', + }, + ], + alumn: true, + tallyForm: { + livingBelgium: true, + workTime: 1, // 1-4 cba this + workJuly: true, + responsibilities: "ik moet shit doen of niet of wel idk", + birthName: "naam", + lastName: "andere naam", + // different name whatever + gender: "male", + // pronouns stuff + language: "typescript of niet dan", + englishLevel: 5, // 1-5 + phoneNumber: "0800999999", + email: "paardenlover123@hotmail.be", + // Skipping cv, portfolio, motivation + studies: ["Photography", "Videography"], + diploma: "No diploma, I am self taught", + diplomaYears: "0", + diplomaYear: "0", + school: "self taught", + role: ["Video editor", "Photographer"], + bestSkill: "Marketer", + participated: true, + studentCoach: true + } + } \ No newline at end of file From c5cc88500723d5a29dbc1787090618932f8b67df Mon Sep 17 00:00:00 2001 From: Michael M Date: Sun, 10 Apr 2022 15:03:21 +0200 Subject: [PATCH 11/91] chore: saving stuff before doing pr's --- frontend/components/student/StudentView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/components/student/StudentView.tsx b/frontend/components/student/StudentView.tsx index f26184e64..ea85c3924 100644 --- a/frontend/components/student/StudentView.tsx +++ b/frontend/components/student/StudentView.tsx @@ -47,7 +47,10 @@ type StudentProp = { const StudentView: React.FC = ({ student }: StudentProp) => { return ( -
+
+
+

{student.tallyForm.birthName + " " + student.tallyForm.lastName}

+
); From b93e1e5189dbe1a269ee9e50021b2cd2f2638fac Mon Sep 17 00:00:00 2001 From: Michael M Date: Sun, 10 Apr 2022 17:57:58 +0200 Subject: [PATCH 12/91] feat: add student suggestion controls, fix mobile, fix dropdown --- frontend/components/StudentSidebar.tsx | 112 +++++++-- frontend/components/student/StudentView.tsx | 244 +++++++++++++++---- frontend/components/students/StudentTile.tsx | 11 +- frontend/package.json | 1 + frontend/pages/students.tsx | 193 +++++++-------- frontend/tailwind.config.js | 6 +- frontend/yarn.lock | 5 + 7 files changed, 398 insertions(+), 174 deletions(-) diff --git a/frontend/components/StudentSidebar.tsx b/frontend/components/StudentSidebar.tsx index c6b863d32..b8d463cee 100644 --- a/frontend/components/StudentSidebar.tsx +++ b/frontend/components/StudentSidebar.tsx @@ -1,13 +1,14 @@ -import { PropsWithChildren, useState } from 'react'; +import { Fragment, PropsWithChildren, useState } from 'react'; import StudentTiles from './students/StudentTiles'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons'; +import { Menu, Transition } from '@headlessui/react'; +import { ChevronDownIcon } from '@heroicons/react/solid'; const magnifying_glass = ; type StudentsSidebarProps = PropsWithChildren; // TODO no actual functionality implemented yet -// TODO fix mobile view const StudentSidebar: React.FC = () => { const [showFilter, setShowFilter] = useState(true); return ( @@ -36,7 +37,7 @@ const StudentSidebar: React.FC = () => { {/* Show/hide filter button */} + {/* These are the actual dropdown options */} + +
+ + {({ active }) => ( +

+ opt1 +

+ )} +
+ + {({ active }) => ( +

+ opt2 +

+ )} +
+ + {({ active }) => ( +

+ opt3 +

+ )} +
+ {/* Don't know what type this dropdown menu will end up being yet */} + {/*
*/} + {/* */} + {/* {({ active }) => (*/} + {/* */} + {/* Sign out*/} + {/* */} + {/* )}*/} + {/* */} + {/*
*/} +
+
+ + + + +
+