From 2e4e09ea17e3076e2819829a492e0e4f71243167 Mon Sep 17 00:00:00 2001 From: Camilo Vega <59750365+camilovegag@users.noreply.github.com> Date: Mon, 13 May 2024 07:12:17 -0500 Subject: [PATCH] 424 adjust berlin results page UI to match other pages (#441) * Create results columns * Add results columns to results page * Add icons * Create tables for results and stats * Fixes * Remove unused import * Update order * Comment code for plurality score at cycle * Remove unused code * Update columns and table dist --- packages/api/src/types/ForumQuestionType.ts | 1 + packages/berlin/public/icons/money-dark.svg | 3 + packages/berlin/public/icons/money-light.svg | 3 + packages/berlin/public/icons/sqrt-dark.svg | 3 + packages/berlin/public/icons/sqrt-light.svg | 3 + .../cycle-columns/CycleColumns.styled.tsx | 8 +- .../components/cycle-columns/CycleColumns.tsx | 6 +- .../option-card/OptionCard.styled.tsx | 8 +- .../src/components/option-card/OptionCard.tsx | 26 ++-- .../result-card/ResultCard.styled.tsx | 33 ++--- .../src/components/result-card/ResultCard.tsx | 114 ++++++------------ .../results-columns/ResultsColumns.styled.tsx | 8 ++ .../results-columns/ResultsColumns.tsx | 35 ++++++ .../src/components/results-columns/index.ts | 1 + .../components/stat-card/StatCard.styled.tsx | 11 -- .../src/components/stat-card/StatCard.tsx | 22 ---- .../berlin/src/components/stat-card/index.ts | 1 - .../stats-card/StatsCard.styled.tsx | 8 ++ .../src/components/stats-card/StatsCard.tsx | 18 +++ .../berlin/src/components/stats-card/index.ts | 1 + .../stats-columns/StatsColumns.styled.tsx | 8 ++ .../components/stats-columns/StatsColumns.tsx | 13 ++ .../src/components/stats-columns/index.ts | 1 + packages/berlin/src/pages/Comments.tsx | 13 +- packages/berlin/src/pages/Cycle.tsx | 13 +- packages/berlin/src/pages/Results.tsx | 24 ++-- 26 files changed, 198 insertions(+), 187 deletions(-) create mode 100644 packages/berlin/public/icons/money-dark.svg create mode 100644 packages/berlin/public/icons/money-light.svg create mode 100644 packages/berlin/public/icons/sqrt-dark.svg create mode 100644 packages/berlin/public/icons/sqrt-light.svg create mode 100644 packages/berlin/src/components/results-columns/ResultsColumns.styled.tsx create mode 100644 packages/berlin/src/components/results-columns/ResultsColumns.tsx create mode 100644 packages/berlin/src/components/results-columns/index.ts delete mode 100644 packages/berlin/src/components/stat-card/StatCard.styled.tsx delete mode 100644 packages/berlin/src/components/stat-card/StatCard.tsx delete mode 100644 packages/berlin/src/components/stat-card/index.ts create mode 100644 packages/berlin/src/components/stats-card/StatsCard.styled.tsx create mode 100644 packages/berlin/src/components/stats-card/StatsCard.tsx create mode 100644 packages/berlin/src/components/stats-card/index.ts create mode 100644 packages/berlin/src/components/stats-columns/StatsColumns.styled.tsx create mode 100644 packages/berlin/src/components/stats-columns/StatsColumns.tsx create mode 100644 packages/berlin/src/components/stats-columns/index.ts diff --git a/packages/api/src/types/ForumQuestionType.ts b/packages/api/src/types/ForumQuestionType.ts index 8b1a0ef6..c8cd09ee 100644 --- a/packages/api/src/types/ForumQuestionType.ts +++ b/packages/api/src/types/ForumQuestionType.ts @@ -13,6 +13,7 @@ export type GetForumQuestionStatisticsResponse = { optionSubTitle: string; distinctGroups: number; listOfGroupNames: string[]; + quadraticScore: string; } >; }; diff --git a/packages/berlin/public/icons/money-dark.svg b/packages/berlin/public/icons/money-dark.svg new file mode 100644 index 00000000..52386eca --- /dev/null +++ b/packages/berlin/public/icons/money-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/berlin/public/icons/money-light.svg b/packages/berlin/public/icons/money-light.svg new file mode 100644 index 00000000..361531ef --- /dev/null +++ b/packages/berlin/public/icons/money-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/berlin/public/icons/sqrt-dark.svg b/packages/berlin/public/icons/sqrt-dark.svg new file mode 100644 index 00000000..eb548d54 --- /dev/null +++ b/packages/berlin/public/icons/sqrt-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/berlin/public/icons/sqrt-light.svg b/packages/berlin/public/icons/sqrt-light.svg new file mode 100644 index 00000000..200a9ded --- /dev/null +++ b/packages/berlin/public/icons/sqrt-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/berlin/src/components/cycle-columns/CycleColumns.styled.tsx b/packages/berlin/src/components/cycle-columns/CycleColumns.styled.tsx index acfaa36c..49492176 100644 --- a/packages/berlin/src/components/cycle-columns/CycleColumns.styled.tsx +++ b/packages/berlin/src/components/cycle-columns/CycleColumns.styled.tsx @@ -53,7 +53,7 @@ export const Hearts = styled(FlexRow)` padding: 1.5rem; `; -export const Plurality = styled(FlexRow)` - max-width: 5.5rem; - padding: 1.5rem; -`; +// export const Plurality = styled(FlexRow)` +// max-width: 5.5rem; +// padding: 1.5rem; +// `; diff --git a/packages/berlin/src/components/cycle-columns/CycleColumns.tsx b/packages/berlin/src/components/cycle-columns/CycleColumns.tsx index c74d75f2..c277bd51 100644 --- a/packages/berlin/src/components/cycle-columns/CycleColumns.tsx +++ b/packages/berlin/src/components/cycle-columns/CycleColumns.tsx @@ -1,6 +1,6 @@ import IconButton from '../icon-button'; import { Body } from '../typography/Body.styled'; -import { Affiliation, Author, Card, Hearts, Plurality, Proposal } from './CycleColumns.styled'; +import { Affiliation, Author, Card, Hearts, Proposal } from './CycleColumns.styled'; type CycleColumnsProps = { onColumnClick: (column: string) => void; @@ -25,13 +25,13 @@ function CycleColumns({ onColumnClick }: CycleColumnsProps) { icon={{ src: `/icons/heart-full.svg`, alt: 'Full heart' }} /> - onColumnClick('voteScore')}> + {/* onColumnClick('voteScore')}> - + */} ); } diff --git a/packages/berlin/src/components/option-card/OptionCard.styled.tsx b/packages/berlin/src/components/option-card/OptionCard.styled.tsx index 87ef6664..eb97a35f 100644 --- a/packages/berlin/src/components/option-card/OptionCard.styled.tsx +++ b/packages/berlin/src/components/option-card/OptionCard.styled.tsx @@ -45,7 +45,7 @@ export const Votes = styled(FlexRow)` padding: 1.5rem; `; -export const Plurality = styled(FlexRow)` - max-width: 5.5rem; - padding: 1.5rem; -`; +// export const Plurality = styled(FlexRow)` +// max-width: 5.5rem; +// padding: 1.5rem; +// `; diff --git a/packages/berlin/src/components/option-card/OptionCard.tsx b/packages/berlin/src/components/option-card/OptionCard.tsx index 071f8b65..70d32669 100644 --- a/packages/berlin/src/components/option-card/OptionCard.tsx +++ b/packages/berlin/src/components/option-card/OptionCard.tsx @@ -1,12 +1,12 @@ -import { useMemo, useState } from 'react'; -import { Body } from '../typography/Body.styled'; -import { Affiliation, Author, Card, Votes, Plurality, Proposal } from './OptionCard.styled'; -import { FlexColumn } from '../containers/FlexColum.styled'; -import IconButton from '../icon-button'; -import { useAppStore } from '../../store'; -import { FlexRow } from '../containers/FlexRow.styled'; import { QuestionOption } from 'api'; +import { useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; +import { useAppStore } from '../../store'; +import { FlexColumn } from '../containers/FlexColum.styled'; +import { FlexRow } from '../containers/FlexRow.styled'; +import IconButton from '../icon-button'; +import { Body } from '../typography/Body.styled'; +import { Affiliation, Author, Card, Proposal, Votes } from './OptionCard.styled'; type OptionCardProps = { option: QuestionOption; @@ -18,10 +18,10 @@ function OptionCard({ option, numOfVotes, onVote, onUnvote }: OptionCardProps) { const { eventId, cycleId } = useParams(); const theme = useAppStore((state) => state.theme); const navigate = useNavigate(); - const formattedPluralityScore = useMemo(() => { - const score = parseFloat(String(option.voteScore)); - return score % 1 === 0 ? score.toFixed(0) : score.toFixed(1); - }, [option.voteScore]); + // const formattedPluralityScore = useMemo(() => { + // const score = parseFloat(String(option.voteScore)); + // return score % 1 === 0 ? score.toFixed(0) : score.toFixed(1); + // }, [option.voteScore]); const [expanded, setExpanded] = useState(false); @@ -75,9 +75,9 @@ function OptionCard({ option, numOfVotes, onVote, onUnvote }: OptionCardProps) { {numOfVotes} - + {/* {formattedPluralityScore} - + */} {option.optionSubTitle && {option.optionSubTitle}} diff --git a/packages/berlin/src/components/result-card/ResultCard.styled.tsx b/packages/berlin/src/components/result-card/ResultCard.styled.tsx index 3709b353..3709fc20 100644 --- a/packages/berlin/src/components/result-card/ResultCard.styled.tsx +++ b/packages/berlin/src/components/result-card/ResultCard.styled.tsx @@ -1,37 +1,18 @@ import styled from 'styled-components'; +import { Grid } from '../containers/Grid.styled'; -export const Card = styled.article<{ $expanded: boolean }>` - border-radius: 1rem; - border: 1px solid var(--color-black); - color: var(--color-white); +export const Card = styled(Grid)<{ $expanded: boolean }>` cursor: pointer; + border-bottom: 1px solid var(--color-black); + grid-template-columns: auto repeat(3, 48px) 80px; overflow: hidden; - padding: 2rem; + padding: 1.5rem; position: relative; transition: height 0.3s ease-in-out; width: 100%; - .statistics { + .description { display: ${(props) => (props.$expanded ? 'flex' : 'none')}; - } -`; -export const Badge = styled.div<{ $type: 'gold' | 'silver' | 'bronze' }>` - align-items: center; - background-image: ${(props) => props.$type && `url('/icons/badge-${props.$type}.svg')`}; - background-position: center center; - background-repeat: no-repeat; - background-size: contain; - display: flex; - height: 2rem; - width: 2rem; -`; - -export const List = styled.ul` - list-style: none; -`; -export const ListItem = styled.li` - padding-left: 1rem; - &::before { - content: '• '; + grid-column: 1/6; } `; diff --git a/packages/berlin/src/components/result-card/ResultCard.tsx b/packages/berlin/src/components/result-card/ResultCard.tsx index 8b99160f..5dc9c98c 100644 --- a/packages/berlin/src/components/result-card/ResultCard.tsx +++ b/packages/berlin/src/components/result-card/ResultCard.tsx @@ -1,5 +1,5 @@ // React and third-party libraries -import { useMemo, useState } from 'react'; +import { useMemo } from 'react'; // Store import { useAppStore } from '../../store'; @@ -9,16 +9,13 @@ import { Body } from '../typography/Body.styled'; import { Bold } from '../typography/Bold.styled'; import { FlexColumn } from '../containers/FlexColum.styled'; import { FlexRow } from '../containers/FlexRow.styled'; -import { Subtitle } from '../typography/Subtitle.styled'; import IconButton from '../icon-button'; // Styled Components -import { Badge, Card, List, ListItem } from './ResultCard.styled'; -import { Separator } from '../separator'; +import { Card } from './ResultCard.styled'; type ResultCardProps = { $expanded: boolean; - index: number; option: { optionTitle: string; pluralityScore: string; @@ -27,92 +24,51 @@ type ResultCardProps = { optionSubTitle: string; distinctGroups: number; listOfGroupNames: string[]; + quadraticScore: string; id: string; }; onClick: () => void; }; -function ResultCard({ $expanded, option, index, onClick }: ResultCardProps) { - const [groupsExpanded, setGroupsExpanded] = useState(false); +function ResultCard({ $expanded, option, onClick }: ResultCardProps) { const theme = useAppStore((state) => state.theme); + + const formattedQuadraticScore = useMemo(() => { + const score = parseFloat(option.quadraticScore); + return score % 1 === 0 ? score.toFixed(0) : score.toFixed(3); + }, [option.quadraticScore]); + const formattedPluralityScore = useMemo(() => { const score = parseFloat(option.pluralityScore); return score % 1 === 0 ? score.toFixed(0) : score.toFixed(3); }, [option.pluralityScore]); - const handleGroupsClick = ( - e: - | React.MouseEvent - | React.MouseEvent, - ) => { - e.stopPropagation(); - setGroupsExpanded(!groupsExpanded); - }; - return ( - - - {index === 0 && } - {index === 1 && } - {index === 2 && } - - - {option.optionTitle} - - - - - - Plurality score: {formattedPluralityScore} - - - - - - Distinct voters: {option.distinctUsers} - - - - - Allocated hearts: {option.allocatedHearts} - - - - - Distinct groups: {option.distinctGroups} - - - handleGroupsClick(e)} $gap="0.5rem"> - - - Group names: - - handleGroupsClick(e)} - icon={{ src: `/icons/arrow-down-${theme}.svg`, alt: '' }} - $flipVertical={groupsExpanded} - /> - - {groupsExpanded && ( - - - {option.listOfGroupNames.sort().map((name) => ( - {name} - ))} - - - )} - - - - {option.optionSubTitle && {option.optionSubTitle}} + + + + {option.optionTitle} + + {option.allocatedHearts} + {formattedQuadraticScore} + {formattedPluralityScore} + $ 10.000 + + {option.optionSubTitle} + + Distinct voters: {option.distinctUsers} + + + Distinct groups: {option.distinctGroups} + + + Group names: {option.listOfGroupNames.join(', ')} + ); diff --git a/packages/berlin/src/components/results-columns/ResultsColumns.styled.tsx b/packages/berlin/src/components/results-columns/ResultsColumns.styled.tsx new file mode 100644 index 00000000..ab2fb3da --- /dev/null +++ b/packages/berlin/src/components/results-columns/ResultsColumns.styled.tsx @@ -0,0 +1,8 @@ +import styled from 'styled-components'; +import { Grid } from '../containers/Grid.styled'; + +export const Card = styled(Grid)` + border-bottom: 2px solid var(--color-black); + padding: 1.5rem; + grid-template-columns: auto repeat(3, 48px) 80px; +`; diff --git a/packages/berlin/src/components/results-columns/ResultsColumns.tsx b/packages/berlin/src/components/results-columns/ResultsColumns.tsx new file mode 100644 index 00000000..888eaaf5 --- /dev/null +++ b/packages/berlin/src/components/results-columns/ResultsColumns.tsx @@ -0,0 +1,35 @@ +import { useAppStore } from '../../store'; +import IconButton from '../icon-button'; +import { Bold } from '../typography/Bold.styled'; +import { Card } from './ResultsColumns.styled'; + +function ResultsColumns() { + const theme = useAppStore((state) => state.theme); + return ( + + Title + + + + + + ); +} + +export default ResultsColumns; diff --git a/packages/berlin/src/components/results-columns/index.ts b/packages/berlin/src/components/results-columns/index.ts new file mode 100644 index 00000000..d1e6d05c --- /dev/null +++ b/packages/berlin/src/components/results-columns/index.ts @@ -0,0 +1 @@ +export { default } from './ResultsColumns'; diff --git a/packages/berlin/src/components/stat-card/StatCard.styled.tsx b/packages/berlin/src/components/stat-card/StatCard.styled.tsx deleted file mode 100644 index 2abdd46f..00000000 --- a/packages/berlin/src/components/stat-card/StatCard.styled.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import styled from 'styled-components'; -import { FlexColumn } from '../containers/FlexColum.styled'; - -export const Card = styled(FlexColumn)` - border-radius: 1rem; - border: 1px solid var(--color-black); - color: var(--color-white); - overflow: hidden; - padding: 2rem; - width: 100%; -`; diff --git a/packages/berlin/src/components/stat-card/StatCard.tsx b/packages/berlin/src/components/stat-card/StatCard.tsx deleted file mode 100644 index 86b1717f..00000000 --- a/packages/berlin/src/components/stat-card/StatCard.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Body } from '../typography/Body.styled'; -import { Bold } from '../typography/Bold.styled'; -import { Subtitle } from '../typography/Subtitle.styled'; -import { Card } from './StatCard.styled'; - -type StatCardProps = { - title: string; - number?: number; -}; - -function StatCard({ title, number }: StatCardProps) { - return ( - - - {title}: - - {number} - - ); -} - -export default StatCard; diff --git a/packages/berlin/src/components/stat-card/index.ts b/packages/berlin/src/components/stat-card/index.ts deleted file mode 100644 index b0262e33..00000000 --- a/packages/berlin/src/components/stat-card/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './StatCard'; diff --git a/packages/berlin/src/components/stats-card/StatsCard.styled.tsx b/packages/berlin/src/components/stats-card/StatsCard.styled.tsx new file mode 100644 index 00000000..fd6f7b22 --- /dev/null +++ b/packages/berlin/src/components/stats-card/StatsCard.styled.tsx @@ -0,0 +1,8 @@ +import styled from 'styled-components'; +import { Grid } from '../containers/Grid.styled'; + +export const Card = styled(Grid)` + border-bottom: 1px solid var(--color-black); + padding: 1.5rem; + grid-template-columns: auto 240px; +`; diff --git a/packages/berlin/src/components/stats-card/StatsCard.tsx b/packages/berlin/src/components/stats-card/StatsCard.tsx new file mode 100644 index 00000000..6a70b80e --- /dev/null +++ b/packages/berlin/src/components/stats-card/StatsCard.tsx @@ -0,0 +1,18 @@ +import { Body } from '../typography/Body.styled'; +import { Card } from './StatsCard.styled'; + +type StatsCardProps = { + title: string; + number?: number; +}; + +function StatsCard({ title, number }: StatsCardProps) { + return ( + + {title} + {number} + + ); +} + +export default StatsCard; diff --git a/packages/berlin/src/components/stats-card/index.ts b/packages/berlin/src/components/stats-card/index.ts new file mode 100644 index 00000000..ebab22c4 --- /dev/null +++ b/packages/berlin/src/components/stats-card/index.ts @@ -0,0 +1 @@ +export { default } from './StatsCard'; diff --git a/packages/berlin/src/components/stats-columns/StatsColumns.styled.tsx b/packages/berlin/src/components/stats-columns/StatsColumns.styled.tsx new file mode 100644 index 00000000..2fa9b7aa --- /dev/null +++ b/packages/berlin/src/components/stats-columns/StatsColumns.styled.tsx @@ -0,0 +1,8 @@ +import styled from 'styled-components'; +import { Grid } from '../containers/Grid.styled'; + +export const Card = styled(Grid)` + border-bottom: 2px solid var(--color-black); + padding: 1.5rem; + grid-template-columns: auto 240px; +`; diff --git a/packages/berlin/src/components/stats-columns/StatsColumns.tsx b/packages/berlin/src/components/stats-columns/StatsColumns.tsx new file mode 100644 index 00000000..c10cae64 --- /dev/null +++ b/packages/berlin/src/components/stats-columns/StatsColumns.tsx @@ -0,0 +1,13 @@ +import { Bold } from '../typography/Bold.styled'; +import { Card } from './StatsColumns.styled'; + +function StatsColumns() { + return ( + + Statistic + Value + + ); +} + +export default StatsColumns; diff --git a/packages/berlin/src/components/stats-columns/index.ts b/packages/berlin/src/components/stats-columns/index.ts new file mode 100644 index 00000000..4f280484 --- /dev/null +++ b/packages/berlin/src/components/stats-columns/index.ts @@ -0,0 +1 @@ +export { default } from './StatsColumns'; diff --git a/packages/berlin/src/pages/Comments.tsx b/packages/berlin/src/pages/Comments.tsx index 2a1cba26..bfccfdd4 100644 --- a/packages/berlin/src/pages/Comments.tsx +++ b/packages/berlin/src/pages/Comments.tsx @@ -20,6 +20,7 @@ import { ResponseUserVotesType } from '../types/CycleType'; import { useAppStore } from '../store'; // Components +import { Body } from '../components/typography/Body.styled'; import { Bold } from '../components/typography/Bold.styled'; import { FlexColumn } from '../components/containers/FlexColum.styled'; import { FlexRow } from '../components/containers/FlexRow.styled'; @@ -50,6 +51,7 @@ function Comments() { queryFn: () => fetchOption(optionId || ''), enabled: !!optionId, }); + const { data: userVotes } = useQuery({ queryKey: ['votes', cycleId], queryFn: () => fetchUserVotes(cycleId || ''), @@ -141,7 +143,7 @@ function Comments() { return ( - + {localOptionHearts} {option?.optionTitle} - + {option?.optionSubTitle} + + Lead author: [// TODO] + + + Co-authors: [// TODO] + + - )} ); } diff --git a/packages/berlin/src/pages/Results.tsx b/packages/berlin/src/pages/Results.tsx index 410609f0..f3d06e53 100644 --- a/packages/berlin/src/pages/Results.tsx +++ b/packages/berlin/src/pages/Results.tsx @@ -4,10 +4,11 @@ import { useState } from 'react'; import { useParams } from 'react-router-dom'; import BackButton from '../components/back-button'; import { FlexColumn } from '../components/containers/FlexColum.styled'; -import { Grid } from '../components/containers/Grid.styled'; -import { Title } from '../components/typography/Title.styled'; import ResultCard from '../components/result-card'; -import StatCard from '../components/stat-card'; +import StatsCard from '../components/stats-card'; +import ResultsColumns from '../components/results-columns'; +import { Subtitle } from '../components/typography/Subtitle.styled'; +import StatsColumns from '../components/stats-columns'; function Results() { const [expandedIndex, setExpandedIndex] = useState(null); @@ -22,7 +23,7 @@ function Results() { }); const { data: statistics } = useQuery({ - queryKey: ['cycles', cycleId, 'forumQuestions', 0, 'statistics'], + queryKey: ['cycles', cycleId, 'forumQuestions', 0, 'statistics', cycle?.forumQuestions[0].id], queryFn: () => fetchForumQuestionStatistics(cycle?.forumQuestions[0].id || ''), enabled: !!cycle?.id, retry: false, @@ -61,24 +62,25 @@ function Results() { return ( - Results for: {cycle?.forumQuestions?.[0].questionTitle} - + Results for: {cycle?.forumQuestions?.[0].questionTitle} + + {optionStatsArray.map((option, index) => ( setExpandedIndex(expandedIndex === index ? null : index)} /> ))} - Overall Statistics - + Overall Statistics + + {overallStatistics.map((stat) => ( - + ))} - + ); }