feat: implement ThreadChat component and enhance Messages and CommentThreads with improved structure and styling
This commit is contained in:
parent
5c6116a01c
commit
43adb0137a
|
@ -18,19 +18,19 @@ const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked }) => {
|
||||||
lastUpdatedAt: "string",
|
lastUpdatedAt: "string",
|
||||||
replies: [
|
replies: [
|
||||||
{
|
{
|
||||||
replyId: 'string',
|
replyId: "string",
|
||||||
creatorId: 'string',
|
creatorId: "string",
|
||||||
createdAt: 'string',
|
createdAt: "string",
|
||||||
lastUpdatedAt: 'string',
|
lastUpdatedAt: "string",
|
||||||
reply: 'string',
|
reply: "string",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
replyId: 'string',
|
replyId: "string",
|
||||||
creatorId: 'string',
|
creatorId: "string",
|
||||||
createdAt: 'string',
|
createdAt: "string",
|
||||||
lastUpdatedAt: 'string',
|
lastUpdatedAt: "string",
|
||||||
reply: 'string',
|
reply: "string",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,8 +54,9 @@ const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked }) => {
|
||||||
onPointerEnter={() => getDetails()}
|
onPointerEnter={() => getDetails()}
|
||||||
onPointerLeave={() => getDetails()}
|
onPointerLeave={() => getDetails()}
|
||||||
onClick={() => getDetails("clicked")}
|
onClick={() => getDetails("clicked")}
|
||||||
className={`comments-threads-container ${expand ? "open" : "closed"
|
className={`comments-threads-container ${
|
||||||
} unread`}
|
expand ? "open" : "closed"
|
||||||
|
} unread`}
|
||||||
>
|
>
|
||||||
<div className="users-commented">
|
<div className="users-commented">
|
||||||
{commentsedUsers.map((val, i) => (
|
{commentsedUsers.map((val, i) => (
|
||||||
|
@ -79,7 +80,10 @@ const CommentThreads: React.FC<CommentThreadsProps> = ({ commentClicked }) => {
|
||||||
</div>
|
</div>
|
||||||
<div className="message">{CommentDetails.comment}</div>
|
<div className="message">{CommentDetails.comment}</div>
|
||||||
{CommentDetails.replies.length > 0 && (
|
{CommentDetails.replies.length > 0 && (
|
||||||
<div className="replies">{CommentDetails.replies.length} reply(s)</div>
|
<div className="replies">
|
||||||
|
{CommentDetails.replies.length}{" "}
|
||||||
|
{CommentDetails.replies.length === 1 ? "reply" : "replies"}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -17,7 +17,19 @@ const Messages: React.FC<MessageProps> = ({ val, i }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isEditing ? (
|
{isEditing ? (
|
||||||
<>
|
<div className="edit-container">
|
||||||
|
<div className="input-container">
|
||||||
|
<textarea />
|
||||||
|
</div>
|
||||||
|
<div className="actions-container">
|
||||||
|
<div className="actions">
|
||||||
|
<button className="cancel-button">Cancel</button>
|
||||||
|
<button className="save-button">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="message-container">
|
||||||
<div
|
<div
|
||||||
className="profile"
|
className="profile"
|
||||||
style={{ background: getAvatarColor(i, UserName) }}
|
style={{ background: getAvatarColor(i, UserName) }}
|
||||||
|
@ -54,18 +66,7 @@ const Messages: React.FC<MessageProps> = ({ val, i }) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
<div className="message">{val.reply}</div>
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<div className="edit-container">
|
|
||||||
<div className="input-container">
|
|
||||||
<textarea />
|
|
||||||
</div>
|
|
||||||
<div className="actions-container">
|
|
||||||
<div className="actions">
|
|
||||||
<button className="cancel-button">Cancel</button>
|
|
||||||
<button className="save-button">Save</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { CloseIcon, KebabIcon } from "../../icons/ExportCommonIcons";
|
import { CloseIcon, KebabIcon } from "../../icons/ExportCommonIcons";
|
||||||
import Messages from "./Messages";
|
import Messages from "./Messages";
|
||||||
import { ExpandIcon } from "../../icons/SimulationIcons";
|
import { ExpandIcon } from "../../icons/SimulationIcons";
|
||||||
|
|
||||||
const ThreadChat: React.FC = () => {
|
const ThreadChat: React.FC = () => {
|
||||||
|
const [openThreadOptions, setOpenThreadOptions] = useState(false);
|
||||||
const messages = [
|
const messages = [
|
||||||
{
|
{
|
||||||
replyId: "user 1",
|
replyId: "user 1",
|
||||||
|
@ -13,11 +14,11 @@ const ThreadChat: React.FC = () => {
|
||||||
reply: "true",
|
reply: "true",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
userName: "user 2",
|
replyId: "user 2",
|
||||||
userId: "2",
|
creatorId: "2",
|
||||||
message: "hello, thread check",
|
createdAt: "hello, thread check",
|
||||||
creationTime: "2 hrs ago",
|
lastUpdatedAt: "2 hrs ago",
|
||||||
idEdited: "true",
|
reply: "true",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -27,14 +28,21 @@ const ThreadChat: React.FC = () => {
|
||||||
<div className="header-wrapper">
|
<div className="header-wrapper">
|
||||||
<div className="header">Comment</div>
|
<div className="header">Comment</div>
|
||||||
<div className="header-options">
|
<div className="header-options">
|
||||||
<button className="options-button">
|
<button
|
||||||
|
className="options-button"
|
||||||
|
onClick={() => {
|
||||||
|
setOpenThreadOptions(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
<KebabIcon />
|
<KebabIcon />
|
||||||
</button>
|
</button>
|
||||||
<div className="options-list">
|
{openThreadOptions && (
|
||||||
<div className="options">Mark as Unread</div>
|
<div className="options-list">
|
||||||
<div className="options">Mark as Resolved</div>
|
<div className="options">Mark as Unread</div>
|
||||||
<div className="options">Delete Thread</div>
|
<div className="options">Mark as Resolved</div>
|
||||||
</div>
|
<div className="options">Delete Thread</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<button className="close-button">
|
<button className="close-button">
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</button>
|
</button>
|
||||||
|
@ -42,16 +50,16 @@ const ThreadChat: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="messages-wrapper">
|
<div className="messages-wrapper">
|
||||||
{messages.map((val, i) => (
|
{messages.map((val, i) => (
|
||||||
<Messages val={val as Reply} i={i} key={val.userId} />
|
<Messages val={val as Reply} i={i} key={val.replyId} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="send-message-wrapper">
|
<div className="send-message-wrapper">
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<input type="text" />
|
<input type="text" />
|
||||||
<div className="sent-button">
|
<div className="sent-button">
|
||||||
<ExpandIcon />
|
<ExpandIcon />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -38,6 +38,7 @@ import {useToggleStore} from "../store/useUIToggleStore";
|
||||||
import RegularDropDown from "../components/ui/inputs/RegularDropDown";
|
import RegularDropDown from "../components/ui/inputs/RegularDropDown";
|
||||||
import VersionSaved from "../components/layout/sidebarRight/versionHisory/VersionSaved";
|
import VersionSaved from "../components/layout/sidebarRight/versionHisory/VersionSaved";
|
||||||
import SimulationPlayer from "../components/ui/simulation/simulationPlayer";
|
import SimulationPlayer from "../components/ui/simulation/simulationPlayer";
|
||||||
|
import ThreadChat from "../components/ui/collaboration/ThreadChat";
|
||||||
|
|
||||||
const Project: React.FC = () => {
|
const Project: React.FC = () => {
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
|
@ -180,6 +181,7 @@ const Project: React.FC = () => {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<VersionSaved />
|
<VersionSaved />
|
||||||
|
<ThreadChat />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -83,3 +83,69 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.thread-char-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
// remove later
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
// ----
|
||||||
|
z-index: 10000;
|
||||||
|
.thread-char-container {
|
||||||
|
.header-wrapper {
|
||||||
|
.header {
|
||||||
|
}
|
||||||
|
.header-options {
|
||||||
|
.options-button {
|
||||||
|
}
|
||||||
|
.options-list {
|
||||||
|
.options {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.close-button {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.messages-wrapper {
|
||||||
|
.edit-container {
|
||||||
|
.input-container {
|
||||||
|
}
|
||||||
|
.actions-container {
|
||||||
|
.actions {
|
||||||
|
.cancel-button {
|
||||||
|
}
|
||||||
|
.save-button {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.message-container {
|
||||||
|
.profile {
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
.user-details {
|
||||||
|
.user-name {
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.more-options {
|
||||||
|
.more-options-button {
|
||||||
|
}
|
||||||
|
.options-list {
|
||||||
|
.option {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.send-message-wrapper {
|
||||||
|
.input-container {
|
||||||
|
.sent-button {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue