import { useFetcher } from "@remix-run/react"; import type { ActionFunctionArgs } from "@remix-run/server-runtime"; import { json } from "@remix-run/server-runtime"; import { useCallback, useEffect, useState } from "react"; import { z } from "zod"; import { AISparkleIcon } from "~/assets/icons/AISparkleIcon"; import { Button } from "~/components/primitives/Buttons"; import { FormError } from "~/components/primitives/FormError"; import { Label } from "~/components/primitives/Label"; import { Spinner } from "~/components/primitives/Spinner"; import { env } from "~/env.server"; import { useOrganization } from "~/hooks/useOrganizations"; import { useProject } from "~/hooks/useProject"; import { requireUserId } from "~/services/session.server"; import { humanToCron } from "~/v3/humanToCron.server"; const schema = z.object({ message: z.string(), }); export const action = async ({ request }: ActionFunctionArgs) => { const userId = await requireUserId(request); if (!env.OPENAI_API_KEY) { return json( { isValid: false as const, error: "OpenAI API key is not set", cron: undefined, }, { status: 400 } ); } const data = await request.json(); const submission = schema.safeParse(data); if (!submission.success) { return json( { isValid: false as const, error: "Invalid input", cron: undefined, }, { status: 400 } ); } const result = await humanToCron(submission.data.message, userId); return json(result); }; type AIGeneratedCronFieldProps = { onSuccess: (cron: string) => void; }; export function AIGeneratedCronField({ onSuccess }: AIGeneratedCronFieldProps) { const fetcher = useFetcher(); const [text, setText] = useState(""); const organization = useOrganization(); const project = useProject(); const isLoading = fetcher.state !== "idle"; const resultData = fetcher.data; useEffect(() => { if (resultData?.cron !== undefined) { onSuccess(resultData.cron); } }, [resultData?.cron]); const submit = useCallback(async (value: string) => { fetcher.submit( { message: value }, { method: "POST", action: `/resources/orgs/${organization.slug}/projects/${project.slug}/schedules/new/natural-language`, encType: "application/json", } ); }, []); return (