Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

全体のリファクタ #135

Merged
merged 3 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
DialogHeader,
DialogTitle,
} from "~/components/ui/dialog";
import { GoogleForm } from "./google-form";
import { GoogleForm } from "../routes/resources+/google-form";

interface LoginDialogProps {
isOpen: boolean;
Expand Down
2 changes: 1 addition & 1 deletion web/app/routes/reader.$/components/AddTranslationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { getZodConstraint } from "@conform-to/zod";
import { useFetcher } from "@remix-run/react";
import { Save } from "lucide-react";
import { useState } from "react";
import { LoginDialog } from "~/components/LoginDialog";
import { Button } from "~/components/ui/button";
import { Textarea } from "~/components/ui/textarea";
import { LoginDialog } from "~/routes/resources+/LoginDialog";
import type { action } from "../route";
import { addTranslationSchema } from "../types";

Expand Down
2 changes: 1 addition & 1 deletion web/app/routes/reader.$/components/VoteButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { parseWithZod } from "@conform-to/zod";
import { useFetcher } from "@remix-run/react";
import { memo, useMemo } from "react";
import { useState } from "react";
import { LoginDialog } from "~/routes/resources+/LoginDialog";
import { LoginDialog } from "~/components/LoginDialog";
import { cn } from "~/utils/cn";
import type { TranslationWithVote } from "../types";
import { voteSchema } from "../types";
Expand Down
7 changes: 3 additions & 4 deletions web/app/routes/reader.$/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,14 @@ export const action = async ({ request }: ActionFunctionArgs) => {
};

export default function ReaderView() {
const { encodedUrl } = useParams();
const { targetLanguage, pageData, safeUser } =
useTypedLoaderData<typeof loader>();
const { "*": urlParam } = useParams();
const { pageData, safeUser } = useTypedLoaderData<typeof loader>();

if (!pageData) {
return <div>Loading...</div>;
}

const originalUrl = encodedUrl ? decodeURIComponent(encodedUrl) : "";
const originalUrl = urlParam ? decodeURIComponent(urlParam) : "";

return (
<div>
Expand Down
11 changes: 11 additions & 0 deletions web/app/routes/resources+/functions/mutations.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { prisma } from "~/utils/prisma";

export const updateGeminiApiKey = async (
userId: number,
geminiApiKey: string,
) => {
await prisma.user.update({
where: { id: userId },
data: { geminiApiKey },
});
};
ttizze marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,22 +1,53 @@
import { useForm } from "@conform-to/react";
import { getFormProps, getInputProps } from "@conform-to/react";
import { getZodConstraint, parseWithZod } from "@conform-to/zod";
import { Form, useActionData } from "@remix-run/react";
import type { ActionFunctionArgs } from "@remix-run/node";
import { Link } from "@remix-run/react";
import { useNavigation } from "@remix-run/react";
import { useFetcher } from "@remix-run/react";
import { Save } from "lucide-react";
import { ExternalLink, Key } from "lucide-react";
import { TriangleAlert } from "lucide-react";
import { z } from "zod";
import { LoadingSpinner } from "~/components/LoadingSpinner";
import { Alert, AlertDescription } from "~/components/ui/alert";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { Input } from "~/components/ui/input";
import type { action } from "../route";
import { geminiApiKeySchema } from "../types";
import { validateGeminiApiKey } from "~/feature/translate/utils/gemini";
import { authenticator } from "~/utils/auth.server";
import { updateGeminiApiKey } from "./functions/mutations.server";

export const geminiApiKeySchema = z.object({
geminiApiKey: z.string().min(1, "API key is required"),
});

export async function action({ request }: ActionFunctionArgs) {
const safeUser = await authenticator.isAuthenticated(request, {
failureRedirect: "/",
});
const submission = parseWithZod(await request.formData(), {
schema: geminiApiKeySchema,
});
if (submission.status !== "success") {
return { lastResult: submission.reply() };
}

const isValid = await validateGeminiApiKey(submission.value.geminiApiKey);
if (!isValid) {
return {
lastResult: submission.reply({
formErrors: ["Gemini API key validation failed"],
}),
};
}
await updateGeminiApiKey(safeUser.id, submission.value.geminiApiKey);
return { lastResult: submission.reply({ resetForm: true }) };
}

export function GeminiApiKeyForm() {
const actionData = useActionData<typeof action>();
const fetcher = useFetcher<typeof action>();
const actionData = fetcher.data;
const navigation = useNavigation();
const [form, { geminiApiKey }] = useForm({
id: "gemini-api-key-form",
Expand Down Expand Up @@ -71,7 +102,11 @@ export function GeminiApiKeyForm() {
</AlertDescription>
</div>
</Alert>
<Form method="post" {...getFormProps(form)}>
<fetcher.Form
method="post"
action="/resources/gemini-api-key-form"
{...getFormProps(form)}
>
<div className="flex items-center">
<div className="w-full">
<Input
Expand All @@ -85,8 +120,6 @@ export function GeminiApiKeyForm() {
</div>
<Button
type="submit"
name="intent"
value="saveGeminiApiKey"
size="icon"
disabled={navigation.state === "submitting"}
>
ttizze marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -107,7 +140,7 @@ export function GeminiApiKeyForm() {
{form.errors && (
<p className="text-red-500 text-center mt-2">{form.errors}</p>
)}
</Form>
</fetcher.Form>
</CardContent>
</Card>
);
Expand Down
9 changes: 5 additions & 4 deletions web/app/routes/resources+/google-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { FcGoogle } from "react-icons/fc";
import { Button } from "~/components/ui/button";
import { authenticator } from "~/utils/auth.server";

export const action = async ({ request }: ActionFunctionArgs) => {
export async function action({ request }: ActionFunctionArgs) {
return authenticator.authenticate("google", request, {
successRedirect: "/api/auth/callback/google",
failureRedirect: "/login",
});
};
export const GoogleForm = ({ redirectTo }: { redirectTo: string }) => {
}

export function GoogleForm({ redirectTo }: { redirectTo: string }) {
const fetcher = useFetcher();
return (
<fetcher.Form
Expand All @@ -31,4 +32,4 @@ export const GoogleForm = ({ redirectTo }: { redirectTo: string }) => {
</Button>
</fetcher.Form>
);
};
}
2 changes: 1 addition & 1 deletion web/app/routes/translate/components/URLTranslationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { LoadingSpinner } from "~/components/LoadingSpinner";
import { Alert, AlertDescription, AlertTitle } from "~/components/ui/alert";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { AIModelSelector } from "../../../feature/translate/components/AIModelSelector";
ttizze marked this conversation as resolved.
Show resolved Hide resolved
import type { action } from "../route";
import { urlTranslationSchema } from "../types";
import { AIModelSelector } from "./AIModelSelector";

export function URLTranslationForm() {
const navigation = useNavigation();
Expand Down
32 changes: 0 additions & 32 deletions web/app/routes/translate/functions/translate-job.server.ts

This file was deleted.

17 changes: 1 addition & 16 deletions web/app/routes/translate/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import { useEffect } from "react";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { Header } from "~/components/Header";
import { getTranslateUserQueue } from "~/feature/translate/translate-user-queue";
import { validateGeminiApiKey } from "~/feature/translate/utils/gemini";
import { authenticator } from "~/utils/auth.server";
import { normalizeAndSanitizeUrl } from "~/utils/normalize-and-sanitize-url.server";
import { getTargetLanguage } from "~/utils/target-language.server";
import { GeminiApiKeyForm } from "./components/GeminiApiKeyForm";
import { GeminiApiKeyForm } from "../resources+/gemini-api-key-form";
import { URLTranslationForm } from "./components/URLTranslationForm";
import { UserAITranslationStatus } from "./components/UserAITranslationStatus";
import { updateGeminiApiKey } from "./functions/mutations.server";
import {
getDbUser,
listUserAiTranslationInfo,
Expand Down Expand Up @@ -51,19 +49,6 @@ export async function action({ request }: ActionFunctionArgs) {
const intent = submission.value.intent;

switch (submission.value.intent) {
case "saveGeminiApiKey": {
const isValid = await validateGeminiApiKey(submission.value.geminiApiKey);
if (!isValid) {
return {
intent,
lastResult: submission.reply({
formErrors: ["Gemini API key validation failed"],
}),
};
}
await updateGeminiApiKey(safeUser.id, submission.value.geminiApiKey);
return { intent, lastResult: submission.reply({ resetForm: true }) };
}
case "translateUrl": {
const dbUser = await getDbUser(safeUser.id);
if (!dbUser?.geminiApiKey) {
Expand Down
Loading