117 lines
3.1 KiB
TypeScript
117 lines
3.1 KiB
TypeScript
import { Prompt } from '@/types/prompt';
|
|
import {
|
|
IconBulbFilled,
|
|
IconCheck,
|
|
IconTrash,
|
|
IconX,
|
|
} from '@tabler/icons-react';
|
|
import { DragEvent, FC, useEffect, useState } from 'react';
|
|
import { PromptModal } from './PromptModal';
|
|
|
|
interface Props {
|
|
prompt: Prompt;
|
|
onUpdatePrompt: (prompt: Prompt) => void;
|
|
onDeletePrompt: (prompt: Prompt) => void;
|
|
}
|
|
|
|
export const PromptComponent: FC<Props> = ({
|
|
prompt,
|
|
onUpdatePrompt,
|
|
onDeletePrompt,
|
|
}) => {
|
|
const [showModal, setShowModal] = useState<boolean>(false);
|
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
const [isRenaming, setIsRenaming] = useState(false);
|
|
const [renameValue, setRenameValue] = useState('');
|
|
|
|
const handleDragStart = (e: DragEvent<HTMLButtonElement>, prompt: Prompt) => {
|
|
if (e.dataTransfer) {
|
|
e.dataTransfer.setData('prompt', JSON.stringify(prompt));
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (isRenaming) {
|
|
setIsDeleting(false);
|
|
} else if (isDeleting) {
|
|
setIsRenaming(false);
|
|
}
|
|
}, [isRenaming, isDeleting]);
|
|
|
|
return (
|
|
<div className="relative flex items-center">
|
|
<button
|
|
className="flex w-full cursor-pointer items-center gap-3 rounded-lg p-3 text-sm transition-colors duration-200 hover:bg-[#343541]/90"
|
|
draggable="true"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
setShowModal(true);
|
|
}}
|
|
onDragStart={(e) => handleDragStart(e, prompt)}
|
|
onMouseLeave={() => {
|
|
setIsDeleting(false);
|
|
setIsRenaming(false);
|
|
setRenameValue('');
|
|
}}
|
|
>
|
|
<IconBulbFilled size={18} />
|
|
|
|
<div className="relative max-h-5 flex-1 overflow-hidden text-ellipsis whitespace-nowrap break-all pr-4 text-left text-[12.5px] leading-3">
|
|
{prompt.name}
|
|
</div>
|
|
</button>
|
|
|
|
{(isDeleting || isRenaming) && (
|
|
<div className="absolute right-1 z-10 flex text-gray-300">
|
|
<button
|
|
className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
|
|
if (isDeleting) {
|
|
onDeletePrompt(prompt);
|
|
}
|
|
|
|
setIsDeleting(false);
|
|
}}
|
|
>
|
|
<IconCheck size={18} />
|
|
</button>
|
|
|
|
<button
|
|
className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
setIsDeleting(false);
|
|
}}
|
|
>
|
|
<IconX size={18} />
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
{!isDeleting && !isRenaming && (
|
|
<div className="absolute right-1 z-10 flex text-gray-300">
|
|
<button
|
|
className="min-w-[20px] p-1 text-neutral-400 hover:text-neutral-100"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
setIsDeleting(true);
|
|
}}
|
|
>
|
|
<IconTrash size={18} />
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
{showModal && (
|
|
<PromptModal
|
|
prompt={prompt}
|
|
onClose={() => setShowModal(false)}
|
|
onUpdatePrompt={onUpdatePrompt}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|