diff --git a/frontend/src/components/Generic/Badges/Badge/index.jsx b/frontend/src/components/Generic/Badges/Badge/index.jsx index 0be7d849..2a04cf6a 100644 --- a/frontend/src/components/Generic/Badges/Badge/index.jsx +++ b/frontend/src/components/Generic/Badges/Badge/index.jsx @@ -3,10 +3,20 @@ import React from "react"; // Updated utility function for dark theme const colorMapping = (bg) => { const mappings = { - "emerald-600": { text: "text-emerald-100", icon: "text-emerald-200 group-hover:text-emerald-50" }, + "bg-green-500": { + text: "text-green-400", + icon: "text-green-600 group-hover:text-green-50", + ring: "ring-1 ring-inset ring-green-500/20", + }, }; - return mappings[bg] || { text: "text-gray-100", icon: "text-gray-200" }; + return ( + mappings[bg] || { + text: "text-white/60", + icon: "text-white/80 group-hover:text-white/50", + ring: "ring-1 ring-inset ring-gray-500/20", + } + ); }; // Badge Component @@ -18,18 +28,21 @@ export default function Badge({ shadow = "none", // "none", "sm", "md", "lg", "xl" showDot = false, showClose = false, - bg = "emerald-600", + bg = "bg-green-500", animated = false, onClose = () => {}, // Callback for close icon }) { - // Adjustments based on props - const { text: textColor, icon: iconColor } = colorMapping(bg); + const { + text: textColor, + icon: iconColor, + ring: ringClasses, + } = colorMapping(bg); const animatedClasses = animated ? "animate-pulse" : ""; const sizeClasses = { - sm: "py-0.5 pl-2 pr-0.5 text-xs", - md: "py-1 pl-2 pr-1 text-sm", - lg: "py-1 px-3 text-sm", - xl: "py-1.5 px-4 text-base", + sm: "py-0.5 px-2 pr-0.5 text-xs", + md: "py-1.5 px-2 pr-1 text-xs", + lg: "py-2 px-3 text-sm", + xl: "py-2.5 px-4 text-base", }[size]; const iconSizeClasses = { sm: "h-2 w-2", @@ -51,7 +64,7 @@ export default function Badge({ lg: "shadow-lg", xl: "shadow-xl", }[shadow]; - const backgroundClasses = `bg-${bg}`; + const backgroundClasses = `${bg} bg-opacity-10 hover:bg-opacity-20`; // SVG Icons const DotIcon = () => ( @@ -78,14 +91,14 @@ export default function Badge({ return (
{showDot && (
)} -

+

{label}

