-
Notifications
You must be signed in to change notification settings - Fork 7
#377 Competencies page should display previous reflections table #408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 19 commits
80645b2
6c39bfb
9cebf66
e0d9ac0
d07cb8c
231c114
b0ec8ea
65b098e
980c54c
802be19
fc462a9
d00ee1a
8a477c4
81da9a7
357491a
cf5a8ad
1ef245c
3a909d0
0acc3ee
c5dac23
af569e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import React from 'react'; | ||
| import { | ||
| Table, | ||
| TableBody, | ||
| TableCell, | ||
| TableContainer, | ||
| TableHead, | ||
| TableRow, | ||
| Paper, | ||
| } from '@mui/material'; | ||
| import CompetenciesDetailTable from './CompetenciesDetailTable'; | ||
| import useApiData from '../helpers/useApiData'; | ||
| import { CompetenciesByCategory } from '../types/api'; | ||
|
|
||
| const CompetenciesCategoriesTable = () => { | ||
| const { data, isLoading, error } = useApiData<CompetenciesByCategory[]>({ | ||
| deps: [], | ||
| path: `/competencies/categories`, | ||
| sendCredentials: true, | ||
| }); | ||
| if (error) { | ||
| return <p>There was an error loading the competencies.</p>; | ||
| } | ||
| if (!data) { | ||
| return null; | ||
| } | ||
|
|
||
| return ( | ||
| <TableContainer component={Paper}> | ||
| <Table aria-label="collapsible table"> | ||
| <TableHead> | ||
| <TableRow | ||
| sx={{ | ||
| '& > *': { | ||
| fontWeight: 'bold !important', | ||
| textTransform: 'uppercase', | ||
| }, | ||
| }} | ||
| > | ||
| <TableCell sx={{ width: '5%' }} /> | ||
| <TableCell sx={{ width: '25%' }}>Category</TableCell> | ||
| <TableCell align="left">Summary</TableCell> | ||
| </TableRow> | ||
| </TableHead> | ||
| <TableBody> | ||
| {!isLoading && | ||
| data.map(({ id, label, description, competencies }) => ( | ||
| <CompetenciesDetailTable | ||
| key={id} | ||
| catgoryLabel={label} | ||
| categoryDescription={description} | ||
| competencies={competencies} | ||
| /> | ||
| ))} | ||
| </TableBody> | ||
| </Table> | ||
| </TableContainer> | ||
| ); | ||
| }; | ||
|
|
||
| export default CompetenciesCategoriesTable; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,191 @@ | ||
| import React from 'react'; | ||
| import { | ||
| Box, | ||
| Collapse, | ||
| IconButton, | ||
| Table, | ||
| TableBody, | ||
| TableCell, | ||
| TableHead, | ||
| TableRow, | ||
| Rating, | ||
| Tooltip, | ||
| } from '@mui/material'; | ||
| import { styled } from '@mui/material/styles'; | ||
| import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; | ||
| import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; | ||
| import CircleOutlinedIcon from '@mui/icons-material/CircleOutlined'; | ||
| import CircleIcon from '@mui/icons-material/Circle'; | ||
| import { Competency, Reflection } from '../types/api'; | ||
| import useApiData from '../helpers/useApiData'; | ||
| import { formatDate } from '../helpers/dateTime'; | ||
|
|
||
| export interface IBackgroundColor { | ||
| [key: string]: string; | ||
| } | ||
| export const categoryBackgroundColor: IBackgroundColor = { | ||
| Functional: '#CAE2FA', | ||
| Strategic: '#ffe59a', | ||
| Operational: '#b6d7a8', | ||
| Behavioural: '#b4a7d5', | ||
| Organizational: '#F7B8D7', | ||
| }; | ||
|
|
||
| const StyledRating = styled(Rating)({ | ||
| '& .MuiRating-iconFilled': { | ||
| color: '#42a5f5', | ||
| }, | ||
| }); | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and this line? |
||
| interface IRatingValue { | ||
| [key: string]: number; | ||
| } | ||
| const ratingValue: IRatingValue = { | ||
| Aware: 1, | ||
| Novice: 2, | ||
| Intermediate: 3, | ||
| Advanced: 4, | ||
| Expert: 5, | ||
| }; | ||
|
|
||
| interface DetailTableProps { | ||
| catgoryLabel: string; | ||
| categoryDescription: string; | ||
| competencies: Competency[]; | ||
| } | ||
|
|
||
| const CompetenciesDetailTable = ({ | ||
| catgoryLabel, | ||
| categoryDescription, | ||
| competencies, | ||
| }: DetailTableProps) => { | ||
| const [open, setOpen] = React.useState(false); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useState can directly be destructured in the import so that
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point! I changed code to import |
||
|
|
||
| const { data: reflections } = useApiData<Reflection[]>({ | ||
| deps: [], | ||
| path: '/reflections', | ||
| sendCredentials: true, | ||
| }); | ||
|
|
||
| return ( | ||
| <> | ||
| <TableRow | ||
| sx={{ | ||
| '& > *': { borderBottom: 'unset' }, | ||
| backgroundColor: categoryBackgroundColor[catgoryLabel], | ||
| }} | ||
| > | ||
| <TableCell> | ||
| <IconButton | ||
| aria-label="expand row" | ||
| size="small" | ||
| onClick={() => setOpen(!open)} | ||
| > | ||
| {open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />} | ||
| </IconButton> | ||
| </TableCell> | ||
| <TableCell component="th" scope="row"> | ||
| {catgoryLabel} | ||
| </TableCell> | ||
| <TableCell>{categoryDescription}</TableCell> | ||
| </TableRow> | ||
| <TableRow> | ||
| <TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}> | ||
| <Collapse in={open} timeout="auto" unmountOnExit> | ||
| <Box sx={{ margin: 1 }}> | ||
| <Table size="small"> | ||
| <TableHead> | ||
| <TableRow | ||
| sx={{ | ||
| '& > *': { | ||
| fontWeight: 'bold !important', | ||
| textTransform: 'uppercase', | ||
| }, | ||
| }} | ||
| > | ||
| <TableCell component="th" scope="row" sx={{ width: '20%' }}> | ||
| Name | ||
| </TableCell> | ||
| <TableCell>Definition</TableCell> | ||
| {reflections && | ||
| reflections | ||
| .filter(reflection => | ||
| reflection.responses.find(response => | ||
| competencies.find( | ||
| competency => | ||
| competency.label === | ||
| response.option.prompt.label | ||
| ) | ||
| ) | ||
| ) | ||
| .map(reflection => { | ||
| const reflectionCreatedAtDate = formatDate( | ||
| reflection.created_at | ||
| ); | ||
| return ( | ||
| <TableCell key={reflection.id} align="center"> | ||
| {reflectionCreatedAtDate} | ||
| </TableCell> | ||
| ); | ||
| })} | ||
| </TableRow> | ||
| </TableHead> | ||
| <TableBody> | ||
| {reflections && | ||
| competencies.map(competency => ( | ||
| <TableRow key={competency.id}> | ||
| <TableCell>{competency.label}</TableCell> | ||
| <TableCell>{competency.description}</TableCell> | ||
| {reflections | ||
| .filter(reflection => | ||
| reflection.responses.find(response => | ||
| competencies.find( | ||
| competency => | ||
| competency.label === | ||
| response.option.prompt.label | ||
| ) | ||
| ) | ||
| ) | ||
| .map(reflection => { | ||
| const response = reflection.responses.find( | ||
| response => | ||
| response.option.prompt.label === | ||
| competency.label | ||
| ); | ||
| if (response) { | ||
| return ( | ||
| <Tooltip | ||
| key={response.id} | ||
| title={response.option.label} | ||
| placement="top" | ||
| arrow | ||
| > | ||
| <TableCell align="center"> | ||
| <StyledRating | ||
| value={ratingValue[response.option.label]} | ||
| readOnly | ||
| icon={<CircleIcon />} | ||
| emptyIcon={<CircleOutlinedIcon />} | ||
| /> | ||
| </TableCell> | ||
| </Tooltip> | ||
| ); | ||
| } else { | ||
| return ( | ||
| <TableCell key={reflection.id}></TableCell> | ||
| ); | ||
| } | ||
| })} | ||
| </TableRow> | ||
| ))} | ||
| </TableBody> | ||
| </Table> | ||
| </Box> | ||
| </Collapse> | ||
| </TableCell> | ||
| </TableRow> | ||
| </> | ||
| ); | ||
| }; | ||
|
|
||
| export default CompetenciesDetailTable; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import React from 'react'; | ||
| import { Box, Container, Grid, Button } from '@mui/material'; | ||
|
|
||
|
achichikalova marked this conversation as resolved.
Outdated
|
||
| import CompetenciesCategoriesTable from './CompetenciesCategoriesTable'; | ||
|
|
||
| const CompetenciesView = () => { | ||
| return ( | ||
| <Container fixed> | ||
| <h1>Competencies</h1> | ||
| <Grid container justifyContent="center"> | ||
| <Grid item xs={12}> | ||
| <Box textAlign="center"> | ||
| <Button variant="contained" sx={{ my: 5 }}> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What page should the user be shown on clicking this "Take Assessment" button?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe it takes to the assessment page with five pictures ( |
||
| Take Assessment | ||
| </Button> | ||
| </Box> | ||
| <Box> | ||
| {/* The placeholder for the card with the rating instruction */} | ||
| </Box> | ||
| <Box> | ||
| <CompetenciesCategoriesTable /> | ||
| </Box> | ||
| </Grid> | ||
| </Grid> | ||
| </Container> | ||
| ); | ||
| }; | ||
|
|
||
| export default CompetenciesView; | ||
|
achichikalova marked this conversation as resolved.
|
||
Uh oh!
There was an error while loading. Please reload this page.