(fix:ui) tool cards

This commit is contained in:
ManishMadan2882
2025-03-07 17:19:14 +05:30
parent d891c8dae2
commit 773147701d
3 changed files with 92 additions and 115 deletions

View File

@@ -8,10 +8,10 @@ export type InputProps = {
maxLength?: number; maxLength?: number;
name?: string; name?: string;
placeholder?: string; placeholder?: string;
label?: string;
required?: boolean; required?: boolean;
className?: string; className?: string;
children?: React.ReactElement; children?: React.ReactElement;
labelBgClassName?: string;
onChange: ( onChange: (
e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>, e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,
) => void; ) => void;

View File

@@ -94,57 +94,60 @@ export default function AddToolModal({
{modalState === 'ACTIVE' && ( {modalState === 'ACTIVE' && (
<WrapperComponent <WrapperComponent
close={() => setModalState('INACTIVE')} close={() => setModalState('INACTIVE')}
className="h-[85vh] w-[90vw] md:w-[75vw]" className="max-w-[950px] w-[90vw] md:w-[85vw] lg:w-[75vw] h-[85vh]"
> >
<div className="flex flex-col gap-4 h-full"> <div className="flex flex-col h-full">
<div> <div>
<h2 className="font-semibold text-xl text-jet dark:text-bright-gray px-3"> <h2 className="font-semibold text-xl text-jet dark:text-bright-gray px-3">
{t('settings.tools.selectToolSetup')} {t('settings.tools.selectToolSetup')}
</h2> </h2>
<div className="mt-5 flex flex-col sm:grid sm:grid-cols-3 gap-4 h-[73vh] overflow-auto px-3 py-px"> <div className="mt-5 h-[73vh] overflow-auto px-3 py-px">
{loading ? ( {loading ? (
<div className="h-full col-span-3 flex items-center justify-center"> <div className="h-full flex items-center justify-center">
<Spinner /> <Spinner />
</div> </div>
) : ( ) : (
availableTools.map((tool, index) => ( <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 auto-rows-fr">
<div {availableTools.map((tool, index) => (
role="button" <div
tabIndex={0} role="button"
key={index} tabIndex={0}
className="h-52 w-full p-6 border rounded-2xl border-silver dark:border-[#4D4E58] flex flex-col justify-between dark:bg-[#32333B] cursor-pointer hover:border-[#9d9d9d] hover:dark:border-[#717179]" key={index}
onClick={() => { className="h-52 w-full p-6 border rounded-2xl border-light-gainsboro dark:border-arsenic bg-white-3000 dark:bg-gunmetal flex flex-col justify-between cursor-pointer hover:border-[#9d9d9d] hover:dark:border-[#717179]"
setSelectedTool(tool); onClick={() => {
handleAddTool(tool);
}}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
setSelectedTool(tool); setSelectedTool(tool);
handleAddTool(tool); handleAddTool(tool);
} }}
}} onKeyDown={(e) => {
> if (e.key === 'Enter' || e.key === ' ') {
<div className="w-full"> setSelectedTool(tool);
<div className="px-1 w-full flex items-center justify-between"> handleAddTool(tool);
<img }
src={`/toolIcons/tool_${tool.name}.svg`} }}
className="h-8 w-8" >
/> <div className="w-full">
</div> <div className="px-1 w-full flex items-center justify-between">
<div className="mt-[9px]"> <img
<p src={`/toolIcons/tool_${tool.name}.svg`}
title={tool.displayName} className="h-6 w-6"
className="px-1 text-sm font-semibold text-eerie-black dark:text-white leading-relaxed capitalize truncate" alt={`${tool.name} icon`}
> />
{tool.displayName} </div>
</p> <div className="mt-[9px]">
<p className="mt-1 px-1 h-24 overflow-auto text-sm text-gray-600 dark:text-[#8a8a8c] leading-relaxed"> <p
{tool.description} title={tool.displayName}
</p> className="px-1 text-[13px] font-semibold text-raisin-black-light dark:text-bright-gray leading-relaxed capitalize truncate"
>
{tool.displayName}
</p>
<p className="mt-1 px-1 h-24 overflow-auto text-[12px] text-old-silver dark:text-sonic-silver-light leading-relaxed">
{tool.description}
</p>
</div>
</div> </div>
</div> </div>
</div> ))}
)) </div>
)} )}
</div> </div>
</div> </div>

View File

@@ -3,19 +3,16 @@ import { useTranslation } from 'react-i18next';
import userService from '../api/services/userService'; import userService from '../api/services/userService';
import CogwheelIcon from '../assets/cogwheel.svg'; import CogwheelIcon from '../assets/cogwheel.svg';
import NoFilesDarkIcon from '../assets/no-files-dark.svg';
import NoFilesIcon from '../assets/no-files.svg';
import Input from '../components/Input'; import Input from '../components/Input';
import Spinner from '../components/Spinner'; import Spinner from '../components/Spinner';
import { useDarkTheme } from '../hooks';
import AddToolModal from '../modals/AddToolModal'; import AddToolModal from '../modals/AddToolModal';
import { ActiveState } from '../models/misc'; import { ActiveState } from '../models/misc';
import ToolConfig from './ToolConfig'; import ToolConfig from './ToolConfig';
import { APIToolType, UserToolType } from './types'; import { APIToolType, UserToolType } from './types';
import ToggleSwitch from '../components/ToggleSwitch';
export default function Tools() { export default function Tools() {
const { t } = useTranslation(); const { t } = useTranslation();
const [isDarkTheme] = useDarkTheme();
const [searchTerm, setSearchTerm] = React.useState(''); const [searchTerm, setSearchTerm] = React.useState('');
const [addToolModalState, setAddToolModalState] = const [addToolModalState, setAddToolModalState] =
React.useState<ActiveState>('INACTIVE'); React.useState<ActiveState>('INACTIVE');
@@ -114,7 +111,7 @@ export default function Tools() {
/> />
</div> </div>
<button <button
className="rounded-full min-w-[160px] bg-purple-30 px-6 py-3 text-white hover:bg-[#6F3FD1] text-nowrap" className="rounded-full w-[108px] h-[30px] text-sm bg-purple-30 text-white hover:bg-[#6F3FD1] flex items-center justify-center"
onClick={() => { onClick={() => {
setAddToolModalState('ACTIVE'); setAddToolModalState('ACTIVE');
}} }}
@@ -122,6 +119,7 @@ export default function Tools() {
{t('settings.tools.addTool')} {t('settings.tools.addTool')}
</button> </button>
</div> </div>
<div className="border-b border-light-silver dark:border-dim-gray mb-8 mt-5" />
{loading ? ( {loading ? (
<div className="grid grid-cols-2 lg:grid-cols-3 gap-6"> <div className="grid grid-cols-2 lg:grid-cols-3 gap-6">
<div className="mt-24 h-32 col-span-2 lg:col-span-3 flex items-center justify-center"> <div className="mt-24 h-32 col-span-2 lg:col-span-3 flex items-center justify-center">
@@ -129,90 +127,66 @@ export default function Tools() {
</div> </div>
</div> </div>
) : ( ) : (
<div className="grid grid-cols-2 lg:grid-cols-3 gap-6"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4">
{userTools.filter((tool) => {userTools
tool.displayName .filter((tool) =>
.toLowerCase() tool.displayName
.includes(searchTerm.toLowerCase()), .toLowerCase()
).length === 0 ? ( .includes(searchTerm.toLowerCase()),
<div className="mt-24 col-span-2 lg:col-span-3 text-center text-gray-500 dark:text-gray-400"> )
<img .map((tool, index) => (
src={isDarkTheme ? NoFilesDarkIcon : NoFilesIcon} <div
alt="No tools found" key={index}
className="h-24 w-24 mx-auto mb-2" className="relative h-52 border rounded-2xl border-light-gainsboro dark:border-arsenic"
/> >
{t('settings.tools.noToolsFound')} <div className="h-full flex flex-col p-6">
</div> <button
) : ( onClick={() => handleSettingsClick(tool)}
userTools aria-label={t('settings.tools.configureToolAria', {
.filter((tool) => toolName: tool.displayName,
tool.displayName })}
.toLowerCase() className="absolute top-4 right-4"
.includes(searchTerm.toLowerCase()), >
) <img
.map((tool, index) => ( src={CogwheelIcon}
<div alt={t('settings.tools.settingsIconAlt')}
key={index} className="h-[19px] w-[19px]"
className="relative h-56 w-full p-6 border rounded-2xl border-silver dark:border-silver/40 flex flex-col justify-between" />
> </button>
<div className="w-full"> <div className="flex-1">
<div className="w-full flex items-center justify-between"> <div className="flex flex-col items-start space-y-3">
<img <img
src={`/toolIcons/tool_${tool.name}.svg`} src={`/toolIcons/tool_${tool.name}.svg`}
alt={`${tool.displayName} icon`} alt={`${tool.displayName} icon`}
className="h-8 w-8" className="h-6 w-6"
/> />
<button <p
className="absolute top-3 right-3 cursor-pointer" title={tool.displayName}
onClick={() => handleSettingsClick(tool)} className="w-[calc(100%-24px)] text-[13px] font-semibold text-raisin-black-light dark:text-bright-gray capitalize truncate"
aria-label={t(
'settings.tools.configureToolAria',
{
toolName: tool.displayName,
},
)}
> >
<img
src={CogwheelIcon}
alt={t('settings.tools.settingsIconAlt')}
className="h-[19px] w-[19px]"
/>
</button>
</div>
<div className="mt-[9px]">
<p className="text-sm font-semibold text-eerie-black dark:text-[#EEEEEE] leading-relaxed">
{tool.displayName} {tool.displayName}
</p> </p>
<p className="mt-1 h-16 overflow-auto text-[13px] text-gray-600 dark:text-gray-400 leading-relaxed pr-1"> <p className="h-20 overflow-auto text-[12px] text-old-silver dark:text-sonic-silver-light">
{tool.description} {tool.description}
</p> </p>
</div> </div>
</div> </div>
<div className="absolute bottom-3 right-3"> <div className="flex justify-end pt-2">
<label <ToggleSwitch
htmlFor={`toolToggle-${index}`} checked={tool.status}
className="relative inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-300 dark:bg-[#D2D5DA33]/20 transition [-webkit-tap-highlight-color:_transparent] has-[:checked]:bg-[#0C9D35CC] has-[:checked]:dark:bg-[#0C9D35CC]" onChange={(checked) =>
> updateToolStatus(tool.id, checked)
<span className="sr-only"> }
{t('settings.tools.toggleToolAria', { size="small"
toolName: tool.displayName, id={`toolToggle-${index}`}
})} ariaLabel={t('settings.tools.toggleToolAria', {
</span> toolName: tool.displayName,
<input })}
type="checkbox" />
id={`toolToggle-${index}`}
className="peer sr-only"
checked={tool.status}
onChange={() =>
updateToolStatus(tool.id, !tool.status)
}
/>
<span className="absolute inset-y-0 start-0 m-[3px] size-[18px] rounded-full bg-white transition-all peer-checked:start-4"></span>
</label>
</div> </div>
</div> </div>
)) </div>
)} ))}
</div> </div>
)} )}
</div> </div>