From 1ed11d978786336d0261408cca636cb98a1c0ede Mon Sep 17 00:00:00 2001 From: Zhang Ziqing <69516975+ziqing26@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:43:10 +0800 Subject: [PATCH] [offers][feat] offer discussion section (#392) * [offers][feat] add comment components * [offers][feat] add comment reply components * [offers][feat] offer discussion section * [offers][chore] remove comments --- .../offers/profile/ProfileComments.tsx | 135 ++++++++++++++-- .../offers/profile/comments/CommentCard.tsx | 152 ++++++++++++++++++ .../comments/ExpandableCommentCard.tsx | 44 +++++ .../src/components/offers/table/types.ts | 7 - apps/portal/src/components/offers/types.ts | 11 ++ .../pages/offers/profile/[offerProfileId].tsx | 25 +-- apps/portal/src/utils/offers/time.tsx | 28 ++++ 7 files changed, 368 insertions(+), 34 deletions(-) create mode 100644 apps/portal/src/components/offers/profile/comments/CommentCard.tsx create mode 100644 apps/portal/src/components/offers/profile/comments/ExpandableCommentCard.tsx diff --git a/apps/portal/src/components/offers/profile/ProfileComments.tsx b/apps/portal/src/components/offers/profile/ProfileComments.tsx index a0a47d43..ecf1843d 100644 --- a/apps/portal/src/components/offers/profile/ProfileComments.tsx +++ b/apps/portal/src/components/offers/profile/ProfileComments.tsx @@ -1,21 +1,102 @@ +import { signIn, useSession } from 'next-auth/react'; +import { useState } from 'react'; import { ClipboardDocumentIcon, ShareIcon } from '@heroicons/react/24/outline'; -import { Button, Spinner } from '@tih/ui'; +import { Button, HorizontalDivider, Spinner, TextArea } from '@tih/ui'; + +import ExpandableCommentCard from '~/components/offers/profile/comments/ExpandableCommentCard'; + +import { trpc } from '~/utils/trpc'; + +import type { OffersDiscussion, Reply } from '~/types/offers'; type ProfileHeaderProps = Readonly<{ - handleCopyEditLink: () => void; - handleCopyPublicLink: () => void; isDisabled: boolean; isEditable: boolean; isLoading: boolean; + profileId: string; + profileName?: string; + token?: string; }>; export default function ProfileComments({ - handleCopyEditLink, - handleCopyPublicLink, isDisabled, isEditable, isLoading, + profileId, + profileName, + token, }: ProfileHeaderProps) { + const { data: session, status } = useSession(); + const [currentReply, setCurrentReply] = useState(''); + const [replies, setReplies] = useState>(); + + const commentsQuery = trpc.useQuery( + ['offers.comments.getComments', { profileId }], + { + onSuccess(response: OffersDiscussion) { + setReplies(response.data); + }, + }, + ); + + const trpcContext = trpc.useContext(); + const createCommentMutation = trpc.useMutation(['offers.comments.create'], { + onSuccess() { + trpcContext.invalidateQueries([ + 'offers.comments.getComments', + { profileId }, + ]); + }, + }); + + function handleComment(message: string) { + if (isEditable) { + // If it is with edit permission, send comment to API with username = null + createCommentMutation.mutate( + { + message, + profileId, + token, + }, + { + onSuccess: () => { + setCurrentReply(''); + }, + }, + ); + } else if (status === 'authenticated') { + // If not the OP and logged in, send comment to API + createCommentMutation.mutate( + { + message, + profileId, + userId: session.user?.id, + }, + { + onSuccess: () => { + setCurrentReply(''); + }, + }, + ); + } else { + // If not the OP and not logged in, direct users to log in + signIn(); + } + } + + function handleCopyEditLink() { + // TODO: Add notification + navigator.clipboard.writeText( + `${window.location.origin}/offers/profile/${profileId}?token=${token}`, + ); + } + + function handleCopyPublicLink() { + navigator.clipboard.writeText( + `${window.location.origin}/offers/profile/${profileId}`, + ); + } + if (isLoading) { return (
@@ -24,7 +105,7 @@ export default function ProfileComments({ ); } return ( -
+
{isEditable && (
-

- Discussions feature coming soon -

- {/*