simplified the new assistant text box

This commit is contained in:
arkml 2025-09-08 22:16:47 +05:30
parent a0734f7013
commit 86a33994b9
2 changed files with 53 additions and 41 deletions

View file

@ -2,7 +2,8 @@
import { forwardRef, TextareaHTMLAttributes } from 'react'; import { forwardRef, TextareaHTMLAttributes } from 'react';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { Send } from 'lucide-react'; import { Send, MoreVertical } from 'lucide-react';
import { Dropdown, DropdownItem, DropdownMenu, DropdownTrigger } from '@heroui/react';
import clsx from 'clsx'; import clsx from 'clsx';
interface TextareaWithSendProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> { interface TextareaWithSendProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> {
@ -11,6 +12,9 @@ interface TextareaWithSendProps extends Omit<TextareaHTMLAttributes<HTMLTextArea
onSubmit: () => void; onSubmit: () => void;
isSubmitting?: boolean; isSubmitting?: boolean;
submitDisabled?: boolean; submitDisabled?: boolean;
onImportJson?: () => void;
importDisabled?: boolean;
isImporting?: boolean;
placeholder?: string; placeholder?: string;
className?: string; className?: string;
rows?: number; rows?: number;
@ -25,6 +29,9 @@ export const TextareaWithSend = forwardRef<HTMLTextAreaElement, TextareaWithSend
onSubmit, onSubmit,
isSubmitting = false, isSubmitting = false,
submitDisabled = false, submitDisabled = false,
onImportJson,
importDisabled = false,
isImporting = false,
placeholder, placeholder,
className, className,
rows = 3, rows = 3,
@ -32,6 +39,7 @@ export const TextareaWithSend = forwardRef<HTMLTextAreaElement, TextareaWithSend
autoResize = false, autoResize = false,
...props ...props
}, ref) => { }, ref) => {
const hasMore = Boolean(onImportJson);
return ( return (
<div className="relative"> <div className="relative">
<Textarea <Textarea
@ -39,7 +47,11 @@ export const TextareaWithSend = forwardRef<HTMLTextAreaElement, TextareaWithSend
value={value} value={value}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
placeholder={placeholder} placeholder={placeholder}
className={clsx("pr-14", className)} className={clsx(
// Extra right padding for kebab + send controls
hasMore ? "pr-24" : "pr-14",
className
)}
rows={rows} rows={rows}
autoFocus={autoFocus} autoFocus={autoFocus}
autoResize={autoResize} autoResize={autoResize}
@ -51,7 +63,35 @@ export const TextareaWithSend = forwardRef<HTMLTextAreaElement, TextareaWithSend
}} }}
{...props} {...props}
/> />
<div className="absolute right-3 bottom-3"> <div className="absolute right-3 bottom-3 flex items-center gap-2">
{hasMore && (
<Dropdown>
<DropdownTrigger>
<button
className={clsx(
"rounded-full p-2 transition-all duration-200",
"bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:scale-105 active:scale-95 hover:bg-gray-200 dark:hover:bg-gray-700"
)}
aria-label="More actions"
title="More actions"
>
<MoreVertical size={18} />
</button>
</DropdownTrigger>
<DropdownMenu
aria-label="More actions"
onAction={(key) => {
if (key === 'import-json' && onImportJson) {
onImportJson();
}
}}
>
<DropdownItem key="import-json" isDisabled={importDisabled || isImporting}>
{isImporting ? 'Importing Assistant (JSON)…' : 'Import Assistant (JSON)'}
</DropdownItem>
</DropdownMenu>
</Dropdown>
)}
<button <button
onClick={onSubmit} onClick={onSubmit}
disabled={isSubmitting || submitDisabled || !value.trim()} disabled={isSubmitting || submitDisabled || !value.trim()}
@ -62,6 +102,8 @@ export const TextareaWithSend = forwardRef<HTMLTextAreaElement, TextareaWithSend
: "bg-gray-100 dark:bg-gray-800 text-gray-400 dark:text-gray-500", : "bg-gray-100 dark:bg-gray-800 text-gray-400 dark:text-gray-500",
isSubmitting ? "opacity-50" : "hover:scale-105 active:scale-95" isSubmitting ? "opacity-50" : "hover:scale-105 active:scale-95"
)} )}
aria-label="Send"
title="Send"
> >
{isSubmitting ? ( {isSubmitting ? (
<div className="animate-spin rounded-full h-5 w-5 border-b-2 border-current"></div> <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-current"></div>
@ -75,4 +117,4 @@ export const TextareaWithSend = forwardRef<HTMLTextAreaElement, TextareaWithSend
} }
); );
TextareaWithSend.displayName = 'TextareaWithSend'; TextareaWithSend.displayName = 'TextareaWithSend';

