From e1bc825abc1c57140541c0f20f276cd7f35d885e Mon Sep 17 00:00:00 2001 From: Camilo Vega <59750365+camilovegag@users.noreply.github.com> Date: Tue, 28 May 2024 02:17:44 -0500 Subject: [PATCH] Release 2.5.2 (#576) * Update back button to recieve a fallback route * Create a loader to redirect to cycle id if cycle is open (protect /results) * Add fallback route to cycle back button * 561 redirect to results when cycle closes (#562) * Match nav distribution from desktop on mobile * Redirect to results if cycle is closed * Add refetch of 5 seconds to cycle * Change redirect to navigate * Add toast * Add fallback route to results page back button * Show toast with clock emoji * Update message * Remove emoji * fix joining public groups * 559 change secret to access code at table (#560) * Change secret to access code at group table * Hide input number arrows * Hide spinner at hover * Fix header ui * Remove type number input styles as they dont work as expected * Burning min of 0 and max of 10000 for input fields (funding at the moment) * Burn a 0 to 10000 validation at number input * Update min and max checks * Make public group registration more general (#565) * Fix query key * Update min number input value from 0 to 250 & validation messages (#568) * Fix nav links on mobile (#566) * 569 update secret groups page (#570) * Update copy * Update layout * Update final question constant (#572) * Minor fixes (#573) * Fix long usernames at comments table * sort by lead if votes are equal * sort by id if votes are equal * add sort fallback by id --------- Co-authored-by: Diego Alzate * 574 swap usernames to full names on comments page (#575) * Change group names to voter affiliations * Update comments response type * Show full name instead of username --------- Co-authored-by: Diego Alzate --- packages/api/src/types/CommentType.ts | 9 +++- packages/berlin/src/App.tsx | 2 + .../CommentsColumns.styled.tsx | 2 +- .../groups-columns/GroupsColumns.styled.tsx | 2 +- .../columns/groups-columns/GroupsColumns.tsx | 4 +- .../src/components/header/Header.styled.tsx | 2 +- .../berlin/src/components/header/Header.tsx | 21 ++++---- .../comment-table/CommentsTable.styled.tsx | 4 +- .../tables/comment-table/CommentsTable.tsx | 6 ++- .../tables/results-table/ResultsTable.tsx | 2 +- packages/berlin/src/data/groups.ts | 30 ++++++----- packages/berlin/src/pages/Account.tsx | 2 +- packages/berlin/src/pages/Cycle.tsx | 35 +++++++++++- .../src/pages/PublicGroupRegistration.tsx | 22 +++----- packages/berlin/src/pages/Register.tsx | 5 +- packages/berlin/src/pages/Results.tsx | 4 +- .../src/pages/SecretGroupRegistration.tsx | 54 +++++++++---------- packages/berlin/src/utils/constants.ts | 2 +- 18 files changed, 126 insertions(+), 82 deletions(-) diff --git a/packages/api/src/types/CommentType.ts b/packages/api/src/types/CommentType.ts index df97de20..ae006265 100644 --- a/packages/api/src/types/CommentType.ts +++ b/packages/api/src/types/CommentType.ts @@ -11,7 +11,14 @@ export type GetCommentsRequest = { optionId: string; }; -export type GetCommentsResponse = (Comment & { user?: { id: string; username: string } })[]; +export type GetCommentsResponse = (Comment & { + user?: { + id: string; + username: string; + firstName: string; + lastName: string; + }; +})[]; export type PostCommentRequest = { value: string; diff --git a/packages/berlin/src/App.tsx b/packages/berlin/src/App.tsx index 8477dd86..603551ca 100644 --- a/packages/berlin/src/App.tsx +++ b/packages/berlin/src/App.tsx @@ -251,6 +251,8 @@ const router = (queryClient: QueryClient) => loader: ({ params }) => redirectToCycleIfOpen(queryClient, params.eventId, params.cycleId), path: ':cycleId/results', + loader: ({ params }) => + redirectToCycleIfOpen(queryClient, params.eventId, params.cycleId), Component: Results, }, { diff --git a/packages/berlin/src/components/columns/comments-columns/CommentsColumns.styled.tsx b/packages/berlin/src/components/columns/comments-columns/CommentsColumns.styled.tsx index fe08b092..8d3fb671 100644 --- a/packages/berlin/src/components/columns/comments-columns/CommentsColumns.styled.tsx +++ b/packages/berlin/src/components/columns/comments-columns/CommentsColumns.styled.tsx @@ -8,7 +8,7 @@ export const Card = styled(Grid)` grid-template-columns: minmax(200px, 600px) minmax(100px, 150px) 56px; @media (min-width: 600px) { - grid-template-columns: minmax(200px, 600px) minmax(100px, 150px) minmax(100px, 150px) 56px; + grid-template-columns: minmax(200px, 600px) minmax(100px, 200px) minmax(80px, 100px) 56px; } `; diff --git a/packages/berlin/src/components/columns/groups-columns/GroupsColumns.styled.tsx b/packages/berlin/src/components/columns/groups-columns/GroupsColumns.styled.tsx index cfa8e7df..287ebac3 100644 --- a/packages/berlin/src/components/columns/groups-columns/GroupsColumns.styled.tsx +++ b/packages/berlin/src/components/columns/groups-columns/GroupsColumns.styled.tsx @@ -17,7 +17,7 @@ export const Members = styled(Body)` font-weight: bold; `; -export const Secret = styled(Body)` +export const AccessCode = 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 index 1ef1a1e8..cfd42c3b 100644 --- a/packages/berlin/src/components/columns/groups-columns/GroupsColumns.tsx +++ b/packages/berlin/src/components/columns/groups-columns/GroupsColumns.tsx @@ -1,11 +1,11 @@ -import { Action, Card, Group, Members, Secret } from './GroupsColumns.styled'; +import { Action, Card, Group, Members, AccessCode } from './GroupsColumns.styled'; function GroupsColumns() { return ( Group Members - Secret + Access Code Action ); diff --git a/packages/berlin/src/components/header/Header.styled.tsx b/packages/berlin/src/components/header/Header.styled.tsx index 08609a44..36e34cce 100644 --- a/packages/berlin/src/components/header/Header.styled.tsx +++ b/packages/berlin/src/components/header/Header.styled.tsx @@ -108,7 +108,7 @@ export const ThemeButton = styled(Button)` } `; -export const MenuButton = styled.div` +export const MenuButton = styled.li` align-items: center; cursor: pointer; display: flex; diff --git a/packages/berlin/src/components/header/Header.tsx b/packages/berlin/src/components/header/Header.tsx index e5201cb7..79544b75 100644 --- a/packages/berlin/src/components/header/Header.tsx +++ b/packages/berlin/src/components/header/Header.tsx @@ -136,19 +136,19 @@ function Header() { onClick={() => navigate('/account')} icon={{ src: `/icons/user-${theme}.svg`, alt: 'User' }} $color="primary" + $height={20} + $width={20} /> ) : ( Login with Zupass )} -
  • - setIsBurgerMenuOpen(!isBurgerMenuOpen)}> - - - - -
  • + setIsBurgerMenuOpen(!isBurgerMenuOpen)}> + + + +
  • + My proposals + Agenda )} - - My proposals - + Account diff --git a/packages/berlin/src/components/tables/comment-table/CommentsTable.styled.tsx b/packages/berlin/src/components/tables/comment-table/CommentsTable.styled.tsx index a2a4493f..a1749a50 100644 --- a/packages/berlin/src/components/tables/comment-table/CommentsTable.styled.tsx +++ b/packages/berlin/src/components/tables/comment-table/CommentsTable.styled.tsx @@ -11,7 +11,7 @@ export const Card = styled(Grid)` grid-template-columns: minmax(200px, 600px) minmax(100px, 150px) 56px; @media (min-width: 600px) { - grid-template-columns: minmax(200px, 600px) minmax(100px, 150px) minmax(100px, 150px) 56px; + grid-template-columns: minmax(200px, 600px) minmax(100px, 200px) minmax(80px, 100px) 56px; } `; @@ -19,6 +19,8 @@ export const Comment = styled(Body)``; export const Author = styled(Body)` font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; `; export const FormattedDate = styled(Body)` diff --git a/packages/berlin/src/components/tables/comment-table/CommentsTable.tsx b/packages/berlin/src/components/tables/comment-table/CommentsTable.tsx index 34edcac3..6580aac1 100644 --- a/packages/berlin/src/components/tables/comment-table/CommentsTable.tsx +++ b/packages/berlin/src/components/tables/comment-table/CommentsTable.tsx @@ -99,11 +99,13 @@ function CommentsTable({ comment }: CommentsTableProps) { }; return ( - + {comment.value} - @{comment.user?.username} + + {comment.user?.firstName} {comment.user?.lastName} + {formattedDate} Distinct groups: {option.distinctGroups} - Group names: {option.listOfGroupNames.join(', ')} + Voter affiliations: {option.listOfGroupNames.join(', ')} diff --git a/packages/berlin/src/data/groups.ts b/packages/berlin/src/data/groups.ts index e243c91f..c2697123 100644 --- a/packages/berlin/src/data/groups.ts +++ b/packages/berlin/src/data/groups.ts @@ -1,38 +1,42 @@ const groups = { create: { - subtitle: 'Create a Research Group', + subtitle: 'Create a Group', body: [ { id: 0, - text: 'Share the access code with your collaborators so they can join your group', + text: 'Share the access code with your collaborators', }, { id: 1, - text: 'Any group member can assign a proposal to this group from My Proposals', + text: 'Any group member can assign their proposal to this group', }, ], - buttonText: 'Create group', + buttonText: 'Create', dialog: { - actionButtonText: 'Create group', + actionButtonText: 'Create', form: { input: { - placeholder: 'Research group name', - requiredMessage: 'Research group name must be 2 characters long or more', + placeholder: 'Group name', + requiredMessage: 'Group name must be 2 characters long or more', }, - buttonText: 'Create group', + buttonText: 'Create', }, - buttonText: 'Create group', + buttonText: 'Create', }, }, join: { - subtitle: 'Join a Research Group', - body: [], + subtitle: 'Join a Group', + body: [ + { + id: 0, + text: 'Ask the group creator for the access code', + }, + ], input: { - label: 'Ask the group creator for the access code', placeholder: 'Enter access code', requiredMessage: 'Access code is required', }, - buttonText: 'Join group', + buttonText: 'Join', }, }; diff --git a/packages/berlin/src/pages/Account.tsx b/packages/berlin/src/pages/Account.tsx index fb10604a..18ffae41 100644 --- a/packages/berlin/src/pages/Account.tsx +++ b/packages/berlin/src/pages/Account.tsx @@ -76,7 +76,7 @@ function Account() { }); const { data: usersToGroups, isLoading: userGroupsIsLoading } = useQuery({ - queryKey: ['user', user?.id, 'groups'], + queryKey: ['user', user?.id, 'users-to-groups'], queryFn: () => fetchUsersToGroups(user?.id || ''), enabled: !!user?.id, }); diff --git a/packages/berlin/src/pages/Cycle.tsx b/packages/berlin/src/pages/Cycle.tsx index 4aed96ce..2fe0557b 100644 --- a/packages/berlin/src/pages/Cycle.tsx +++ b/packages/berlin/src/pages/Cycle.tsx @@ -1,7 +1,7 @@ // React and third-party libraries import { useEffect, useMemo, useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import toast from 'react-hot-toast'; // API @@ -40,14 +40,16 @@ type QuestionOption = GetCycleResponse['forumQuestions'][number]['questionOption function Cycle() { const queryClient = useQueryClient(); - + const navigate = useNavigate(); const { user } = useUser(); const { eventId, cycleId } = useParams(); const { data: cycle } = useQuery({ queryKey: ['cycles', cycleId], queryFn: () => fetchCycle(cycleId || ''), enabled: !!cycleId, + refetchInterval: 5000, // Poll every 5 seconds }); + const { data: userVotes } = useQuery({ queryKey: ['votes', cycleId], queryFn: () => fetchUserVotes(cycleId || ''), @@ -72,6 +74,13 @@ function Cycle() { order: 'desc', }); + useEffect(() => { + if (cycle?.status === 'CLOSED') { + toast('Agenda has closed. Redirecting to results.'); + navigate(`/events/${eventId}/cycles/${cycleId}/results`); + } + }, [cycle?.status]); + useEffect(() => { if (cycle && cycle.startAt && cycle.endAt) { setStartAt(cycle.startAt); @@ -202,15 +211,32 @@ function Cycle() { const currentCycle = cycle?.forumQuestions[0]; + const sortId = (a: QuestionOption, b: QuestionOption, order: Order) => { + const idA = a.id.toUpperCase(); + const idB = b.id.toUpperCase(); + + return order === 'desc' ? idB.localeCompare(idA) : idA.localeCompare(idB); + }; + const sortByLead = (a: QuestionOption, b: QuestionOption, order: Order) => { const leadA = (a.user.lastName || a.user.username).toUpperCase(); const leadB = (b.user.lastName || b.user.username).toUpperCase(); + + if (leadA === leadB) { + return sortId(a, b, order); + } + return order === 'desc' ? leadB.localeCompare(leadA) : leadA.localeCompare(leadB); }; const sortByAffiliation = (a: QuestionOption, b: QuestionOption, order: Order) => { const affiliationA = a.user.group?.name.toUpperCase(); const affiliationB = b.user.group?.name.toUpperCase() ?? ''; + + if (affiliationA === affiliationB) { + return sortId(a, b, order); + } + return order === 'desc' ? affiliationB.localeCompare(affiliationA) : affiliationA.localeCompare(affiliationB); @@ -224,6 +250,11 @@ function Cycle() { ) => { const votesA = localUserVotes?.find((vote) => vote.optionId === a.id)?.numOfVotes || 0; const votesB = localUserVotes?.find((vote) => vote.optionId === b.id)?.numOfVotes || 0; + + if (votesA === votesB) { + return sortId(a, b, order); + } + return order === 'desc' ? votesB - votesA : votesA - votesB; }; diff --git a/packages/berlin/src/pages/PublicGroupRegistration.tsx b/packages/berlin/src/pages/PublicGroupRegistration.tsx index 23416ac4..390fe82d 100644 --- a/packages/berlin/src/pages/PublicGroupRegistration.tsx +++ b/packages/berlin/src/pages/PublicGroupRegistration.tsx @@ -23,10 +23,6 @@ function PublicGroupRegistration() { const [searchParams] = useSearchParams(); const groupCategoryNameParam = searchParams.get('groupCategory'); - const capitalizedParam = - groupCategoryNameParam && - groupCategoryNameParam?.slice(0, 1).toUpperCase() + groupCategoryNameParam?.slice(1); - const { control, getValues, @@ -78,8 +74,8 @@ function PublicGroupRegistration() { if (!body) { return; } - queryClient.invalidateQueries({ queryKey: ['user', user?.id, 'groups'] }); - toast.success(`Joined ${groupCategoryNameParam} group successfully!`); + queryClient.invalidateQueries({ queryKey: ['user', user?.id, 'users-to-groups'] }); + toast.success(`Joined group successfully!`); }, onError: () => { toast.error('Something went wrong.'); @@ -98,8 +94,8 @@ function PublicGroupRegistration() { return; } - queryClient.invalidateQueries({ queryKey: ['user', user?.id, 'groups'] }); - toast.success(`Updated ${groupCategoryNameParam} group successfully!`); + queryClient.invalidateQueries({ queryKey: ['user', user?.id, 'users-to-groups'] }); + toast.success(`Updated group successfully!`); }, onError: () => { toast.error('Something went wrong.'); @@ -133,15 +129,11 @@ function PublicGroupRegistration() { name="group" control={control} rules={{ - required: `${capitalizedParam} group is required`, + required: `Group is required`, }} render={({ field }) => ( {groupsInCategory && groupsInCategory.length > 0 && ( - <> - Your groups + - + )} ); diff --git a/packages/berlin/src/utils/constants.ts b/packages/berlin/src/utils/constants.ts index d5871434..28640e58 100644 --- a/packages/berlin/src/utils/constants.ts +++ b/packages/berlin/src/utils/constants.ts @@ -1,3 +1,3 @@ export const INITIAL_HEARTS = 80; export const FIVE_MINUTES_IN_SECONDS = 300; -export const FINAL_QUESTION_TITLE = 'Which research should receive a share of 100,000 ARB?'; +export const FINAL_QUESTION_TITLE = 'How should we allocate 100,000 ARB?';