diff --git a/app/api/agent-creator/route.ts b/app/api/agent-creator/route.ts deleted file mode 100644 index 8380a329c..000000000 --- a/app/api/agent-creator/route.ts +++ /dev/null @@ -1,47 +0,0 @@ -import getAccountById from "@/lib/supabase/accounts/getAccountById"; -import { ADMIN_EMAILS } from "@/lib/admin"; -import { NextRequest } from "next/server"; - -export const runtime = "edge"; - -export async function GET(req: NextRequest) { - const creatorId = req.nextUrl.searchParams.get("creatorId"); - - if (!creatorId) { - return Response.json({ message: "Missing creatorId" }, { status: 400 }); - } - - try { - const account = await getAccountById(creatorId); - - if (!account) { - return Response.json({ message: "Creator not found" }, { status: 404 }); - } - - const info = Array.isArray(account.account_info) - ? account.account_info[0] || null - : null; - const email = Array.isArray(account.account_emails) - ? account.account_emails[0]?.email || null - : null; - const isAdmin = !!email && ADMIN_EMAILS.includes(email); - - return Response.json( - { - creator: { - name: account.name || null, - image: info?.image || null, - is_admin: isAdmin, - }, - }, - { status: 200 }, - ); - } catch (e) { - const message = e instanceof Error ? e.message : "failed"; - return Response.json({ message }, { status: 400 }); - } -} - -export const dynamic = "force-dynamic"; -export const fetchCache = "force-no-store"; -export const revalidate = 0; diff --git a/app/api/agent-templates/favorites/route.ts b/app/api/agent-templates/favorites/route.ts deleted file mode 100644 index d1fb81729..000000000 --- a/app/api/agent-templates/favorites/route.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { NextResponse } from "next/server"; -import { addAgentTemplateFavorite } from "@/lib/supabase/agent_templates/addAgentTemplateFavorite"; -import { removeAgentTemplateFavorite } from "@/lib/supabase/agent_templates/removeAgentTemplateFavorite"; -import type { ToggleFavoriteRequest, ToggleFavoriteResponse } from "@/types/AgentTemplates"; - -export const runtime = "edge"; - -export async function POST(request: Request) { - try { - const { templateId, userId, isFavourite }: ToggleFavoriteRequest = await request.json(); - - if (!templateId || !userId) { - return NextResponse.json({ error: "Missing templateId or userId" }, { status: 400 }); - } - - if (isFavourite) { - await addAgentTemplateFavorite(templateId, userId); - } else { - await removeAgentTemplateFavorite(templateId, userId); - } - - return NextResponse.json({ success: true } as ToggleFavoriteResponse); - } catch (error) { - console.error("Error toggling favourite:", error); - return NextResponse.json({ error: "Failed to toggle favourite" } as ToggleFavoriteResponse, { status: 500 }); - } -} - -export const dynamic = "force-dynamic"; -export const revalidate = 0; - - diff --git a/app/api/agent-templates/route.ts b/app/api/agent-templates/route.ts deleted file mode 100644 index c594cd80f..000000000 --- a/app/api/agent-templates/route.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { NextResponse } from "next/server"; -// Supabase client is used in utilities imported below; no direct use here -import { getUserAccessibleTemplates } from "@/lib/supabase/agent_templates/getUserAccessibleTemplates"; -import { createAgentTemplate } from "@/lib/supabase/agent_templates/createAgentTemplate"; -import { updateAgentTemplate } from "@/lib/supabase/agent_templates/updateAgentTemplate"; -import { deleteAgentTemplate } from "@/lib/supabase/agent_templates/deleteAgentTemplate"; -import { verifyAgentTemplateOwner } from "@/lib/supabase/agent_templates/verifyAgentTemplateOwner"; -import { getSharedEmailsForTemplates } from "@/lib/supabase/agent_templates/getSharedEmailsForTemplates"; - -export const runtime = "edge"; - -export async function GET(request: Request) { - try { - const { searchParams } = new URL(request.url); - const userId = searchParams.get("userId"); - - const templates = await getUserAccessibleTemplates(userId ?? undefined); - - // Get shared emails for private templates - const privateTemplateIds = templates - .filter(template => template.is_private) - .map(template => template.id); - - let sharedEmails: Record = {}; - if (privateTemplateIds.length > 0) { - sharedEmails = await getSharedEmailsForTemplates(privateTemplateIds); - } - - // Add shared emails to templates - const templatesWithEmails = templates.map(template => ({ - ...template, - shared_emails: template.is_private ? (sharedEmails[template.id] || []) : [] - })); - - return NextResponse.json(templatesWithEmails); - } catch (error) { - console.error('Error fetching agent templates:', error); - return NextResponse.json({ error: 'Failed to fetch templates' }, { status: 500 }); - } -} - -export async function POST(request: Request) { - try { - const body = await request.json(); - const { - title, - description, - prompt, - tags, - isPrivate, - shareEmails, - userId, - }: { - title: string; - description: string; - prompt: string; - tags: string[]; - isPrivate: boolean; - shareEmails?: string[]; - userId?: string | null; - } = body; - - const data = await createAgentTemplate({ - title, - description, - prompt, - tags, - isPrivate, - shareEmails, - userId, - }); - return NextResponse.json(data, { status: 201 }); - } catch (error) { - console.error("Error creating agent template:", error); - return NextResponse.json({ error: "Failed to create template" }, { status: 500 }); - } -} - -export async function DELETE(request: Request) { - try { - const { id, userId } = (await request.json()) as { id: string; userId: string }; - if (!id || !userId) { - return NextResponse.json({ error: "Missing id or userId" }, { status: 400 }); - } - - const isOwner = await verifyAgentTemplateOwner(id, userId); - if (!isOwner) { - return NextResponse.json({ error: "Forbidden" }, { status: 403 }); - } - - await deleteAgentTemplate(id); - return NextResponse.json({ success: true }); - } catch (error) { - console.error("Error deleting template:", error); - return NextResponse.json({ error: "Failed to delete template" }, { status: 500 }); - } -} - -export async function PATCH(request: Request) { - try { - const body = await request.json(); - const { - id, - userId, - title, - description, - prompt, - tags, - isPrivate, - shareEmails, - }: { - id: string; - userId: string; - title?: string; - description?: string; - prompt?: string; - tags?: string[]; - isPrivate?: boolean; - shareEmails?: string[]; - } = body; - - if (!id || !userId) { - return NextResponse.json({ error: "Missing id or userId" }, { status: 400 }); - } - - const isOwner = await verifyAgentTemplateOwner(id, userId); - if (!isOwner) { - return NextResponse.json({ error: "Forbidden" }, { status: 403 }); - } - - const updateFields: { - title?: string; - description?: string; - prompt?: string; - tags?: string[]; - is_private?: boolean; - } = {}; - if (typeof title !== "undefined") updateFields.title = title; - if (typeof description !== "undefined") updateFields.description = description; - if (typeof prompt !== "undefined") updateFields.prompt = prompt; - if (typeof tags !== "undefined") updateFields.tags = tags; - if (typeof isPrivate !== "undefined") updateFields.is_private = isPrivate; - - const data = await updateAgentTemplate(id, updateFields, shareEmails); - return NextResponse.json(data); - } catch (error) { - console.error("Error updating agent template:", error); - return NextResponse.json({ error: "Failed to update template" }, { status: 500 }); - } -} - -export const dynamic = "force-dynamic"; -export const revalidate = 0; \ No newline at end of file diff --git a/components/Agents/AgentCard.tsx b/components/Agents/AgentCard.tsx index 5ca0dc271..6d3fc022e 100644 --- a/components/Agents/AgentCard.tsx +++ b/components/Agents/AgentCard.tsx @@ -1,5 +1,5 @@ import type React from "react"; -import { ExternalLink, Users} from "lucide-react"; +import { ExternalLink, Users } from "lucide-react"; import { Card, CardHeader, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import AgentCreator from "./AgentCreator"; @@ -9,7 +9,7 @@ import AgentDeleteButton from "./AgentDeleteButton"; import AgentHeart from "./AgentHeart"; import type { AgentTemplateRow } from "@/types/AgentTemplates"; import { useUserProvider } from "@/providers/UserProvder"; -import { useAgentCard } from "./useAgentCard"; +import { useAgentCard } from "@/hooks/useAgentCard"; type Agent = AgentTemplateRow; @@ -22,7 +22,7 @@ interface AgentCardProps { const AgentCard: React.FC = ({ agent, onClick, - onToggleFavorite + onToggleFavorite, }) => { const { userData } = useUserProvider(); @@ -31,11 +31,11 @@ const AgentCard: React.FC = ({ pillTag, handleCardKeyDown, handleCardClick, - handleToggleFavorite + handleToggleFavorite, } = useAgentCard({ agent, onClick, - onToggleFavorite + onToggleFavorite, }); return ( @@ -62,14 +62,19 @@ const AgentCard: React.FC = ({ {pillTag || "General"} {isSharedWithUser && ( - + Shared )}
-

