diff --git a/components/IssueComparison.css.ts b/components/IssueComparison.css.ts index a8c4937..81d9ff6 100644 --- a/components/IssueComparison.css.ts +++ b/components/IssueComparison.css.ts @@ -7,9 +7,11 @@ export const header = style({ }); export const main = style({ + alignItems: "start", columnGap: 20, display: "grid", - gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1fr)", + gridAutoColumns: "minmax(0, 1fr)", + gridAutoFlow: "column", padding: "20px 20px 150px", rowGap: 20, }); @@ -17,13 +19,26 @@ export const main = style({ export const footer = style({ background: theme.color.background, bottom: 0, + left: "10rem", + padding: "30px 0", + position: "fixed", + right: 0, + rowGap: 20, + display: "grid", +}); + +export const buttons = style({ columnGap: 20, display: "grid", + gridAutoColumns: "minmax(0, 1fr)", gridAutoFlow: "column", - gridTemplateColumns: "1fr 1fr 1fr", justifyItems: "center", - left: "10rem", - padding: "50px 0", - position: "fixed", - right: 0, +}); + +export const submit = style({ + display: "grid", + placeItems: "center", + gridAutoFlow: "column", + columnGap: 20, + justifyContent: "center", }); diff --git a/components/IssueComparison.tsx b/components/IssueComparison.tsx index 6d691b8..de0dc8e 100644 --- a/components/IssueComparison.tsx +++ b/components/IssueComparison.tsx @@ -1,67 +1,84 @@ -import { ReactNode } from "react"; +import { ReactNode, useState } from "react"; import { Context } from "../utils/AppContext"; import { IssueDetail } from "../utils/linear"; import useIssues from "../utils/useIssues"; import IssueCard from "./IssueCard"; -import { footer, header, main } from "./IssueComparison.css"; +import { buttons, footer, header, main, submit } from "./IssueComparison.css"; type Props = { context: Context; localStorageKey: string; title: ReactNode; - buttonLabel: (issue: IssueDetail) => string; + firstButtonLabel: (issue: IssueDetail) => string; + successiveButtonLabel: (issue: IssueDetail) => string; }; const IssueComparison = ({ context, localStorageKey, title, - buttonLabel, + firstButtonLabel, + successiveButtonLabel, }: Props) => { - const { issueA, issueB, addComparison, loadIssues } = useIssues( + const { issueList, addComparison, loadIssues } = useIssues( context.credentials, context.data.issues, localStorageKey ); - return issueA && issueB ? ( + const [order, setOrder] = useState>([]); + + return issueList.length > 0 ? ( <>

{title}

- - + {issueList.map((issue) => ( + + ))}
-
- +
+ {issueList.map((issue) => + order.includes(issue.id) ? ( + {order.indexOf(issue.id) + 1} + ) : ( + + ) + )}
-
+
-
-
diff --git a/pages/effort.page.tsx b/pages/effort.page.tsx index 4028793..3886de9 100644 --- a/pages/effort.page.tsx +++ b/pages/effort.page.tsx @@ -32,7 +32,10 @@ const EffortPage: NextPage = () => { )? } - buttonLabel={(issue) => `${issue.identifier} is quickest`} + firstButtonLabel={(issue) => `${issue.identifier} is quickest`} + successiveButtonLabel={(issue) => + `${issue.identifier} is next quickest` + } /> ); diff --git a/pages/value.page.tsx b/pages/value.page.tsx index dd22ae7..4bbc284 100644 --- a/pages/value.page.tsx +++ b/pages/value.page.tsx @@ -1,10 +1,8 @@ import type { NextPage } from "next"; import { useContext } from "react"; -import IssueCard from "../components/IssueCard"; import IssueComparison from "../components/IssueComparison"; import Layout from "../components/Layout"; import AppContext from "../utils/AppContext"; -import useIssues from "../utils/useIssues"; const ValuePage: NextPage = () => { const context = useContext(AppContext); @@ -26,7 +24,12 @@ const ValuePage: NextPage = () => { first? } - buttonLabel={(issue) => `${issue.identifier} should be resolved first`} + firstButtonLabel={(issue) => + `${issue.identifier} should be resolved first` + } + successiveButtonLabel={(issue) => + `${issue.identifier} should be resolved next` + } /> ); diff --git a/utils/useIssues.ts b/utils/useIssues.ts index 9a201eb..e769fea 100644 --- a/utils/useIssues.ts +++ b/utils/useIssues.ts @@ -12,43 +12,49 @@ const useIssues = ( ) => { const alive = useRef(false); - const [issueA, setIssueA] = useState(null); - const [issueB, setIssueB] = useState(null); + const [issueList, setIssueList] = useState>([]); const loadIssues = useCallback(async () => { - setIssueA(null); - setIssueB(null); + setIssueList([]); const stats = getStats(issues, localStorageKey); if (issues.length > 1) { - const idA = weightedRandomPick( - [...issues.map(({ id }) => id)].sort( - (a, b) => stats[a].comparisons - stats[b].comparisons - ), - 8 - ); + const ids: Array = []; - const idB = weightedRandomPick( - [...issues.map(({ id }) => id)] - .filter((x) => x !== idA) - .sort( - (a, b) => - Math.abs(stats[idA].rating - stats[a].rating) - - Math.abs(stats[idA].rating - stats[b].rating) + ids.push( + weightedRandomPick( + [...issues.map(({ id }) => id)].sort( + (a, b) => stats[a].comparisons - stats[b].comparisons ), - 2 + 8 + ) ); - const a = await getIssue(credentials, idA); - const b = await getIssue(credentials, idB); + for (let i = 0; i < 3; i++) { + ids.push( + weightedRandomPick( + [...issues.map(({ id }) => id)] + .filter((x) => !ids.includes(x)) + .sort( + (a, b) => + Math.abs(stats[ids[0]].rating - stats[a].rating) - + Math.abs(stats[ids[0]].rating - stats[b].rating) + ), + 2 + ) + ); + } + + const newIssues: Array = await Promise.all( + ids.map((id) => getIssue(credentials, id)) + ); if (alive.current) { - setIssueA(a); - setIssueB(b); + setIssueList(newIssues); } } - }, [credentials, issues, setIssueA, setIssueB, localStorageKey]); + }, [credentials, issues, localStorageKey]); const addComparison = (entities: [string, string], result: number) => { const comparisons: EloTournament["comparisons"] = JSON.parse( @@ -67,9 +73,8 @@ const useIssues = ( }, [alive, issues, loadIssues]); return { - issueA, - issueB, addComparison, + issueList, loadIssues, }; };