feat(components): add image preview, picker, and clear controls to AIToolbar
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
|
import Image from "next/image";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
|
import { ImagePicker } from "@/components/image-picker";
|
||||||
|
import { X } from "lucide-react";
|
||||||
|
|
||||||
interface AIToolbarProps {
|
interface AIToolbarProps {
|
||||||
isAuthenticated: boolean;
|
isAuthenticated: boolean;
|
||||||
@@ -8,6 +11,9 @@ interface AIToolbarProps {
|
|||||||
aiPrompt: string;
|
aiPrompt: string;
|
||||||
setAiPrompt: (prompt: string) => void;
|
setAiPrompt: (prompt: string) => void;
|
||||||
aiLoading: boolean;
|
aiLoading: boolean;
|
||||||
|
imagePreview: string | null;
|
||||||
|
onImageSelect: (file: File) => void;
|
||||||
|
onImageClear: () => void;
|
||||||
onAiCreate: () => void;
|
onAiCreate: () => void;
|
||||||
onAiSummarize: () => void;
|
onAiSummarize: () => void;
|
||||||
summary: string | null;
|
summary: string | null;
|
||||||
@@ -20,6 +26,9 @@ export const AIToolbar = ({
|
|||||||
aiPrompt,
|
aiPrompt,
|
||||||
setAiPrompt,
|
setAiPrompt,
|
||||||
aiLoading,
|
aiLoading,
|
||||||
|
imagePreview,
|
||||||
|
onImageSelect,
|
||||||
|
onImageClear,
|
||||||
onAiCreate,
|
onAiCreate,
|
||||||
onAiSummarize,
|
onAiSummarize,
|
||||||
summary,
|
summary,
|
||||||
@@ -39,12 +48,36 @@ export const AIToolbar = ({
|
|||||||
<Textarea
|
<Textarea
|
||||||
className="wrap-anywhere field-sizing-content resize-none w-full min-h-[2.5rem] max-h-64 overflow-y-auto sm:overflow-y-visible px-3 py-2 scroll-p-8 placeholder:italic"
|
className="wrap-anywhere field-sizing-content resize-none w-full min-h-[2.5rem] max-h-64 overflow-y-auto sm:overflow-y-visible px-3 py-2 scroll-p-8 placeholder:italic"
|
||||||
style={{ clipPath: "inset(0 round 1rem)" }}
|
style={{ clipPath: "inset(0 round 1rem)" }}
|
||||||
placeholder="Describe event for AI to create"
|
placeholder="Describe event or attach an image for AI to create"
|
||||||
value={aiPrompt}
|
value={aiPrompt}
|
||||||
onChange={(e) => setAiPrompt(e.target.value)}
|
onChange={(e) => setAiPrompt(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
{imagePreview && (
|
||||||
|
<div className="relative mt-2 inline-block">
|
||||||
|
<Image
|
||||||
|
src={imagePreview}
|
||||||
|
alt="Attached event flyer"
|
||||||
|
className="h-20 rounded-md object-cover border"
|
||||||
|
width={80}
|
||||||
|
height={80}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
size="icon"
|
||||||
|
className="absolute -top-2 -right-2 h-5 w-5"
|
||||||
|
onClick={onImageClear}
|
||||||
|
aria-label="Remove image"
|
||||||
|
>
|
||||||
|
<X className="h-3 w-3" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row gap-2 pt-1">
|
<div className="flex flex-row gap-2 pt-1">
|
||||||
|
<ImagePicker
|
||||||
|
onFileSelect={onImageSelect}
|
||||||
|
disabled={aiLoading}
|
||||||
|
/>
|
||||||
<Button onClick={onAiCreate} disabled={aiLoading}>
|
<Button onClick={onAiCreate} disabled={aiLoading}>
|
||||||
{aiLoading ? "Thinking..." : "AI Create"}
|
{aiLoading ? "Thinking..." : "AI Create"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user