Skip to content
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

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/components/NumberButtonSequence.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { FC } from "react"
import { Button, HStack, StackProps } from "@threshold-network/components"
import { range } from "../utils/range"
import { ButtonProps } from "@chakra-ui/react"

interface NumberButtonSequenceProps extends StackProps {
numberOfButtons: number
selectedButtonNum?: number
onButtonClick: (n: number) => void
size?: ButtonProps["size"]
}

const NumberButtonSequence: FC<NumberButtonSequenceProps> = ({
numberOfButtons,
selectedButtonNum,
onButtonClick,
size,
...props
}) => {
return (
<HStack spacing={1} {...props}>
{range(numberOfButtons, 1).map((n) => (
<Button
size={size}
variant="sequence"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's bump the components package- the PR that adds new variant has been merged threshold-network/components#37.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@r-czajkowski doesn't the development version cover this case? Is it just a yarn.lock update we need? or do you suggest we install "@threshold-network/components": "^1.0.0-dev.0",?

isActive={n === selectedButtonNum}
onClick={() => onButtonClick(n)}
>
{n}
</Button>
))}
</HStack>
)
}

export default NumberButtonSequence
43 changes: 43 additions & 0 deletions src/pages/Feedback/UsabilitySurvey/MobileSurvey.tsx
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
82 changes: 82 additions & 0 deletions src/pages/Feedback/UsabilitySurvey/TableSurvey.tsx
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,
useColorModeValue,
} from "@threshold-network/components"
import { Row, RowID, RowValue } from "./types"
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
101 changes: 98 additions & 3 deletions src/pages/Feedback/UsabilitySurvey/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,104 @@
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,
// }))
// 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 = {
Expand Down
26 changes: 26 additions & 0 deletions src/pages/Feedback/UsabilitySurvey/types.ts
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",
}
1 change: 1 addition & 0 deletions src/theme/Radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PartsStyleFunction } from "@chakra-ui/theme-tools"
const baseStyle: PartsStyleFunction<typeof radioAnatomy> = () => {
return {
control: {
backgroundColor: "white",
_checked: {
backgroundColor: "brand.500",
_hover: {
Expand Down
3 changes: 3 additions & 0 deletions src/utils/range.ts
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)
}
Loading