{showClose && ( @@ -98,4 +111,4 @@ export default function Badge({ )}
); -}; \ No newline at end of file +} diff --git a/frontend/src/components/Generic/Blocks/CheckBoxBlock/index.jsx b/frontend/src/components/Generic/Blocks/CheckBoxBlock/index.jsx index d6f34a46..190719e6 100644 --- a/frontend/src/components/Generic/Blocks/CheckBoxBlock/index.jsx +++ b/frontend/src/components/Generic/Blocks/CheckBoxBlock/index.jsx @@ -31,16 +31,10 @@ export default function CheckBoxBlock({ badgeBg, border, Icon, - contentLocation, disabled, inline = false, }) { const borderStyle = border ? "border border-gray-600 rounded-2xl p-4" : ""; - const contentPosition = { - middle: "middle", - top: "top", - bottom: "bottom", - }[contentLocation]; return (
diff --git a/frontend/src/components/Generic/Blocks/TextAreaBlock/index.jsx b/frontend/src/components/Generic/Blocks/TextAreaBlock/index.jsx index 8534156a..b28cfda4 100644 --- a/frontend/src/components/Generic/Blocks/TextAreaBlock/index.jsx +++ b/frontend/src/components/Generic/Blocks/TextAreaBlock/index.jsx @@ -13,6 +13,8 @@ export default function TextAreaBlock({ className, autoComplete, wrap, + code, + onSave, }) { return (
@@ -39,6 +41,8 @@ export default function TextAreaBlock({ className={className} autoComplete={autoComplete} wrap={wrap} + code={code} + onSave={onSave} />
); diff --git a/frontend/src/components/Generic/Blocks/TitleBlock/index.jsx b/frontend/src/components/Generic/Blocks/TitleBlock/index.jsx index b4722094..37da2ced 100644 --- a/frontend/src/components/Generic/Blocks/TitleBlock/index.jsx +++ b/frontend/src/components/Generic/Blocks/TitleBlock/index.jsx @@ -13,28 +13,34 @@ export default function TitleBlock({ bg, Icon, labelStyles, + divider, }) { const borderStyle = border ? "border border-gray-600 rounded-2xl p-4" : ""; const backgroundStyle = bg ? "bg-black/10" : ""; + const dividerStyle = divider + ? "pb-4 mb-8 border-white/10 border-b-2" + : "pb-2"; return (
-
+
- {Icon && } + {Icon && }
- + {label && ( + + )} {badge && (
-

- {description} -

+

{description}

{content}
diff --git a/frontend/src/components/Generic/Blocks/ToggleBlock/index.jsx b/frontend/src/components/Generic/Blocks/ToggleBlock/index.jsx index 5584eda0..0ba6c3c7 100644 --- a/frontend/src/components/Generic/Blocks/ToggleBlock/index.jsx +++ b/frontend/src/components/Generic/Blocks/ToggleBlock/index.jsx @@ -30,7 +30,7 @@ export default function ToggleBlock({
-
+
{Icon && }
@@ -44,7 +44,7 @@ export default function ToggleBlock({ />
)} -
{!inline && ( - +
+ +
)}
-

- {description} -

+

{description}

{content}
diff --git a/frontend/src/components/Generic/Inputs/CheckBox/index.jsx b/frontend/src/components/Generic/Inputs/CheckBox/index.jsx index a951068f..d231e9df 100644 --- a/frontend/src/components/Generic/Inputs/CheckBox/index.jsx +++ b/frontend/src/components/Generic/Inputs/CheckBox/index.jsx @@ -1,8 +1,12 @@ import React, { useState, useEffect } from "react"; -export default function CheckBox({ initialChecked, onToggle, name, disabled }) { +export default function CheckBox({ + initialChecked = false, + onToggle, + name, + disabled, +}) { const [isChecked, setIsChecked] = useState(initialChecked); - useEffect(() => { setIsChecked(initialChecked); }, [initialChecked]); diff --git a/frontend/src/components/Generic/Inputs/TextArea/index.jsx b/frontend/src/components/Generic/Inputs/TextArea/index.jsx index 1309b499..a9b275ee 100644 --- a/frontend/src/components/Generic/Inputs/TextArea/index.jsx +++ b/frontend/src/components/Generic/Inputs/TextArea/index.jsx @@ -1,4 +1,5 @@ -import React, { useState } from "react"; +import { ArrowsIn, ArrowsOut, Check } from "@phosphor-icons/react"; +import React, { useState, useRef, useEffect } from "react"; export default function TextArea({ defaultValue, @@ -11,44 +12,121 @@ export default function TextArea({ className = "", autoComplete = "off", wrap = "soft", + code = false, + onSave, }) { const [rows, setRows] = useState(initialRows); + const [isExpanded, setIsExpanded] = useState(false); + const [showExpandIcon, setShowExpandIcon] = useState(false); + const [content, setContent] = useState(defaultValue); + const [showSaveButton, setShowSaveButton] = useState(false); + const textAreaRef = useRef(null); + + useEffect(() => { + adjustRowsToFitContent(); + // Initial check to determine if the expand icon should be shown + checkForOverflow(); + }, [defaultValue]); + + const toggleExpansion = () => { + setIsExpanded(!isExpanded); + if (!isExpanded) { + adjustRowsToFitContent(true); + } else { + setRows(initialRows); + } + // After toggling, check again to see if the content overflows + setTimeout(checkForOverflow, 0); // Timeout ensures the DOM updates are applied + }; + + const adjustRowsToFitContent = (forceExpand = false) => { + const textarea = textAreaRef.current; + if (textarea) { + const lineHeight = 18; // Match this with your CSS + if (forceExpand || isExpanded) { + const currentRows = Math.ceil(textarea.scrollHeight / lineHeight); + setRows(currentRows); + } + checkForOverflow(); + } + }; const handleChange = (e) => { if (onChange) { onChange(e); } - - // Dynamically adjust rows - const textareaLineHeight = 24; - const previousRows = e.target.rows; - e.target.rows = initialRows; - - const currentRows = ~~(e.target.scrollHeight / textareaLineHeight); - - if (currentRows === previousRows) { - e.target.rows = currentRows; - } - - if (e.target.scrollHeight > e.target.clientHeight) { - e.target.rows = currentRows; - } - - setRows(currentRows); + adjustRowsToFitContent(); + setContent(e.target.value); + setShowSaveButton(true); }; + // Function to determine if the expand/collapse icon should be shown + const checkForOverflow = () => { + const textarea = textAreaRef.current; + if (textarea) { + // Check if the content overflows + const isOverflowing = textarea.scrollHeight > textarea.clientHeight; + setShowExpandIcon(isOverflowing); + } + }; + + // Handle save action + const handleSave = () => { + if (onSave) { + onSave(content); + setShowSaveButton(false); + } + }; + + const textColorClass = disabled ? "text-white/40" : "text-white/60"; + const codeClass = code ? "font-mono text-xs" : "text-sm"; + return ( -