-
Notifications
You must be signed in to change notification settings - Fork 26
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
Builds the usability survey page #315
base: main
Are you sure you want to change the base?
Changes from 15 commits
5abb9e3
8d21a8c
508de77
b84a33e
9c97e22
3e7ddcd
e47880b
f1d804a
2f72073
ffe4e88
55134f5
4e05982
b95eafb
70795b6
09fd893
f2acb95
6259a49
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,37 @@ | ||
import { FC } from "react" | ||
import { Button, HStack } from "@threshold-network/components" | ||
import { range } from "../utils/range" | ||
import { StackProps } from "@chakra-ui/react" | ||
import { ThemeTypings } from "@chakra-ui/styled-system" | ||
|
||
interface NumberButtonSequenceProps extends StackProps { | ||
numberOfButtons: number | ||
selectedButtonNum?: number | ||
onButtonClick: (n: number) => void | ||
size?: ThemeTypings["components"]["Button"]["sizes"] | ||
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 think we can |
||
} | ||
|
||
const NumberButtonSequence: FC<NumberButtonSequenceProps> = ({ | ||
numberOfButtons, | ||
selectedButtonNum, | ||
onButtonClick, | ||
size, | ||
...props | ||
}) => { | ||
return ( | ||
<HStack spacing={1} {...props}> | ||
{range(numberOfButtons, 1).map((n) => ( | ||
<Button | ||
size={size} | ||
variant="sequence" | ||
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. Let's bump the 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. @r-czajkowski doesn't the |
||
isActive={n === selectedButtonNum} | ||
onClick={() => onButtonClick(n)} | ||
> | ||
{n} | ||
</Button> | ||
))} | ||
</HStack> | ||
) | ||
} | ||
|
||
export default NumberButtonSequence |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React, { FC } from "react" | ||
import { BodyMd, LabelSm, Box } from "@threshold-network/components" | ||
import { Row, RowID, RowValue } from "./types" | ||
import NumberButtonSequence from "../../../components/NumberButtonSequence" | ||
import { columns } from "./index" | ||
|
||
const MobileSurvey: FC<{ | ||
rows: Row[] | ||
handleRadioClick: (rowId: RowID, value: RowValue) => void | ||
}> = ({ rows, handleRadioClick }) => { | ||
return ( | ||
<> | ||
<Box display="flex" justifyContent={"space-between"} px={8} py={6}> | ||
<Box> | ||
<LabelSm>Strongly Disagree: 1</LabelSm> | ||
<LabelSm>Disagree: 2</LabelSm> | ||
<LabelSm>Neutral: 3</LabelSm> | ||
</Box> | ||
<Box> | ||
<LabelSm>Agree: 4</LabelSm> | ||
<LabelSm>Strongly Agree: 5</LabelSm> | ||
</Box> | ||
</Box> | ||
{rows.map((row, i) => { | ||
return ( | ||
<Box bg={i % 2 == 0 ? "gray.50" : undefined} px={8} py={6}> | ||
<BodyMd mb={6}>{row.text}</BodyMd> | ||
<NumberButtonSequence | ||
justifyContent="space-between" | ||
numberOfButtons={columns.length} | ||
selectedButtonNum={columns.findIndex((v) => v === row.value) + 1} | ||
onButtonClick={(value) => | ||
handleRadioClick(row.id, columns[value - 1]) | ||
} | ||
/> | ||
</Box> | ||
) | ||
})} | ||
</> | ||
) | ||
} | ||
|
||
export default MobileSurvey |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import React, { FC } from "react" | ||
import { | ||
Button, | ||
Table, | ||
Tbody, | ||
Td, | ||
Th, | ||
Thead, | ||
Tr, | ||
} from "@threshold-network/components" | ||
import { Row, RowID, RowValue } from "./types" | ||
import { useColorModeValue } from "@chakra-ui/react" | ||
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. Let's import from |
||
import { columns } from "./index" | ||
|
||
const firstColWidth = { | ||
base: "200px", | ||
xl: "300px", | ||
} | ||
|
||
const TableSurvey: FC<{ | ||
rows: Row[] | ||
handleRadioClick: (rowId: RowID, value: RowValue) => void | ||
}> = ({ rows, handleRadioClick }) => { | ||
const s = { | ||
py: 6, | ||
borderColor: useColorModeValue("gray.50", "gray.700"), | ||
} | ||
|
||
return ( | ||
<> | ||
<Table sx={{ tableLayout: "fixed" }}> | ||
<Thead> | ||
<Tr> | ||
<Th {...s} width={firstColWidth}> | ||
Question | ||
</Th> | ||
<Th {...s}>Strongly Disagree</Th> | ||
<Th {...s}>Disagree</Th> | ||
<Th {...s}>Neutral</Th> | ||
<Th {...s}>Agree</Th> | ||
<Th {...s}>Strongly Agree</Th> | ||
</Tr> | ||
</Thead> | ||
</Table> | ||
|
||
{/* TODO: Implement pagination */} | ||
{rows.map((row, i) => { | ||
return ( | ||
<Table sx={{ tableLayout: "fixed" }} key={row.text}> | ||
<Tbody> | ||
<Tr | ||
bg={ | ||
i % 2 == 0 | ||
? useColorModeValue("gray.50", "gray.700") | ||
: undefined | ||
} | ||
{...s} | ||
> | ||
<Td {...s} width={firstColWidth}> | ||
{row.text} | ||
</Td> | ||
{columns.map((value, i) => ( | ||
<Td {...s}> | ||
<Button | ||
variant="sequence" | ||
isActive={row.value === value} | ||
onClick={() => handleRadioClick(row.id, value)} | ||
> | ||
{i + 1} | ||
</Button> | ||
</Td> | ||
))} | ||
</Tr> | ||
</Tbody> | ||
</Table> | ||
) | ||
})} | ||
</> | ||
) | ||
} | ||
|
||
export default TableSurvey |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,106 @@ | ||
import React from "react" | ||
import { Box } from "@threshold-network/components" | ||
import React, { useState } from "react" | ||
import { Button, Divider, Card, H5 } from "@threshold-network/components" | ||
import { PageComponent } from "../../../types" | ||
import { Row, RowID, RowValue } from "./types" | ||
import TableSurvey from "./TableSurvey" | ||
import MobileSurvey from "./MobileSurvey" | ||
import useChakraBreakpoint from "../../../hooks/useChakraBreakpoint" | ||
|
||
export const columns: RowValue[] = [ | ||
RowValue.StrongDisagree, | ||
RowValue.Disagree, | ||
RowValue.Neutral, | ||
RowValue.Agree, | ||
RowValue.StronglyAgree, | ||
] | ||
|
||
const UsabilitySurvey: PageComponent = () => { | ||
return <Box>Usability survey page</Box> | ||
const [rows, setRows] = useState<Row[]>([ | ||
{ | ||
id: RowID.FrequentUsage, | ||
text: "I think that I would like to use this product frequently.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.UnnecessarilyComplex, | ||
text: "I found the product unnecessarily complex.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.EasyToUse, | ||
text: "I thought the product was easy to use.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.NeedTechnicalSupportPerson, | ||
text: "I think I would need the support of a technical person to be able to use this product.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.WellIntegratedFunctions, | ||
text: "I found the various functions in this product well integrated.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.TooMuchInconsistency, | ||
text: "I thought there was too much inconsistency in the product.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.QuickToLearn, | ||
text: "I would imagine that most people would learn to use this product very quickly.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.InconvenientToUse, | ||
text: "I found the product inconvenient to use.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.Confident, | ||
text: "I felt very confident using the product.", | ||
value: undefined, | ||
}, | ||
{ | ||
id: RowID.HighLearningCurve, | ||
text: "I need to learn a lot of things before I could get going with the product.", | ||
value: undefined, | ||
}, | ||
]) | ||
|
||
const handleRadioClick = (rowId: RowID, value: RowValue) => { | ||
setRows((rows) => | ||
rows.map((row) => (row.id === rowId ? { ...row, value } : row)) | ||
) | ||
} | ||
|
||
const handleSubmit = () => { | ||
const payload = rows.map(({ id, value }) => ({ | ||
id, | ||
value, | ||
})) | ||
|
||
console.log("Payload ", payload) | ||
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. Do we need 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 can remove it. just added to prevent an unused var warning. I still need to implement the post function, but waiting for code from other branches. |
||
// TODO: Implement post to survey data tracking source | ||
} | ||
|
||
const isSmallScreen = useChakraBreakpoint("xl") | ||
|
||
return ( | ||
<Card> | ||
<H5 mb={8}>Overall Product Usability Score</H5> | ||
<Divider mb={4} /> | ||
{isSmallScreen ? ( | ||
<MobileSurvey rows={rows} handleRadioClick={handleRadioClick} /> | ||
) : ( | ||
<TableSurvey rows={rows} handleRadioClick={handleRadioClick} /> | ||
)} | ||
|
||
<Button mt={4} onClick={handleSubmit} isFullWidth={isSmallScreen}> | ||
Submit Survey | ||
</Button> | ||
</Card> | ||
) | ||
} | ||
|
||
UsabilitySurvey.route = { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
export interface Row { | ||
id: RowID | ||
text: string | ||
value?: RowValue | ||
} | ||
|
||
export enum RowValue { | ||
StrongDisagree = "STRONGLY_DISAGREE", | ||
Disagree = "DISAGREE", | ||
Neutral = "NEUTRAL", | ||
Agree = "AGREE", | ||
StronglyAgree = "STRONGLY_AGREE", | ||
} | ||
|
||
export enum RowID { | ||
FrequentUsage = "FREQUENT_USAGE", | ||
UnnecessarilyComplex = "UNNECESSARILY_COMPLEX", | ||
EasyToUse = "EASY_TO_USE", | ||
NeedTechnicalSupportPerson = "NEED_TECHNICAL_SUPPORT_PERSON", | ||
WellIntegratedFunctions = "WELL_INTEGRATED_FUNCTIONS", | ||
TooMuchInconsistency = "TOO_MUCH_INCONSISTENCY", | ||
QuickToLearn = "QUICK_TO_LEARN", | ||
InconvenientToUse = "INCONVENIENT_TO_USE", | ||
Confident = "CONFIDENT", | ||
HighLearningCurve = "HIGH_LEARNING_CURVE", | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const range = (size: number, startAt = 0) => { | ||
return Array.from(Array(size).keys()).map((i) => i + startAt) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we import from
@threshold-network/components
?