diff --git a/apps/portal/src/components/offers/profile/ProfileComments.tsx b/apps/portal/src/components/offers/profile/ProfileComments.tsx
index a0a47d43..e3e9bb18 100644
--- a/apps/portal/src/components/offers/profile/ProfileComments.tsx
+++ b/apps/portal/src/components/offers/profile/ProfileComments.tsx
@@ -1,5 +1,7 @@
import { ClipboardDocumentIcon, ShareIcon } from '@heroicons/react/24/outline';
-import { Button, Spinner } from '@tih/ui';
+import { Button, Spinner, TextArea } from '@tih/ui';
+
+import ExpandableCommentCard from './comments/ExpandableCommentCard';
type ProfileHeaderProps = Readonly<{
handleCopyEditLink: () => void;
@@ -16,6 +18,9 @@ export default function ProfileComments({
isEditable,
isLoading,
}: ProfileHeaderProps) {
+ function handleReply(replayingToId: string, userId: string) {
+ return replayingToId + userId; // To integrate with API
+ }
if (isLoading) {
return (
@@ -52,7 +57,41 @@ export default function ProfileComments({
Discussions feature coming soon
- {/* */}
+
+
);
}
diff --git a/apps/portal/src/components/offers/profile/comments/CommentCard.tsx b/apps/portal/src/components/offers/profile/comments/CommentCard.tsx
new file mode 100644
index 00000000..712f06a1
--- /dev/null
+++ b/apps/portal/src/components/offers/profile/comments/CommentCard.tsx
@@ -0,0 +1,49 @@
+import { ChatBubbleBottomCenterIcon } from '@heroicons/react/24/outline';
+import { Button } from '@tih/ui';
+
+import type { CommentEntity } from '~/components/offers/types';
+
+import { timeSinceNow } from '~/utils/offers/time';
+
+type Props = Readonly<{
+ comment: CommentEntity;
+ handleReply: (replayingToId: string, userId: string) => void;
+}>;
+
+export default function CommentCard({
+ comment: {
+ createdAt,
+ message,
+ // ProfileId,
+ // replies,
+ replyingToId,
+ userId,
+ username,
+ },
+ handleReply,
+}: Props) {
+ return (
+
+
+
{username}
+
{message}
+
+
{`${timeSinceNow(
+ createdAt,
+ )} ago`}
+
+
+
+
+
+ );
+}
diff --git a/apps/portal/src/components/offers/profile/comments/ExpandableCommentCard.tsx b/apps/portal/src/components/offers/profile/comments/ExpandableCommentCard.tsx
new file mode 100644
index 00000000..9bb750a9
--- /dev/null
+++ b/apps/portal/src/components/offers/profile/comments/ExpandableCommentCard.tsx
@@ -0,0 +1,30 @@
+import { Collapsible } from '@tih/ui';
+
+import CommentCard from '~/components/offers/profile/comments/CommentCard';
+import type { CommentEntity } from '~/components/offers/types';
+
+type Props = Readonly<{
+ comment: CommentEntity;
+ handleReply: (replayingToId: string, userId: string) => void;
+}>;
+
+export default function ExpandableCommentCard({ comment, handleReply }: Props) {
+ return (
+
+
+ {comment.replies && (
+
+
+ {comment.replies.map((reply) => (
+
+ ))}
+
+
+ )}
+
+ );
+}
diff --git a/apps/portal/src/components/offers/types.ts b/apps/portal/src/components/offers/types.ts
index 1841a3a5..bab501df 100644
--- a/apps/portal/src/components/offers/types.ts
+++ b/apps/portal/src/components/offers/types.ts
@@ -158,3 +158,14 @@ export type BackgroundCard = {
specificYoes: Array;
totalYoe: string;
};
+
+export type CommentEntity = {
+ createdAt: Date;
+ id: string;
+ message: string;
+ profileId: string;
+ replies?: Array;
+ replyingToId: string;
+ userId: string;
+ username: string;
+};
diff --git a/apps/portal/src/utils/offers/time.tsx b/apps/portal/src/utils/offers/time.tsx
index c13a6efe..6cd5f16e 100644
--- a/apps/portal/src/utils/offers/time.tsx
+++ b/apps/portal/src/utils/offers/time.tsx
@@ -2,6 +2,34 @@ import { getMonth, getYear } from 'date-fns';
import type { MonthYear } from '~/components/shared/MonthYearPicker';
+export function timeSinceNow(date: Date | number | string) {
+ const seconds = Math.floor(
+ new Date().getTime() / 1000 - new Date(date).getTime() / 1000,
+ );
+ let interval = seconds / 31536000;
+
+ if (interval > 1) {
+ return `${Math.floor(interval)} years`;
+ }
+ interval = seconds / 2592000;
+ if (interval > 1) {
+ return `${Math.floor(interval)} months`;
+ }
+ interval = seconds / 86400;
+ if (interval > 1) {
+ return `${Math.floor(interval)} days`;
+ }
+ interval = seconds / 3600;
+ if (interval > 1) {
+ return `${Math.floor(interval)} hours`;
+ }
+ interval = seconds / 60;
+ if (interval > 1) {
+ return `${Math.floor(interval)} minutes`;
+ }
+ return `${Math.floor(interval)} seconds`;
+}
+
export function formatDate(value: Date | number | string) {
const date = new Date(value);
// Const day = date.toLocaleString('default', { day: '2-digit' });