View file

@ -8,7 +8,7 @@ import clsx from 'clsx';
import Image from 'next/image'; import Image from 'next/image';
import mascotImage from '@/public/mascot.png'; import mascotImage from '@/public/mascot.png';
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Upload, ChevronLeftIcon, ChevronRightIcon } from "lucide-react"; import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
import { TextareaWithSend } from "@/app/components/ui/textarea-with-send"; import { TextareaWithSend } from "@/app/components/ui/textarea-with-send";
import { Workflow } from '../../lib/types/workflow_types'; import { Workflow } from '../../lib/types/workflow_types';
import { PictureImg } from '@/components/ui/picture-img'; import { PictureImg } from '@/components/ui/picture-img';
@ -276,6 +276,9 @@ export function BuildAssistantSection() {
setPromptError(null); setPromptError(null);
}} }}
onSubmit={handleCreateAssistant} onSubmit={handleCreateAssistant}
onImportJson={handleImportJsonClick}
isImporting={importLoading}
importDisabled={importLoading}
isSubmitting={isCreating} isSubmitting={isCreating}
placeholder="Example: Build me an assistant to manage my email and calendar..." placeholder="Example: Build me an assistant to manage my email and calendar..."
className={clsx( className={clsx(
@ -287,7 +290,7 @@ export function BuildAssistantSection() {
promptError && "border-red-500 focus:ring-red-500/20", promptError && "border-red-500 focus:ring-red-500/20",
!userPrompt && "animate-pulse border-2 border-indigo-500/40 dark:border-indigo-400/40 shadow-lg shadow-indigo-500/20 dark:shadow-indigo-400/20" !userPrompt && "animate-pulse border-2 border-indigo-500/40 dark:border-indigo-400/40 shadow-lg shadow-indigo-500/20 dark:shadow-indigo-400/20"
)} )}
rows={3} rows={4}
autoFocus autoFocus
autoResize autoResize
/> />
@ -298,40 +301,7 @@ export function BuildAssistantSection() {
)} )}
</div> </div>
{/* Separation line with OR */} {/* Removed separation line and secondary action per request */}
<div className="relative my-3">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-gray-300 dark:border-gray-600"></div>
</div>
<div className="relative flex justify-center text-sm">
<span className="bg-white dark:bg-gray-800 px-3 text-gray-500 dark:text-gray-400">OR</span>
</div>
</div>
{/* Action buttons */}
<div className="flex gap-3 justify-start">
<Button
variant="primary"
size="sm"
onClick={handleImportJsonClick}
type="button"
startContent={<Upload size={14} />}
className="bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-600 border border-gray-300 dark:border-gray-600"
disabled={importLoading}
>
{importLoading ? 'Importing...' : 'Import JSON'}
</Button>
<Button
variant="primary"
size="sm"
onClick={handleCreateAssistant}
isLoading={isCreating}
type="button"
className="bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-600 border border-gray-300 dark:border-gray-600"
>
Go to Builder
</Button>
</div>
{importError && ( {importError && (
<p className="text-sm text-red-500 mt-2"> <p className="text-sm text-red-500 mt-2">
@ -531,4 +501,4 @@ export function BuildAssistantSection() {
)} )}
</> </>
); );
} }