{agent.title}

+

+ {agent.title} +

{agent.description}

@@ -83,22 +88,31 @@ const AgentCard: React.FC = ({
e.stopPropagation()}> handleToggleFavorite(agent.id ?? "", !(agent.is_favourite ?? false))} + onToggle={() => + handleToggleFavorite( + agent.id ?? "", + !(agent.is_favourite ?? false), + ) + } /> - {userData?.id && userData.id === agent.creator ? ( + {userData?.account_id && + userData.account_id === agent.creator?.id ? ( ) : ( )} - +
{/* Creator avatar or brand */} - +
); }; -export default AgentCard; \ No newline at end of file +export default AgentCard; diff --git a/components/Agents/AgentCreator.tsx b/components/Agents/AgentCreator.tsx index 77a6c566b..12dbc288b 100644 --- a/components/Agents/AgentCreator.tsx +++ b/components/Agents/AgentCreator.tsx @@ -1,39 +1,20 @@ "use client"; -import { useQuery } from "@tanstack/react-query"; import Image from "next/image"; import { Avatar, AvatarImage } from "@/components/ui/avatar"; +import type { AgentTemplateCreator } from "@/types/AgentTemplates"; interface AgentCreatorProps { - creatorId: string | null; + creator: AgentTemplateCreator | null; className?: string; } -type CreatorResponse = { - creator?: { - name?: string | null; - image?: string | null; - is_admin?: boolean | null; - } | null; -}; - -const AgentCreator = ({ creatorId, className }: AgentCreatorProps) => { - const { data } = useQuery({ - queryKey: ["agent-creator", creatorId], - queryFn: async () => { - const res = await fetch(`/api/agent-creator?creatorId=${creatorId}`, { cache: "no-store" }); - if (!res.ok) throw new Error("failed"); - return (await res.json()) as CreatorResponse; - }, - enabled: !!creatorId, - staleTime: 60_000, - }); - - const isAdmin = !!data?.creator?.is_admin; - const imageUrl = data?.creator?.image || ""; - const name = data?.creator?.name || ""; +const AgentCreator = ({ creator, className }: AgentCreatorProps) => { + const isAdmin = !!creator?.is_admin; + const imageUrl = creator?.image || ""; + const name = creator?.name || ""; - if (!creatorId || isAdmin) { + if (!creator || isAdmin) { return (
{ }; export default AgentCreator; - - diff --git a/components/Agents/AgentDeleteButton.tsx b/components/Agents/AgentDeleteButton.tsx index 51ef0a022..f8d250f22 100644 --- a/components/Agents/AgentDeleteButton.tsx +++ b/components/Agents/AgentDeleteButton.tsx @@ -12,40 +12,35 @@ import { } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { Trash2 } from "lucide-react"; -import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useUserProvider } from "@/providers/UserProvder"; +import { useDeleteAgentTemplate } from "@/hooks/useDeleteAgentTemplate"; interface AgentDeleteButtonProps { id: string; creatorId?: string | null; } -const AgentDeleteButton: React.FC = ({ id, creatorId }) => { +const AgentDeleteButton: React.FC = ({ + id, + creatorId, +}) => { const { userData } = useUserProvider(); - const queryClient = useQueryClient(); - const isOwner = Boolean(userData?.id && userData.id === creatorId); - - const del = useMutation({ - mutationFn: async () => { - const res = await fetch("/api/agent-templates", { - method: "DELETE", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ id, userId: userData?.id }), - }); - if (!res.ok) throw new Error("Failed to delete template"); - return res.json(); - }, - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["agent-templates"] }); - }, - }); + const del = useDeleteAgentTemplate(id); + const isOwner = Boolean( + userData?.account_id && userData.account_id === creatorId, + ); if (!isOwner) return null; return ( - @@ -53,12 +48,17 @@ const AgentDeleteButton: React.FC = ({ id, creatorId }) Delete this template? - This action cannot be undone. This will permanently delete the agent template. + This action cannot be undone. This will permanently delete the agent + template. Cancel - del.mutate()} disabled={del.isPending} className="bg-red-500 hover:bg-red-600 rounded-xl"> + del.mutate()} + disabled={del.isPending} + className="bg-red-500 hover:bg-red-600 rounded-xl" + > Delete @@ -68,5 +68,3 @@ const AgentDeleteButton: React.FC = ({ id, creatorId }) }; export default AgentDeleteButton; - - diff --git a/components/Agents/AgentEditDialog.tsx b/components/Agents/AgentEditDialog.tsx index 703151aaa..0f2c389a6 100644 --- a/components/Agents/AgentEditDialog.tsx +++ b/components/Agents/AgentEditDialog.tsx @@ -10,8 +10,7 @@ import { import { Button } from "@/components/ui/button"; import { Pencil } from "lucide-react"; import CreateAgentForm from "./CreateAgentForm"; -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { useUserProvider } from "@/providers/UserProvder"; +import { useUpdateAgentTemplate } from "@/hooks/useUpdateAgentTemplate"; import type { AgentTemplateRow } from "@/types/AgentTemplates"; import { useState, useEffect } from "react"; @@ -21,46 +20,10 @@ interface AgentEditDialogProps { const AgentEditDialog: React.FC = ({ agent }) => { const [open, setOpen] = useState(false); - const { userData } = useUserProvider(); - const queryClient = useQueryClient(); - const [currentSharedEmails, setCurrentSharedEmails] = useState(agent.shared_emails || []); - - const editTemplate = useMutation({ - mutationFn: async (values: { - title?: string; - description?: string; - prompt?: string; - tags?: string[]; - isPrivate?: boolean; - shareEmails?: string[]; - }) => { - // Combine existing emails (after removals) with new emails - const finalShareEmails = values.shareEmails && values.shareEmails.length > 0 - ? [...currentSharedEmails, ...values.shareEmails] - : currentSharedEmails; - - const res = await fetch("/api/agent-templates", { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - id: agent.id, - userId: userData?.id, - title: values.title, - description: values.description, - prompt: values.prompt, - tags: values.tags, - isPrivate: values.isPrivate, - shareEmails: finalShareEmails, - }), - }); - if (!res.ok) throw new Error("Failed to update template"); - return res.json(); - }, - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["agent-templates"] }); - setOpen(false); - }, - }); + const editTemplate = useUpdateAgentTemplate(agent.id); + const [currentSharedEmails, setCurrentSharedEmails] = useState( + agent.shared_emails || [], + ); const onSubmit = (values: { title: string; @@ -70,7 +33,23 @@ const AgentEditDialog: React.FC = ({ agent }) => { isPrivate: boolean; shareEmails?: string[]; }) => { - editTemplate.mutate(values); + // Combine existing emails (after removals) with new emails + const finalShareEmails = + values.shareEmails && values.shareEmails.length > 0 + ? [...currentSharedEmails, ...values.shareEmails] + : currentSharedEmails; + + editTemplate.mutate( + { + title: values.title, + description: values.description, + prompt: values.prompt, + tags: values.tags, + is_private: values.isPrivate, + share_emails: finalShareEmails, + }, + { onSuccess: () => setOpen(false) }, + ); }; const handleExistingEmailsChange = (emails: string[]) => { @@ -87,14 +66,23 @@ const AgentEditDialog: React.FC = ({ agent }) => { return ( - - Edit Agent - Update the agent template details. + + Edit Agent + + + Update the agent template details. + = ({ agent }) => { }; export default AgentEditDialog; - - diff --git a/components/Agents/AgentHeart.tsx b/components/Agents/AgentHeart.tsx index 0e3c42ae0..98fcd3336 100644 --- a/components/Agents/AgentHeart.tsx +++ b/components/Agents/AgentHeart.tsx @@ -12,7 +12,7 @@ interface AgentHeartProps { const AgentHeart: React.FC = ({ isFavorited, onToggle, - className + className, }) => { return ( diff --git a/components/Agents/AgentPreviewDialog.tsx b/components/Agents/AgentPreviewDialog.tsx index 5d59e28e1..448a7ba27 100644 --- a/components/Agents/AgentPreviewDialog.tsx +++ b/components/Agents/AgentPreviewDialog.tsx @@ -22,7 +22,11 @@ interface AgentPreviewDialogProps { const AgentPreviewDialog: React.FC = ({ agent }) => ( - @@ -43,25 +47,39 @@ const AgentPreviewDialog: React.FC = ({ agent }) => (
-
Prompt
+
+ Prompt +
-{agent.prompt}
+            {agent.prompt}
           
-
Tags
+
+ Tags +
{(agent.tags || []).map((t) => ( - {t} + + {t} + ))}
-
Updated
-
{agent.updated_at ? format(new Date(agent.updated_at), "PPpp") : "—"}
-
Creator
-
{agent.creator ?? "Recoup"}
+
+ Updated +
+
+ {agent.updated_at + ? format(new Date(agent.updated_at), "PPpp") + : "—"} +
+
+ Creator +
+
{agent.creator?.name ?? "Recoup"}
@@ -70,5 +88,3 @@ const AgentPreviewDialog: React.FC = ({ agent }) => ( ); export default AgentPreviewDialog; - - diff --git a/components/Agents/AgentTags.tsx b/components/Agents/AgentTags.tsx index b3bb48532..fcadaec94 100644 --- a/components/Agents/AgentTags.tsx +++ b/components/Agents/AgentTags.tsx @@ -31,4 +31,4 @@ const AgentTags: React.FC = ({
); -export default AgentTags; \ No newline at end of file +export default AgentTags; diff --git a/components/Agents/Agents.tsx b/components/Agents/Agents.tsx index f9f12c672..a7888078a 100644 --- a/components/Agents/Agents.tsx +++ b/components/Agents/Agents.tsx @@ -2,9 +2,9 @@ import { useRouter } from "next/navigation"; import React from "react"; import AgentTags from "./AgentTags"; import AgentCard from "./AgentCard"; -import { useAgentData } from "./useAgentData"; -import { useAgentToggleFavorite } from "./useAgentToggleFavorite"; -import type { Agent } from "./useAgentData"; +import { useAgentData } from "@/hooks/useAgentData"; +import { useAgentToggleFavorite } from "@/hooks/useAgentToggleFavorite"; +import type { Agent } from "@/hooks/useAgentData"; import CreateAgentButton from "./CreateAgentButton"; import { Switch } from "@/components/ui/switch"; import AgentsSkeleton from "./AgentsSkeleton"; @@ -39,7 +39,10 @@ const Agents = () => { {isPrivate ? "Private" : "Public"} - togglePrivate()} /> + togglePrivate()} + /> @@ -78,7 +81,9 @@ const Agents = () => { handleAgentClick(agent)} - onToggleFavorite={(id, next) => handleToggleFavorite(id, next)} + onToggleFavorite={(id, next) => + handleToggleFavorite(id, next) + } /> ))} diff --git a/components/Agents/AgentsSkeleton.tsx b/components/Agents/AgentsSkeleton.tsx index c04846a5d..1400b0717 100644 --- a/components/Agents/AgentsSkeleton.tsx +++ b/components/Agents/AgentsSkeleton.tsx @@ -4,7 +4,10 @@ const AgentsSkeleton = () => { return (
{Array.from({ length: 6 }).map((_, i) => ( -
+
{/* Header area matches CardHeader p-4 pb-2 */}
@@ -34,5 +37,3 @@ const AgentsSkeleton = () => { }; export default AgentsSkeleton; - - diff --git a/components/Agents/CreateAgentDialog.tsx b/components/Agents/CreateAgentDialog.tsx index bbcac6a10..d8c4991b8 100644 --- a/components/Agents/CreateAgentDialog.tsx +++ b/components/Agents/CreateAgentDialog.tsx @@ -9,8 +9,7 @@ import { import CreateAgentForm from "./CreateAgentForm"; import { useState } from "react"; import { type CreateAgentFormData } from "./schemas"; -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { useUserProvider } from "@/providers/UserProvder"; +import { useCreateAgentTemplate } from "@/hooks/useCreateAgentTemplate"; interface CreateAgentDialogProps { children: React.ReactNode; @@ -18,30 +17,20 @@ interface CreateAgentDialogProps { const CreateAgentDialog = ({ children }: CreateAgentDialogProps) => { const [open, setOpen] = useState(false); - const { userData } = useUserProvider(); - const queryClient = useQueryClient(); - - const createTemplate = useMutation({ - mutationFn: async (values: CreateAgentFormData) => { - const res = await fetch("/api/agent-templates", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - ...values, - userId: userData?.id ?? null, - }), - }); - if (!res.ok) throw new Error("Failed to create template"); - return res.json(); - }, - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["agent-templates"] }); - setOpen(false); - }, - }); + const createTemplate = useCreateAgentTemplate(); const onSubmit = (values: CreateAgentFormData) => { - createTemplate.mutate(values); + createTemplate.mutate( + { + title: values.title, + description: values.description, + prompt: values.prompt, + tags: values.tags, + is_private: values.isPrivate, + share_emails: values.shareEmails, + }, + { onSuccess: () => setOpen(false) }, + ); }; return ( @@ -56,7 +45,10 @@ const CreateAgentDialog = ({ children }: CreateAgentDialogProps) => { Create a new intelligent agent to help manage your roster tasks. - + ); diff --git a/components/Agents/CreateAgentForm.tsx b/components/Agents/CreateAgentForm.tsx index 03ceb38b4..420d4ab9d 100644 --- a/components/Agents/CreateAgentForm.tsx +++ b/components/Agents/CreateAgentForm.tsx @@ -16,7 +16,14 @@ interface CreateAgentFormProps { onExistingEmailsChange?: (emails: string[]) => void; } -const CreateAgentForm = ({ onSubmit, isSubmitting, initialValues, submitLabel, existingSharedEmails, onExistingEmailsChange }: CreateAgentFormProps) => { +const CreateAgentForm = ({ + onSubmit, + isSubmitting, + initialValues, + submitLabel, + existingSharedEmails, + onExistingEmailsChange, +}: CreateAgentFormProps) => { const form = useForm({ resolver: zodResolver(createAgentSchema), defaultValues: { @@ -44,7 +51,11 @@ const CreateAgentForm = ({ onSubmit, isSubmitting, initialValues, submitLabel, e
- + ); diff --git a/components/Agents/EmailShareInput.tsx b/components/Agents/EmailShareInput.tsx index 90196d4f1..a4c74fcbf 100644 --- a/components/Agents/EmailShareInput.tsx +++ b/components/Agents/EmailShareInput.tsx @@ -12,7 +12,12 @@ interface EmailShareInputProps { onExistingEmailsChange?: (emails: string[]) => void; } -const EmailShareInput = ({ emails, existingSharedEmails = [], onEmailsChange, onExistingEmailsChange }: EmailShareInputProps) => { +const EmailShareInput = ({ + emails, + existingSharedEmails = [], + onEmailsChange, + onExistingEmailsChange, +}: EmailShareInputProps) => { const [inputValue, setInputValue] = useState(""); const handleKeyDown = (e: React.KeyboardEvent) => { @@ -33,7 +38,10 @@ const EmailShareInput = ({ emails, existingSharedEmails = [], onEmailsChange, on } // Check if email already exists in either existing or new emails - if (emails.includes(trimmedEmail) || existingSharedEmails.includes(trimmedEmail)) { + if ( + emails.includes(trimmedEmail) || + existingSharedEmails.includes(trimmedEmail) + ) { setInputValue(""); return; } @@ -43,12 +51,14 @@ const EmailShareInput = ({ emails, existingSharedEmails = [], onEmailsChange, on }; const removeNewEmail = (emailToRemove: string) => { - onEmailsChange(emails.filter(email => email !== emailToRemove)); + onEmailsChange(emails.filter((email) => email !== emailToRemove)); }; const removeExistingEmail = (emailToRemove: string) => { if (onExistingEmailsChange) { - onExistingEmailsChange(existingSharedEmails.filter(email => email !== emailToRemove)); + onExistingEmailsChange( + existingSharedEmails.filter((email) => email !== emailToRemove), + ); } }; @@ -72,10 +82,7 @@ const EmailShareInput = ({ emails, existingSharedEmails = [], onEmailsChange, on emails={existingSharedEmails} onRemoveEmail={removeExistingEmail} /> - +
)}
diff --git a/components/Agents/ExistingSharedEmailsList.tsx b/components/Agents/ExistingSharedEmailsList.tsx index 2dd376026..aecea6c56 100644 --- a/components/Agents/ExistingSharedEmailsList.tsx +++ b/components/Agents/ExistingSharedEmailsList.tsx @@ -6,7 +6,10 @@ interface ExistingSharedEmailsListProps { onRemoveEmail?: (email: string) => void; } -const ExistingSharedEmailsList = ({ emails, onRemoveEmail }: ExistingSharedEmailsListProps) => { +const ExistingSharedEmailsList = ({ + emails, + onRemoveEmail, +}: ExistingSharedEmailsListProps) => { if (emails.length === 0) return null; return ( diff --git a/components/Agents/PrivacySection.tsx b/components/Agents/PrivacySection.tsx index 8b6a64141..846eeebd6 100644 --- a/components/Agents/PrivacySection.tsx +++ b/components/Agents/PrivacySection.tsx @@ -10,7 +10,11 @@ interface PrivacySectionProps { onExistingEmailsChange?: (emails: string[]) => void; } -const PrivacySection = ({ form, existingSharedEmails = [], onExistingEmailsChange }: PrivacySectionProps) => { +const PrivacySection = ({ + form, + existingSharedEmails = [], + onExistingEmailsChange, +}: PrivacySectionProps) => { const isPrivate = form.watch("isPrivate"); return ( @@ -29,7 +33,10 @@ const PrivacySection = ({ form, existingSharedEmails = [], onExistingEmailsChang emails={form.watch("shareEmails") ?? []} existingSharedEmails={existingSharedEmails} onEmailsChange={(emails) => { - form.setValue("shareEmails", emails, { shouldDirty: true, shouldValidate: true }); + form.setValue("shareEmails", emails, { + shouldDirty: true, + shouldValidate: true, + }); }} onExistingEmailsChange={onExistingEmailsChange} /> diff --git a/components/Agents/SubmitButton.tsx b/components/Agents/SubmitButton.tsx index fa197a45b..5bce53e82 100644 --- a/components/Agents/SubmitButton.tsx +++ b/components/Agents/SubmitButton.tsx @@ -22,7 +22,7 @@ const SubmitButton = ({ isSubmitting, submitLabel }: SubmitButtonProps) => { {submitLabel ? `${submitLabel}...` : "Saving..."} ) : ( - submitLabel ?? "Save" + (submitLabel ?? "Save") )}
diff --git a/components/Agents/TagSelector.tsx b/components/Agents/TagSelector.tsx index 70190e640..20ae1ab19 100644 --- a/components/Agents/TagSelector.tsx +++ b/components/Agents/TagSelector.tsx @@ -1,7 +1,7 @@ import { UseFormReturn } from "react-hook-form"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; -import { useAgentData } from "./useAgentData"; +import { useAgentData } from "@/hooks/useAgentData"; import { CreateAgentFormData } from "./schemas"; interface TagSelectorProps { @@ -24,32 +24,34 @@ const TagSelector = ({ form }: TagSelectorProps) => {
- {tags.filter((t) => t !== "Recommended").map((tag) => { - const isSelected = selectedTags.includes(tag); - return ( - toggleTag(tag)} - onKeyDown={(e) => { - if (e.key === "Enter" || e.key === " ") { - e.preventDefault(); - toggleTag(tag); + {tags + .filter((t) => t !== "Recommended") + .map((tag) => { + const isSelected = selectedTags.includes(tag); + return ( + toggleTag(tag)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + toggleTag(tag); + } + }} + className={ + isSelected + ? "cursor-pointer select-none rounded-full focus:ring-0" + : "cursor-pointer select-none rounded-full bg-transparent border-border text-muted-foreground hover:bg-muted focus:ring-0" } - }} - className={ - isSelected - ? "cursor-pointer select-none rounded-full focus:ring-0" - : "cursor-pointer select-none rounded-full bg-transparent border-border text-muted-foreground hover:bg-muted focus:ring-0" - } - variant={isSelected ? "default" : "outline"} - > - {tag} - - ); - })} + variant={isSelected ? "default" : "outline"} + > + {tag} + + ); + })}
{form.formState.errors.tags && (

diff --git a/components/Chat/StarterAgentCard.tsx b/components/Chat/StarterAgentCard.tsx index 3211213db..028c05f1e 100644 --- a/components/Chat/StarterAgentCard.tsx +++ b/components/Chat/StarterAgentCard.tsx @@ -1,12 +1,15 @@ import type React from "react"; -import { type Agent } from "../Agents/useAgentData"; +import { type Agent } from "@/hooks/useAgentData"; interface StarterAgentCardProps { agent: Agent; onClick: (agent: Agent) => void; } -const StarterAgentCard: React.FC = ({ agent, onClick }) => { +const StarterAgentCard: React.FC = ({ + agent, + onClick, +}) => { return (