mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 06:53:12 +00:00
Add four-tab activity section: Customer, Vendor, Internal, Audit Log
- Filter comments by commentType field (customer, vendor, internal) - Add AuditTimeline component showing field changes with old → new values - Pass auditLog from API response to view page
This commit is contained in:
parent
1958973968
commit
d979d5571a
3 changed files with 80 additions and 22 deletions
|
|
@ -30,6 +30,7 @@ export const getWorkOrderById = async (id) => {
|
|||
po: wo.po ?? "",
|
||||
tt: wo.tt ?? "",
|
||||
comments: wo.comments ?? [],
|
||||
auditLog: wo.auditLog ?? [],
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error fetching work order:", error);
|
||||
|
|
|
|||
|
|
@ -161,6 +161,32 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.woAuditItem {
|
||||
border-left-color: #6c757d;
|
||||
}
|
||||
|
||||
.woAuditField {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.woAuditOld {
|
||||
color: #dc3545;
|
||||
text-decoration: line-through;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.woAuditArrow {
|
||||
color: #999;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.woAuditNew {
|
||||
color: #28a745;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.loading {
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
|
|
|
|||
|
|
@ -35,12 +35,39 @@ function CommentTimeline({ comments }) {
|
|||
);
|
||||
}
|
||||
|
||||
function AuditTimeline({ entries }) {
|
||||
if (!entries || entries.length === 0) {
|
||||
return <p className="woNoComments">No changes recorded.</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="woTimeline">
|
||||
{entries.map((e) => (
|
||||
<div key={e.id} className="woTimelineItem woAuditItem">
|
||||
<div className="woTimelineHeader">
|
||||
<span className="woTimelineAuthor">{e.userName || "System"}</span>
|
||||
<span className="woTimelineDate">
|
||||
{e.createdAt ? formatDateTime(e.createdAt) : ""}
|
||||
</span>
|
||||
</div>
|
||||
<div className="woTimelineBody">
|
||||
<span className="woAuditField">{e.fieldName}</span>
|
||||
{e.oldValue && <span className="woAuditOld">{e.oldValue}</span>}
|
||||
<span className="woAuditArrow">→</span>
|
||||
<span className="woAuditNew">{e.newValue}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function WorkOrderViewPage() {
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [wo, setWo] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [commentTab, setCommentTab] = useState("customer");
|
||||
const [activeTab, setActiveTab] = useState("customer");
|
||||
|
||||
useEffect(() => {
|
||||
const load = async () => {
|
||||
|
|
@ -61,12 +88,18 @@ export default function WorkOrderViewPage() {
|
|||
|
||||
const statusClass = (wo.status || "").toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
const customerComments = (wo.comments || []).filter(
|
||||
(c) => c.recordType || c.commenter
|
||||
);
|
||||
const vendorComments = (wo.comments || []).filter(
|
||||
(c) => !c.recordType && !c.commenter && c.userName
|
||||
);
|
||||
const allComments = wo.comments || [];
|
||||
const customerComments = allComments.filter((c) => c.commentType === "customer");
|
||||
const vendorComments = allComments.filter((c) => c.commentType === "vendor");
|
||||
const internalComments = allComments.filter((c) => c.commentType === "internal");
|
||||
const auditLog = wo.auditLog || [];
|
||||
|
||||
const tabs = [
|
||||
{ key: "customer", label: "Customer", count: customerComments.length },
|
||||
{ key: "vendor", label: "Vendor", count: vendorComments.length },
|
||||
{ key: "internal", label: "Internal", count: internalComments.length },
|
||||
{ key: "audit", label: "Audit Log", count: auditLog.length },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="woViewPage">
|
||||
|
|
@ -145,22 +178,20 @@ export default function WorkOrderViewPage() {
|
|||
<div className="woViewSection">
|
||||
<h4>Activity</h4>
|
||||
<div className="woCommentTabs">
|
||||
<button
|
||||
className={`woCommentTab ${commentTab === "customer" ? "active" : ""}`}
|
||||
onClick={() => setCommentTab("customer")}
|
||||
>
|
||||
Customer ({customerComments.length})
|
||||
</button>
|
||||
<button
|
||||
className={`woCommentTab ${commentTab === "vendor" ? "active" : ""}`}
|
||||
onClick={() => setCommentTab("vendor")}
|
||||
>
|
||||
Vendor ({vendorComments.length})
|
||||
</button>
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.key}
|
||||
className={`woCommentTab ${activeTab === tab.key ? "active" : ""}`}
|
||||
onClick={() => setActiveTab(tab.key)}
|
||||
>
|
||||
{tab.label} ({tab.count})
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<CommentTimeline
|
||||
comments={commentTab === "customer" ? customerComments : vendorComments}
|
||||
/>
|
||||
{activeTab === "customer" && <CommentTimeline comments={customerComments} />}
|
||||
{activeTab === "vendor" && <CommentTimeline comments={vendorComments} />}
|
||||
{activeTab === "internal" && <CommentTimeline comments={internalComments} />}
|
||||
{activeTab === "audit" && <AuditTimeline entries={auditLog} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue