From d3a4bcc9842ae16084c6b2897dde579aeedab138 Mon Sep 17 00:00:00 2001 From: Adam Moussa <166072409+amoussa1229@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:22:34 -0400 Subject: [PATCH] Add comment input on Internal and Vendor tabs - Add CommentInput component with textarea and send button - Enter to send, Shift+Enter for new line - New comments append to the list immediately without reload - Fixed 400px height for tab content with scrollable overflow - Comment input bar pinned at bottom of tab container - Add addComment API function calling AddCommentJson endpoint - Auto-scroll to newest comment --- src/pages/workorders/api.js | 10 ++ .../workorders/view/WorkOrderViewPage.css | 46 +++++- .../workorders/view/WorkOrderViewPage.js | 154 ++++++++++++++---- 3 files changed, 174 insertions(+), 36 deletions(-) diff --git a/src/pages/workorders/api.js b/src/pages/workorders/api.js index bddd1c22..d0b19031 100644 --- a/src/pages/workorders/api.js +++ b/src/pages/workorders/api.js @@ -1,4 +1,6 @@ import { workOrderApi } from "../../services/api"; +import { post } from "../../apiUtil"; +import { API_URL } from "../../constants"; export const getWorkOrders = async (params = {}) => { try { @@ -68,6 +70,14 @@ export const editWorkOrder = async (workOrder) => { } }; +export const addComment = async (workOrderId, text, commentType = "internal") => { + return post(`${API_URL}/WorkOrder/AddCommentJson`, { + WorkorderId: workOrderId, + Text: text, + CommentType: commentType, + }); +}; + export const deleteWorkOrder = async (id) => { try { await workOrderApi.delete(id); diff --git a/src/pages/workorders/view/WorkOrderViewPage.css b/src/pages/workorders/view/WorkOrderViewPage.css index 31c02787..37c7357e 100644 --- a/src/pages/workorders/view/WorkOrderViewPage.css +++ b/src/pages/workorders/view/WorkOrderViewPage.css @@ -126,10 +126,23 @@ line-height: 1.5; } +.woTabContainer { + display: flex; + flex-direction: column; + height: 400px; + border: 1px solid #e5e5e5; + border-radius: 0 0 6px 6px; +} + +.woTabScroll { + flex: 1; + overflow-y: auto; + padding: 16px; +} + .woCommentTabs { display: flex; gap: 0; - margin-bottom: 16px; border-bottom: 2px solid #e5e5e5; } @@ -187,6 +200,37 @@ font-weight: 500; } +.woCommentInput { + display: flex; + gap: 8px; + padding: 12px 16px; + border-top: 1px solid #e5e5e5; + background: #f8f9fa; + flex-shrink: 0; +} + +.woCommentTextarea { + flex: 1; + border: 1px solid #ddd; + border-radius: 4px; + padding: 8px 12px; + font-size: 13px; + font-family: inherit; + resize: none; + line-height: 1.4; +} + +.woCommentTextarea:focus { + outline: none; + border-color: #007bff; +} + +.woCommentSend { + align-self: flex-end; + padding: 8px 16px; + font-size: 13px; +} + .loading { padding: 40px; text-align: center; diff --git a/src/pages/workorders/view/WorkOrderViewPage.js b/src/pages/workorders/view/WorkOrderViewPage.js index 5608d308..eaa3a83e 100644 --- a/src/pages/workorders/view/WorkOrderViewPage.js +++ b/src/pages/workorders/view/WorkOrderViewPage.js @@ -1,7 +1,7 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import { useParams, useNavigate } from "react-router"; import { toast } from "react-toastify"; -import { getWorkOrderById } from "../api"; +import { getWorkOrderById, addComment } from "../api"; import "./WorkOrderViewPage.css"; function formatDateTime(value) { @@ -14,54 +14,109 @@ function formatDateTime(value) { } function CommentTimeline({ comments }) { + const bottomRef = useRef(null); + + useEffect(() => { + bottomRef.current?.scrollIntoView(); + }, [comments?.length]); + if (!comments || comments.length === 0) { - return
No comments yet.
; + returnNo comments yet.
No changes recorded.
; + returnNo changes recorded.