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/api/src/types/GroupType.ts b/packages/api/src/types/GroupType.ts index 5eb06f6d..18bb538c 100644 --- a/packages/api/src/types/GroupType.ts +++ b/packages/api/src/types/GroupType.ts @@ -1,15 +1,18 @@ export type GetGroupsResponse = { id: string; name: string; - description: string; + description: string | null; + secret: string | null; createdAt: string; updatedAt: string; groupCategoryId?: string; groupCategory?: { - createdAt: string; - eventId: string; id: string; name: string; + eventId: string; + userCanCreate: boolean; + userCanView: boolean; + createdAt: string; updatedAt: 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/comments-columns/CommentsColumns.styled.tsx b/packages/berlin/src/components/columns/comments-columns/CommentsColumns.styled.tsx similarity index 85% rename from packages/berlin/src/components/comments-columns/CommentsColumns.styled.tsx rename to packages/berlin/src/components/columns/comments-columns/CommentsColumns.styled.tsx index bc12e7d7..65f13fab 100644 --- a/packages/berlin/src/components/comments-columns/CommentsColumns.styled.tsx +++ b/packages/berlin/src/components/columns/comments-columns/CommentsColumns.styled.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components'; -import { Grid } from '../containers/Grid.styled'; -import { Body } from '../typography/Body.styled'; +import { Grid } from '../../containers/Grid.styled'; +import { Body } from '../../typography/Body.styled'; export const Card = styled(Grid)` border-bottom: 2px solid var(--color-black); diff --git a/packages/berlin/src/components/comments-columns/CommentsColumns.tsx b/packages/berlin/src/components/columns/comments-columns/CommentsColumns.tsx similarity index 100% rename from packages/berlin/src/components/comments-columns/CommentsColumns.tsx rename to packages/berlin/src/components/columns/comments-columns/CommentsColumns.tsx diff --git a/packages/berlin/src/components/comments-columns/index.ts b/packages/berlin/src/components/columns/comments-columns/index.ts similarity index 100% rename from packages/berlin/src/components/comments-columns/index.ts rename to packages/berlin/src/components/columns/comments-columns/index.ts diff --git a/packages/berlin/src/components/cycle-columns/CycleColumns.styled.tsx b/packages/berlin/src/components/columns/cycle-columns/CycleColumns.styled.tsx similarity index 84% rename from packages/berlin/src/components/cycle-columns/CycleColumns.styled.tsx rename to packages/berlin/src/components/columns/cycle-columns/CycleColumns.styled.tsx index acfaa36c..b50530ee 100644 --- a/packages/berlin/src/components/cycle-columns/CycleColumns.styled.tsx +++ b/packages/berlin/src/components/columns/cycle-columns/CycleColumns.styled.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import { FlexRow } from '../containers/FlexRow.styled'; +import { FlexRow } from '../../containers/FlexRow.styled'; export const Card = styled(FlexRow)` border-bottom: 2px solid var(--color-black); @@ -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/columns/cycle-columns/CycleColumns.tsx similarity index 76% rename from packages/berlin/src/components/cycle-columns/CycleColumns.tsx rename to packages/berlin/src/components/columns/cycle-columns/CycleColumns.tsx index c74d75f2..146a6155 100644 --- a/packages/berlin/src/components/cycle-columns/CycleColumns.tsx +++ b/packages/berlin/src/components/columns/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 IconButton from '../../icon-button'; +import { Body } from '../../typography/Body.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/cycle-columns/index.ts b/packages/berlin/src/components/columns/cycle-columns/index.ts similarity index 100% rename from packages/berlin/src/components/cycle-columns/index.ts rename to packages/berlin/src/components/columns/cycle-columns/index.ts diff --git a/packages/berlin/src/components/columns/groups-columns/GroupsColumns.styled.tsx b/packages/berlin/src/components/columns/groups-columns/GroupsColumns.styled.tsx new file mode 100644 index 00000000..f261b5af --- /dev/null +++ b/packages/berlin/src/components/columns/groups-columns/GroupsColumns.styled.tsx @@ -0,0 +1,23 @@ +import styled from 'styled-components'; +import { Body } from '../../typography/Body.styled'; +import { Grid } from '../../containers/Grid.styled'; + +export const Card = styled(Grid)` + border-bottom: 2px solid var(--color-black); + gap: 0; + grid-template-columns: repeat(2, 1fr) 82px; + width: 100%; + padding: 1.5rem; +`; + +export const Group = styled(Body)` + font-weight: bold; +`; + +export const Secret = styled(Body)` + font-weight: bold; +`; + +export const Action = styled(Body)` + font-weight: bold; +`; diff --git a/packages/berlin/src/components/columns/groups-columns/GroupsColumns.tsx b/packages/berlin/src/components/columns/groups-columns/GroupsColumns.tsx new file mode 100644 index 00000000..b4d12e59 --- /dev/null +++ b/packages/berlin/src/components/columns/groups-columns/GroupsColumns.tsx @@ -0,0 +1,13 @@ +import { Action, Card, Group, Secret } from './GroupsColumns.styled'; + +function GroupsColumns() { + return ( + + Group + Secret + Action + + ); +} + +export default GroupsColumns; diff --git a/packages/berlin/src/components/columns/groups-columns/index.ts b/packages/berlin/src/components/columns/groups-columns/index.ts new file mode 100644 index 00000000..e9f9ca75 --- /dev/null +++ b/packages/berlin/src/components/columns/groups-columns/index.ts @@ -0,0 +1 @@ +export { default } from './GroupsColumns'; diff --git a/packages/berlin/src/components/columns/results-columns/ResultsColumns.styled.tsx b/packages/berlin/src/components/columns/results-columns/ResultsColumns.styled.tsx new file mode 100644 index 00000000..59894158 --- /dev/null +++ b/packages/berlin/src/components/columns/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/columns/results-columns/ResultsColumns.tsx b/packages/berlin/src/components/columns/results-columns/ResultsColumns.tsx new file mode 100644 index 00000000..0553c64d --- /dev/null +++ b/packages/berlin/src/components/columns/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/columns/results-columns/index.ts b/packages/berlin/src/components/columns/results-columns/index.ts new file mode 100644 index 00000000..d1e6d05c --- /dev/null +++ b/packages/berlin/src/components/columns/results-columns/index.ts @@ -0,0 +1 @@ +export { default } from './ResultsColumns'; diff --git a/packages/berlin/src/components/columns/stats-columns/StatsColumns.styled.tsx b/packages/berlin/src/components/columns/stats-columns/StatsColumns.styled.tsx new file mode 100644 index 00000000..9dce1f0c --- /dev/null +++ b/packages/berlin/src/components/columns/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/columns/stats-columns/StatsColumns.tsx b/packages/berlin/src/components/columns/stats-columns/StatsColumns.tsx new file mode 100644 index 00000000..500929af --- /dev/null +++ b/packages/berlin/src/components/columns/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/columns/stats-columns/index.ts b/packages/berlin/src/components/columns/stats-columns/index.ts new file mode 100644 index 00000000..4f280484 --- /dev/null +++ b/packages/berlin/src/components/columns/stats-columns/index.ts @@ -0,0 +1 @@ +export { default } from './StatsColumns'; diff --git a/packages/berlin/src/components/comment-card/index.ts b/packages/berlin/src/components/comment-card/index.ts deleted file mode 100644 index 378b8fd1..00000000 --- a/packages/berlin/src/components/comment-card/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './CommentCard'; diff --git a/packages/berlin/src/components/cycle-card/index.ts b/packages/berlin/src/components/cycle-card/index.ts deleted file mode 100644 index 0ac1e285..00000000 --- a/packages/berlin/src/components/cycle-card/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './CycleCard'; 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 deleted file mode 100644 index 3709b353..00000000 --- a/packages/berlin/src/components/result-card/ResultCard.styled.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import styled from 'styled-components'; - -export const Card = styled.article<{ $expanded: boolean }>` - border-radius: 1rem; - border: 1px solid var(--color-black); - color: var(--color-white); - cursor: pointer; - overflow: hidden; - padding: 2rem; - position: relative; - transition: height 0.3s ease-in-out; - width: 100%; - - .statistics { - 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: '• '; - } -`; diff --git a/packages/berlin/src/components/result-card/ResultCard.tsx b/packages/berlin/src/components/result-card/ResultCard.tsx deleted file mode 100644 index 8b99160f..00000000 --- a/packages/berlin/src/components/result-card/ResultCard.tsx +++ /dev/null @@ -1,121 +0,0 @@ -// React and third-party libraries -import { useMemo, useState } from 'react'; - -// Store -import { useAppStore } from '../../store'; - -// Components -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'; - -type ResultCardProps = { - $expanded: boolean; - index: number; - option: { - optionTitle: string; - pluralityScore: string; - distinctUsers: string; - allocatedHearts: string; - optionSubTitle: string; - distinctGroups: number; - listOfGroupNames: string[]; - id: string; - }; - onClick: () => void; -}; - -function ResultCard({ $expanded, option, index, onClick }: ResultCardProps) { - const [groupsExpanded, setGroupsExpanded] = useState(false); - const theme = useAppStore((state) => state.theme); - 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}} - - - ); -} - -export default ResultCard; diff --git a/packages/berlin/src/components/result-card/index.ts b/packages/berlin/src/components/result-card/index.ts deleted file mode 100644 index aca044b9..00000000 --- a/packages/berlin/src/components/result-card/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './ResultCard'; 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/comment-card/CommentCard.styled.tsx b/packages/berlin/src/components/tables/comment-table/CommentsTable.styled.tsx similarity index 86% rename from packages/berlin/src/components/comment-card/CommentCard.styled.tsx rename to packages/berlin/src/components/tables/comment-table/CommentsTable.styled.tsx index e5f389c3..a2a4493f 100644 --- a/packages/berlin/src/components/comment-card/CommentCard.styled.tsx +++ b/packages/berlin/src/components/tables/comment-table/CommentsTable.styled.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components'; -import { Body } from '../typography/Body.styled'; -import { Grid } from '../containers/Grid.styled'; +import { Body } from '../../typography/Body.styled'; +import { Grid } from '../../containers/Grid.styled'; export const Card = styled(Grid)` align-items: flex-start; diff --git a/packages/berlin/src/components/comment-card/CommentCard.tsx b/packages/berlin/src/components/tables/comment-table/CommentsTable.tsx similarity index 89% rename from packages/berlin/src/components/comment-card/CommentCard.tsx rename to packages/berlin/src/components/tables/comment-table/CommentsTable.tsx index f8caaa61..54c4938c 100644 --- a/packages/berlin/src/components/comment-card/CommentCard.tsx +++ b/packages/berlin/src/components/tables/comment-table/CommentsTable.tsx @@ -7,25 +7,25 @@ import { useParams } from 'react-router-dom'; import { GetCommentsResponse, deleteComment, deleteLike, fetchCommentLikes, postLike } from 'api'; // Hooks -import useUser from '../../hooks/useUser'; +import useUser from '../../../hooks/useUser'; // Store -import { useAppStore } from '../../store'; +import { useAppStore } from '../../../store'; // Components -import { FlexRow } from '../containers/FlexRow.styled'; -import Button from '../button'; -import Dialog from '../dialog'; -import IconButton from '../icon-button'; +import { FlexRow } from '../../containers/FlexRow.styled'; +import Button from '../../button'; +import Dialog from '../../dialog'; +import IconButton from '../../icon-button'; // Styled Components -import { Author, Card, Comment, FormattedDate } from './CommentCard.styled'; +import { Author, Card, Comment, FormattedDate } from './CommentsTable.styled'; -type CommentCardProps = { +type CommentsTableProps = { comment: GetCommentsResponse[number]; }; -function CommentCard({ comment }: CommentCardProps) { +function CommentsTable({ comment }: CommentsTableProps) { const { optionId } = useParams(); const theme = useAppStore((state) => state.theme); const queryClient = useQueryClient(); @@ -149,4 +149,4 @@ function CommentCard({ comment }: CommentCardProps) { ); } -export default CommentCard; +export default CommentsTable; diff --git a/packages/berlin/src/components/tables/comment-table/index.ts b/packages/berlin/src/components/tables/comment-table/index.ts new file mode 100644 index 00000000..92e391c6 --- /dev/null +++ b/packages/berlin/src/components/tables/comment-table/index.ts @@ -0,0 +1 @@ +export { default } from './CommentsTable'; diff --git a/packages/berlin/src/components/cycle-card/CycleCard.styled.tsx b/packages/berlin/src/components/tables/cycle-table/CycleTable.styled.tsx similarity index 75% rename from packages/berlin/src/components/cycle-card/CycleCard.styled.tsx rename to packages/berlin/src/components/tables/cycle-table/CycleTable.styled.tsx index b5ac3079..59d90433 100644 --- a/packages/berlin/src/components/cycle-card/CycleCard.styled.tsx +++ b/packages/berlin/src/components/tables/cycle-table/CycleTable.styled.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import { FlexColumn } from '../containers/FlexColum.styled'; +import { FlexColumn } from '../../containers/FlexColum.styled'; export const Card = styled(FlexColumn)` border-radius: 1rem; diff --git a/packages/berlin/src/components/cycle-card/CycleCard.tsx b/packages/berlin/src/components/tables/cycle-table/CycleTable.tsx similarity index 72% rename from packages/berlin/src/components/cycle-card/CycleCard.tsx rename to packages/berlin/src/components/tables/cycle-table/CycleTable.tsx index 0a3014ea..4cb5c327 100644 --- a/packages/berlin/src/components/cycle-card/CycleCard.tsx +++ b/packages/berlin/src/components/tables/cycle-table/CycleTable.tsx @@ -1,16 +1,16 @@ import { GetCycleResponse } from 'api'; -import Button from '../button'; -import { FlexColumn } from '../containers/FlexColum.styled'; -import { Body } from '../typography/Body.styled'; -import { Subtitle } from '../typography/Subtitle.styled'; -import { Card } from './CycleCard.styled'; +import Button from '../../button'; +import { FlexColumn } from '../../containers/FlexColum.styled'; +import { Body } from '../../typography/Body.styled'; +import { Subtitle } from '../../typography/Subtitle.styled'; +import { Card } from './CycleTable.styled'; import { useNavigate, useParams } from 'react-router-dom'; -type CycleCardProps = { +type CycleTableProps = { cycle: GetCycleResponse; }; -function CycleCard({ cycle }: CycleCardProps) { +function CycleTable({ cycle }: CycleTableProps) { const { eventId } = useParams(); const navigate = useNavigate(); @@ -44,4 +44,4 @@ function CycleCard({ cycle }: CycleCardProps) { ); } -export default CycleCard; +export default CycleTable; diff --git a/packages/berlin/src/components/tables/cycle-table/index.ts b/packages/berlin/src/components/tables/cycle-table/index.ts new file mode 100644 index 00000000..e87a2af3 --- /dev/null +++ b/packages/berlin/src/components/tables/cycle-table/index.ts @@ -0,0 +1 @@ +export { default } from './CycleTable'; diff --git a/packages/berlin/src/components/tables/groups-table/GroupsTable.styled.tsx b/packages/berlin/src/components/tables/groups-table/GroupsTable.styled.tsx new file mode 100644 index 00000000..9dee9e39 --- /dev/null +++ b/packages/berlin/src/components/tables/groups-table/GroupsTable.styled.tsx @@ -0,0 +1,15 @@ +import styled from 'styled-components'; +import { Grid } from '../../containers/Grid.styled'; +import { Body } from '../../typography/Body.styled'; + +export const Card = styled(Grid)` + border-bottom: 1px solid var(--color-black); + gap: 0; + grid-template-columns: repeat(2, 1fr) 82px; + padding: 1.5rem; + width: 100%; +`; + +export const Group = styled(Body)``; + +export const Secret = styled(Body)``; diff --git a/packages/berlin/src/components/tables/groups-table/GroupsTable.tsx b/packages/berlin/src/components/tables/groups-table/GroupsTable.tsx new file mode 100644 index 00000000..9c076d77 --- /dev/null +++ b/packages/berlin/src/components/tables/groups-table/GroupsTable.tsx @@ -0,0 +1,62 @@ +// React and third-party libraries +import { useQuery } from '@tanstack/react-query'; +import toast from 'react-hot-toast'; + +// API +import { fetchUserGroups } from 'api'; + +// Hooks +import { useAppStore } from '../../../store'; +import useUser from '../../../hooks/useUser'; + +// Components +import { Card, Group, Secret } from './GroupsTable.styled'; +import { FlexRow } from '../../containers/FlexRow.styled'; +import Button from '../../button'; +import Dialog from '../../dialog'; +import IconButton from '../../icon-button'; +import { Body } from '../../typography/Body.styled'; + +function GroupsTable() { + const { user } = useUser(); + const theme = useAppStore((state) => state.theme); + + const { data: groups } = useQuery({ + queryFn: () => fetchUserGroups(user?.id || ''), + queryKey: ['groups', user?.id], + enabled: !!user?.id, + }); + + const handleCopyButtonClick = (secretCode: string) => { + navigator.clipboard.writeText(secretCode); + toast.success(`Secret code ${secretCode} copied to clipboard`); + }; + + return groups?.map((group) => ( + + {group.name} + {group.secret ? ( + + {group.secret} + handleCopyButtonClick(group.secret!)} + icon={{ src: `/icons/copy-${theme}.svg`, alt: 'Copy icon' }} + $color="secondary" + $padding={4} + /> + + ) : ( + No secret + )} + Leave} + title="Are you sure?" + description={`This action cannot be undone. This will remove you from group ${group.name}.`} + onActionClick={() => alert('Hello world')} // TODO + actionButtonText="Leave group" + /> + + )); +} + +export default GroupsTable; diff --git a/packages/berlin/src/components/tables/groups-table/index.ts b/packages/berlin/src/components/tables/groups-table/index.ts new file mode 100644 index 00000000..ef4da62c --- /dev/null +++ b/packages/berlin/src/components/tables/groups-table/index.ts @@ -0,0 +1 @@ +export { default } from './GroupsTable'; diff --git a/packages/berlin/src/components/tables/results-table/ResultsTable.styled.tsx b/packages/berlin/src/components/tables/results-table/ResultsTable.styled.tsx new file mode 100644 index 00000000..2bd71ceb --- /dev/null +++ b/packages/berlin/src/components/tables/results-table/ResultsTable.styled.tsx @@ -0,0 +1,18 @@ +import styled from 'styled-components'; +import { Grid } from '../../containers/Grid.styled'; + +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: 1.5rem; + position: relative; + transition: height 0.3s ease-in-out; + width: 100%; + + .description { + display: ${(props) => (props.$expanded ? 'flex' : 'none')}; + grid-column: 1/6; + } +`; diff --git a/packages/berlin/src/components/tables/results-table/ResultsTable.tsx b/packages/berlin/src/components/tables/results-table/ResultsTable.tsx new file mode 100644 index 00000000..5723f2dd --- /dev/null +++ b/packages/berlin/src/components/tables/results-table/ResultsTable.tsx @@ -0,0 +1,77 @@ +// React and third-party libraries +import { useMemo } from 'react'; + +// Store +import { useAppStore } from '../../../store'; + +// Components +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 IconButton from '../../icon-button'; + +// Styled Components +import { Card } from './ResultsTable.styled'; + +type ResultsTableProps = { + $expanded: boolean; + option: { + optionTitle: string; + pluralityScore: string; + distinctUsers: string; + allocatedHearts: string; + optionSubTitle: string; + distinctGroups: number; + listOfGroupNames: string[]; + quadraticScore: string; + id: string; + }; + onClick: () => void; +}; + +function ResultsTable({ $expanded, option, onClick }: ResultsTableProps) { + 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]); + + return ( + + + + {option.optionTitle} + + {option.allocatedHearts} + {formattedQuadraticScore} + {formattedPluralityScore} + $ 10.000 + + {option.optionSubTitle} + + Distinct voters: {option.distinctUsers} + + + Distinct groups: {option.distinctGroups} + + + Group names: {option.listOfGroupNames.join(', ')} + + + + ); +} + +export default ResultsTable; diff --git a/packages/berlin/src/components/tables/results-table/index.ts b/packages/berlin/src/components/tables/results-table/index.ts new file mode 100644 index 00000000..ad9cc745 --- /dev/null +++ b/packages/berlin/src/components/tables/results-table/index.ts @@ -0,0 +1 @@ +export { default } from './ResultsTable'; diff --git a/packages/berlin/src/components/tables/stats-table/StatsTable.styled.tsx b/packages/berlin/src/components/tables/stats-table/StatsTable.styled.tsx new file mode 100644 index 00000000..989d53b6 --- /dev/null +++ b/packages/berlin/src/components/tables/stats-table/StatsTable.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/tables/stats-table/StatsTable.tsx b/packages/berlin/src/components/tables/stats-table/StatsTable.tsx new file mode 100644 index 00000000..655750e4 --- /dev/null +++ b/packages/berlin/src/components/tables/stats-table/StatsTable.tsx @@ -0,0 +1,18 @@ +import { Body } from '../../typography/Body.styled'; +import { Card } from './StatsTable.styled'; + +type StatsTableProps = { + title: string; + number?: number; +}; + +function StatsTable({ title, number }: StatsTableProps) { + return ( + + {title} + {number} + + ); +} + +export default StatsTable; diff --git a/packages/berlin/src/components/tables/stats-table/index.ts b/packages/berlin/src/components/tables/stats-table/index.ts new file mode 100644 index 00000000..f4a559e4 --- /dev/null +++ b/packages/berlin/src/components/tables/stats-table/index.ts @@ -0,0 +1 @@ +export { default } from './StatsTable'; diff --git a/packages/berlin/src/components/voting-cards/VotingCards.tsx b/packages/berlin/src/components/voting-cards/VotingCards.tsx index 632864c5..dd739f17 100644 --- a/packages/berlin/src/components/voting-cards/VotingCards.tsx +++ b/packages/berlin/src/components/voting-cards/VotingCards.tsx @@ -1,7 +1,7 @@ -import type { GetCycleResponse } from 'api'; import { FlexColumn } from '../containers/FlexColum.styled'; -import CycleCard from '../cycle-card'; import { Title } from '../typography/Title.styled'; +import CycleTable from '../tables/cycle-table'; +import type { GetCycleResponse } from 'api'; type VotingCardsProps = { state: string; @@ -12,7 +12,7 @@ function VotingCards({ state, cards }: VotingCardsProps) { return ( {state} Agendas - {cards && cards.map((card) => )} + {cards && cards.map((card) => )} ); } diff --git a/packages/berlin/src/pages/Comments.tsx b/packages/berlin/src/pages/Comments.tsx index 2a1cba26..57b0d283 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'; @@ -27,8 +28,8 @@ import { Form } from '../components/containers/Form.styled'; import { Subtitle } from '../components/typography/Subtitle.styled'; import BackButton from '../components/back-button'; import Button from '../components/button'; -import CommentCard from '../components/comment-card'; -import CommentsColumns from '../components/comments-columns'; +import CommentsTable from '../components/tables/comment-table'; +import CommentsColumns from '../components/columns/comments-columns'; import IconButton from '../components/icon-button'; import Textarea from '../components/textarea'; @@ -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..12de1ce8 100644 --- a/packages/berlin/src/pages/Results.tsx +++ b/packages/berlin/src/pages/Results.tsx @@ -1,13 +1,14 @@ -import { useQuery } from '@tanstack/react-query'; import { fetchCycle, fetchForumQuestionStatistics } from 'api'; -import { useState } from 'react'; +import { FlexColumn } from '../components/containers/FlexColum.styled'; +import { Subtitle } from '../components/typography/Subtitle.styled'; import { useParams } from 'react-router-dom'; +import { useQuery } from '@tanstack/react-query'; +import { useState } from 'react'; 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 ResultsColumns from '../components/columns/results-columns'; +import ResultsTable from '../components/tables/results-table'; +import StatsTable from '../components/tables/stats-table'; +import StatsColumns from '../components/columns/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) => ( - + ))} - + ); } diff --git a/packages/berlin/src/pages/SecretGroupRegistration.tsx b/packages/berlin/src/pages/SecretGroupRegistration.tsx index e5b74dc5..a9eda4a6 100644 --- a/packages/berlin/src/pages/SecretGroupRegistration.tsx +++ b/packages/berlin/src/pages/SecretGroupRegistration.tsx @@ -25,6 +25,8 @@ import Divider from '../components/divider'; import Input from '../components/input'; import ResearchGroupForm from '../components/research-group-form'; import SecretCode from '../components/secret-code'; +import GroupsColumns from '../components/columns/groups-columns'; +import GroupsTable from '../components/tables/groups-table'; function SecretGroupRegistration() { const queryClient = useQueryClient(); @@ -103,50 +105,55 @@ function SecretGroupRegistration() { }; return ( - - - {groups.create.subtitle} - {groups.create.body.map(({ id, text }) => ( - {text} - ))} - {groupName && secretCode && } - setIsDialogOpen(true)}>{groups.create.buttonText} - } - title={groups.create.dialog.title} - description={groups.create.dialog.description} - content={ - - } - dialogButtons={false} - /> - - - - {groups.join.subtitle} - {groups.join.body.map(({ id, text }) => ( - {text} - ))} -
- + + + {groups.create.subtitle} + {groups.create.body.map(({ id, text }) => ( + {text} + ))} + {groupName && secretCode && } + setIsDialogOpen(true)}>{groups.create.buttonText} + } + title={groups.create.dialog.title} + description={groups.create.dialog.description} + content={ + + } + dialogButtons={false} /> - - - -
+
+ + + {groups.join.subtitle} + {groups.join.body.map(({ id, text }) => ( + {text} + ))} +
+ + +
+
+
+ Your groups + + + ); }