From 1ea774df581b0684ba9b6ad4f12fb25d34e70b84 Mon Sep 17 00:00:00 2001 From: Kumbham Ajay Goud Date: Sat, 12 Jul 2025 19:33:29 +0530 Subject: [PATCH] feat(ui): add ToolResultCard component for displaying tool results --- src/client/components/ToolResultCard.js | 108 ++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/client/components/ToolResultCard.js diff --git a/src/client/components/ToolResultCard.js b/src/client/components/ToolResultCard.js new file mode 100644 index 00000000..8b63f325 --- /dev/null +++ b/src/client/components/ToolResultCard.js @@ -0,0 +1,108 @@ +import React, { useState } from "react" +import PropTypes from "prop-types" +import { IconCalendarEvent, IconUser, IconChevronDown, IconChevronUp, IconExternalLink } from "@tabler/icons-react" + +/** + * ToolResultCard Component - Displays a tool result (e.g., event details) in a styled card. + * + * @param {object} props - Component props. + * @param {string} props.title - Main title of the result (e.g., event name). + * @param {string} [props.subtitle] - Subtitle or secondary info (e.g., date/time). + * @param {object|array} [props.details] - Additional details (object or array of key-value pairs). + * @param {array} [props.attendees] - List of attendees (array of strings or objects). + * @param {string} [props.externalLink] - Optional external link for more info. + * @returns {React.ReactNode} + */ +const ToolResultCard = ({ title, subtitle, details, attendees, externalLink }) => { + const [expanded, setExpanded] = useState(false) + + const handleToggle = () => setExpanded((prev) => !prev) + + return ( +
+ {/* Header */} +
+ +

{title}

+ {externalLink && ( + + + Open + + )} +
+ {subtitle &&
{subtitle}
} + {/* Expand/collapse details */} + + {expanded && ( +
+ {/* Render details as key-value pairs if object, or as list if array */} + {details && typeof details === "object" && !Array.isArray(details) && ( +
    + {Object.entries(details).map(([key, value]) => ( +
  • + {key}: {String(value)} +
  • + ))} +
+ )} + {details && Array.isArray(details) && ( +
    + {details.map((item, idx) => ( +
  • {String(item)}
  • + ))} +
+ )} + {/* Attendees */} + {attendees && attendees.length > 0 && ( +
+
+ + Attendees: +
+
    + {attendees.map((att, idx) => ( +
  • + {typeof att === "string" ? att : att.name || JSON.stringify(att)} +
  • + ))} +
+
+ )} +
+ )} +
+ ) +} + +ToolResultCard.propTypes = { + title: PropTypes.string.isRequired, + subtitle: PropTypes.string, + details: PropTypes.oneOfType([ + PropTypes.object, + PropTypes.array + ]), + attendees: PropTypes.arrayOf( + PropTypes.oneOfType([ + PropTypes.string, + PropTypes.object + ]) + ), + externalLink: PropTypes.string +} + +export default ToolResultCard \ No newline at end of file