From b7fa790d6eb30043170c9a9dfba9a6bc1bdc17c4 Mon Sep 17 00:00:00 2001 From: priyanshuvish Date: Wed, 22 Apr 2026 14:54:14 +0530 Subject: [PATCH] discussion change --- src/pages/DiscussionsPage/DiscussionsPage.tsx | 58 +++--- src/pages/DiscussionsPage/DiscussionsView.tsx | 166 ++++++++++++------ src/pages/Learners/LearnersPage.tsx | 134 ++++++++------ src/pages/Login.tsx | 2 +- src/redux/services/learnersApi.ts | 2 + 5 files changed, 227 insertions(+), 135 deletions(-) diff --git a/src/pages/DiscussionsPage/DiscussionsPage.tsx b/src/pages/DiscussionsPage/DiscussionsPage.tsx index 7d9097d..00eaa9b 100644 --- a/src/pages/DiscussionsPage/DiscussionsPage.tsx +++ b/src/pages/DiscussionsPage/DiscussionsPage.tsx @@ -6,7 +6,7 @@ import { Textarea } from '../../components/ui/textarea'; import { Badge } from '../../components/ui/badge'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../components/ui/select'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../components/ui/dialog'; -import { AlertCircle, MessageCircle, Plus, Search, ThumbsUp, X } from 'lucide-react'; +import { AlertCircle, Calendar, MessageCircle, Plus, Search, User, X } from 'lucide-react'; import { useCreateThreadMutation, useGetThreadsQuery } from '../../redux/services/forumApi'; import { useToast } from '../../components/toast/useToast'; import DiscussionsView from './DiscussionsView'; @@ -55,14 +55,6 @@ const DiscussionsPage: React.FC = () => { [threads, selectedThreadId] ); - const getReactionCount = (emoji: string) => - (threadsResponse?.data ?? []) - .flatMap((t) => t.reactions) - .find(() => false) && 0; - - const getThreadLikeCount = (thread: (typeof threads)[number]) => - thread.reactions.find((r) => r.emoji_code === 'U+1F44D')?.count ?? 0; - const getThreadReactionCount = (thread: (typeof threads)[number]) => thread.reactions.reduce((sum, r) => sum + r.count, 0); @@ -192,39 +184,41 @@ const DiscussionsPage: React.FC = () => { ))} diff --git a/src/pages/DiscussionsPage/DiscussionsView.tsx b/src/pages/DiscussionsPage/DiscussionsView.tsx index e191a84..2480595 100644 --- a/src/pages/DiscussionsPage/DiscussionsView.tsx +++ b/src/pages/DiscussionsPage/DiscussionsView.tsx @@ -1,5 +1,5 @@ -import React, { useMemo, useState } from 'react'; -import { ArrowLeft, Ellipsis, Link2, List, RefreshCw, Send, Smile, ThumbsUp } from 'lucide-react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { ArrowLeft, Ellipsis, MessageCircle, RefreshCw, Send, ThumbsUp } from 'lucide-react'; import { Button } from '../../components/ui/button'; import { Card, CardContent } from '../../components/ui/card'; import { Badge } from '../../components/ui/badge'; @@ -28,12 +28,21 @@ const getLikeCount = (thread: ForumThread) => thread.reactions.find((r) => r.emoji_code === 'U+1F44D')?.count ?? 0; const getReactionCount = (thread: ForumThread) => thread.reactions.reduce((sum, r) => sum + r.count, 0); +const reactionOptions = [ + { emoji: 'U+1F44D', label: '👍' }, + { emoji: 'U+1F602', label: '😂' }, + { emoji: 'U+1F60D', label: '😍' }, +]; export const DiscussionsView: React.FC = ({ thread, onBack }) => { const { showToast } = useToast(); const [replyInput, setReplyInput] = useState(''); const [childReplyInputById, setChildReplyInputById] = useState>({}); const [openChildReplyForId, setOpenChildReplyForId] = useState(null); + const [openThreadReactionPicker, setOpenThreadReactionPicker] = useState(false); + const [openReplyReactionPickerId, setOpenReplyReactionPickerId] = useState(null); + const threadReactionPickerRef = useRef(null); + const replyReactionPickerRefs = useRef>({}); const { data: repliesResponse, isLoading: repliesLoading, refetch: refetchReplies } = useGetRepliesByThreadQuery(thread.id); @@ -54,10 +63,10 @@ export const DiscussionsView: React.FC = ({ thread, onBack return countNodes(replies); }, [replies]); - const getReplyLikeCount = (reply: ForumReply) => - (reply.reactions ?? []).find((r) => r.emoji_code === 'U+1F44D')?.count ?? 0; const getReplyReactionCount = (reply: ForumReply) => (reply.reactions ?? []).reduce((sum, r) => sum + r.count, 0); + const getReactionLabel = (reactionCode: string) => + reactionOptions.find((opt) => opt.emoji === reactionCode)?.label ?? '🙂'; const postReply = async (content: string, parentId?: string) => { if (!content.trim()) return; @@ -81,33 +90,59 @@ export const DiscussionsView: React.FC = ({ thread, onBack } }; - const reactToThread = async () => { + const reactToThread = async (emoji: string) => { try { await reactToForumItem({ - emoji: 'U+1F44D', + emoji, thread_id: thread.id, }).unwrap(); await refetchReplies(); + setOpenThreadReactionPicker(false); showToast('Reaction added', 'Your reaction was recorded.', 'success'); } catch (error: any) { showToast('Reaction failed', error?.data?.message || 'Could not react right now.', 'error'); } }; - const reactToReply = async (replyId: string) => { + const reactToReply = async (replyId: string, emoji: string) => { try { await reactToForumItem({ - emoji: 'U+1F44D', - thread_id: thread.id, + emoji, reply_id: replyId, }).unwrap(); await refetchReplies(); + setOpenReplyReactionPickerId(null); showToast('Reaction added', 'Your reaction was recorded.', 'success'); } catch (error: any) { showToast('Reaction failed', error?.data?.message || 'Could not react right now.', 'error'); } }; + useEffect(() => { + const handleOutsideClick = (event: Event) => { + const target = event.target as Node | null; + if (!target) return; + + if (openThreadReactionPicker && threadReactionPickerRef.current && !threadReactionPickerRef.current.contains(target)) { + setOpenThreadReactionPicker(false); + } + + if (openReplyReactionPickerId) { + const activeReplyRef = replyReactionPickerRefs.current[openReplyReactionPickerId]; + if (activeReplyRef && !activeReplyRef.contains(target)) { + setOpenReplyReactionPickerId(null); + } + } + }; + + document.addEventListener('pointerdown', handleOutsideClick, true); + document.addEventListener('touchstart', handleOutsideClick, true); + return () => { + document.removeEventListener('pointerdown', handleOutsideClick, true); + document.removeEventListener('touchstart', handleOutsideClick, true); + }; + }, [openThreadReactionPicker, openReplyReactionPickerId]); + const renderReplies = (items: ForumReply[], depth = 0): React.ReactNode => items.map((reply) => { const childReplyText = childReplyInputById[reply.id] ?? ''; @@ -123,25 +158,49 @@ export const DiscussionsView: React.FC = ({ thread, onBack HR User {formatDate(reply.created_at)} -

{reply.content}

-
- {getReplyReactionCount(reply)} reactions - + + {openReplyReactionPickerId === reply.id && ( +
+ {reactionOptions.map((option) => ( + + ))} +
+ )} +
+ {getReplyReactionCount(reply)} @@ -184,10 +243,10 @@ export const DiscussionsView: React.FC = ({ thread, onBack - +
-

{thread.title}

-
@@ -210,20 +269,34 @@ export const DiscussionsView: React.FC = ({ thread, onBack ))} -
- {getReactionCount(thread)} 🤔 - - - 0 - +
+
+ + {openThreadReactionPicker && ( +
+ {reactionOptions.map((option) => ( + + ))} +
+ )} +
+ {getReactionCount(thread)}
@@ -264,20 +337,7 @@ export const DiscussionsView: React.FC = ({ thread, onBack placeholder="Share your thoughts or ask a follow-up question..." />
- {/*
- - - - -
*/} +
Press Enter to post
- +
@@ -1117,7 +1131,7 @@ const LearnersPage: React.FC = () => { {employee.programme || 'No programme assigned'}
- +
Progress @@ -1125,7 +1139,7 @@ const LearnersPage: React.FC = () => {
- +
{employee.status} @@ -1372,28 +1386,28 @@ const LearnersPage: React.FC = () => {

Step 3: Preview CSV Data ({csvRows.length})

- - - - First Name - Last Name - Email Address - Country Code - Phone Number - - - - {csvRows.map((row, index) => ( - - {row.first_name} - {row.last_name} - {row.email_address} - {row.phone_country_code} - {row.phone_number} +
+ + + First Name + Last Name + Email Address + Country Code + Phone Number - ))} - -
+ + + {csvRows.map((row, index) => ( + + {row.first_name} + {row.last_name} + {row.email_address} + {row.phone_country_code} + {row.phone_number} + + ))} + +
@@ -1468,6 +1482,26 @@ const LearnersPage: React.FC = () => {
+
+
+ + setProgrammeStartDate(e.target.value)} + required + /> +
+
+ + setProgrammeEndDate(e.target.value)} + required + /> +
+
); @@ -1792,7 +1828,7 @@ const LearnersPage: React.FC = () => {
)} - +