import type { ActionArgs, LoaderArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { Form, Link, useActionData, useLoaderData, useNavigation, } from "@remix-run/react"; import { useEffect, useRef } from "react"; import { createTranslation } from "~/models/translation.server"; import { requireUser } from "~/session.server"; import { Configuration, OpenAIApi } from "openai"; export const action = async ({ request }: ActionArgs) => { const user = await requireUser(request); const formData = await request.formData(); const lang = formData.get("lang"); const text = formData.get("text"); if (typeof lang !== "string" || lang.length === 0) { return json( { errors: { text: null, lang: "Lang is required", result: null } }, { status: 400 } ); } if (typeof text !== "string" || text.length === 0) { return json( { errors: { text: "Text is required", lang: null, result: null } }, { status: 400 } ); } if (!user.openAIKey?.length) { return redirect("/account"); } try { const configuration = new Configuration({ apiKey: user.openAIKey, }); const openai = new OpenAIApi(configuration); const completion = await openai.createChatCompletion({ model: "gpt-3.5-turbo", messages: [ { role: "system", content: `You will be provided with a sentence, your task is to translate it into ${lang}.`, }, { role: "user", content: text }, ], }); const result = completion.data.choices[0].message?.content; if (typeof result !== "string" || result.length === 0) { return json( { errors: { text: null, lang: null, result: "Error while retrieving translation result", }, }, { status: 500 } ); } const t = await createTranslation({ lang, text, result, userId: user.id }); return redirect(`/t/${t.id}`); } catch (e) { let error = e as any; if (error.response) { console.error(error.response.status); console.error(error.response.data); return json( { errors: { text: null, lang: null, result: `[${error.response.status}] ${ error.response.data || error.message }`, }, }, { status: 500 } ); } else { console.error(error.message); return json( { errors: { text: null, lang: null, result: `[${error.name}] ${error.message}`, }, }, { status: 500 } ); } } }; export const loader = async ({ params, request }: LoaderArgs) => { const user = await requireUser(request); if (!user.openAIKey?.length) { return redirect("/account"); } return json({ userHasOpenAIKey: true }); }; export default function NewTranslationPage() { const actionData = useActionData(); const loaderData = useLoaderData(); const langRef = useRef(null); const textRef = useRef(null); const navigation = useNavigation(); useEffect(() => { if (actionData?.errors?.lang) { langRef.current?.focus(); } else if (actionData?.errors?.text) { textRef.current?.focus(); } }, [actionData]); return (
{actionData?.errors?.lang ? (
{actionData.errors.lang}
) : null}