From 73fb8010ed89ea1d0d41131ae2badb9bdb5e93b0 Mon Sep 17 00:00:00 2001 From: Janhvi Patil Date: Wed, 10 Apr 2024 11:18:38 +0530 Subject: [PATCH] feat: added view poll votes modal in web app --- .../ChatMessage/Renderers/PollMessage.tsx | 2 + .../feature/polls/ViewPollVotes.tsx | 123 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 raven-app/src/components/feature/polls/ViewPollVotes.tsx diff --git a/raven-app/src/components/feature/chat/ChatMessage/Renderers/PollMessage.tsx b/raven-app/src/components/feature/chat/ChatMessage/Renderers/PollMessage.tsx index 1da40427a..751d3341c 100644 --- a/raven-app/src/components/feature/chat/ChatMessage/Renderers/PollMessage.tsx +++ b/raven-app/src/components/feature/chat/ChatMessage/Renderers/PollMessage.tsx @@ -8,6 +8,7 @@ import { RavenPoll } from "@/types/RavenMessaging/RavenPoll" import { ErrorBanner } from "@/components/layout/AlertBanner" import { RavenPollOption } from "@/types/RavenMessaging/RavenPollOption" import { useToast } from "@/hooks/useToast" +import { ViewPollVotes } from "@/components/feature/polls/ViewPollVotes" interface PollMessageBlockProps extends BoxProps { message: PollMessage, @@ -69,6 +70,7 @@ const PollMessageBox = ({ data, messageID }: { data: Poll, messageID: string }) } {data.poll.is_disabled ? Poll is now closed : null} + {data.poll.is_anonymous ? null : } ) diff --git a/raven-app/src/components/feature/polls/ViewPollVotes.tsx b/raven-app/src/components/feature/polls/ViewPollVotes.tsx new file mode 100644 index 000000000..d36c85a70 --- /dev/null +++ b/raven-app/src/components/feature/polls/ViewPollVotes.tsx @@ -0,0 +1,123 @@ +import { useFrappeGetCall } from 'frappe-react-sdk' +import { Poll } from '../chat/ChatMessage/Renderers/PollMessage' +import { useState } from 'react' +import { Button, Dialog, Flex, Separator, Text } from '@radix-ui/themes' +import { DIALOG_CONTENT_CLASS } from '@/utils/layout/dialog' +import { ErrorBanner } from '@/components/layout/AlertBanner' +import { UserAvatar } from '@/components/common/UserAvatar' +import { useGetUser } from '@/hooks/useGetUser' +import clsx from 'clsx' + +type VoteData = { + users: string[] + count: number + percentage: number +} + +type PollVotesResponse = Record + +interface ViewPollVotesProps { + poll: Poll +} + +export const ViewPollVotes = ({ poll }: ViewPollVotesProps) => { + + const [open, setOpen] = useState(false) + const onClose = () => { + setOpen(false) + } + + return ( + + + + + + + + + + + + + ) +} + +interface ViewPollVotesModalContentProps { + onClose: () => void, + poll: Poll +} + +const ViewPollVotesModalContent = ({ onClose, poll }: ViewPollVotesModalContentProps) => { + + // fetch poll votes using poll_id + const { data, error } = useFrappeGetCall<{ message: PollVotesResponse }>('raven.api.raven_poll.get_all_votes', { + 'poll_id': poll.poll.name, + }, `poll_votes_${poll.poll.name}`, { + revalidateOnFocus: false, + revalidateOnReconnect: false, + }) + + return ( + + + {data && data.message && } + + ) +} + +const VotesBlock = ({ votesData, poll }: { votesData: PollVotesResponse, poll: Poll }) => { + return ( + + + + Poll Votes + {poll.poll.total_votes} votes + + + + + + + {poll.poll.question} + {votesData && Object.keys(votesData).map((opt) => { + const option = votesData[opt] + const optionName = poll.poll.options.find(o => o.name === opt)?.option + return ( +
+
+ + {optionName} + - {option.percentage.toFixed(2)}% + + {option.count} vote{option.count > 1 ? 's' : ''} +
+ + {option.users.map((user) => { + return
+ +
+ })} +
+
+ ) + })} +
+
+ ) +} + +const UserVote = ({ user_id }: { user_id: string }) => { + + const user = useGetUser(user_id) + + return + +
+ {user?.full_name} + {user?.name} +
+
+} \ No newline at end of file