Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
ttizze committed Jul 14, 2024
1 parent 15773db commit 0ddc2e5
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 34 deletions.
82 changes: 48 additions & 34 deletions web/app/routes/_index/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import { addNumbersToContent } from "./utils/addNumbersToContent";
import { extractArticle } from "./utils/articleUtils";
import { fetchWithRetry } from "./utils/fetchWithRetry";
import { translate } from "./utils/translation";
import { authenticator } from "../../utils/auth.server";
import { Button } from "~/components/ui/button"
import { Input } from "~/components/ui/input"
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "~/components/ui/card"
import { Alert, AlertDescription } from "~/components/ui/alert"
import { getSession, commitSession } from "~/utils/session.server";


export const meta: MetaFunction = () => {
return [
Expand Down Expand Up @@ -76,38 +81,47 @@ export default function Index() {
});

return (
<div className="font-sans p-4">
<Form method="post" {...getFormProps(form)}>
<input
type="url"
name="url"
placeholder="URLを入力"
required
className="border p-2"
/>
<button
type="submit"
disabled={navigation.state === "submitting"}
className="bg-blue-500 text-white p-2 ml-2"
>
{navigation.state === "submitting" ? "処理中..." : "翻訳を開始"}
</button>
</Form>
{actionData?.result.status === "error" && (
<ul className="text-red-500 mt-2" id={field.url.errorId}>
{field.url.errors}
</ul>
)}
{actionData?.result.status === "success" && (
<div>
<Link
to={`/reader/${encodeURIComponent(actionData.url)}`}
className="text-blue-500 hover:underline"
>
<h2>{actionData.title}</h2>
</Link>
</div>
)}
</div>
<div className="container mx-auto max-w-2xl py-8">
<Card>
<Form method="post" {...getFormProps(form)} className="space-y-4">
<div className="flex space-x-2">
<Input
type="url"
name="url"
placeholder="URLを入力"
required
className="flex-grow"
/>
<Button
type="submit"
disabled={navigation.state === "submitting"}
>
{navigation.state === "submitting" ? "処理中..." : "翻訳を開始"}
</Button>
</div>
</Form>

{actionData?.result.status === "error" && (
<Alert variant="destructive" className="mt-4">
<AlertDescription>
<ul id={field.url.errorId}>
{field.url.errors}
</ul>
</AlertDescription>
</Alert>
)}

{actionData?.result.status === "success" && (
<div className="mt-4">
<Link
to={`/reader/${encodeURIComponent(actionData.url)}`}
className="text-blue-500 hover:underline"
>
<h2 className="text-xl font-semibold">{actionData.title}</h2>
</Link>
</div>
)}
</Card>
</div>
);
}
41 changes: 41 additions & 0 deletions web/app/routes/components/URLInputForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Form, useNavigation } from '@remix-run/react'
import { getFormProps, useForm } from '@conform-to/react'
import { parseWithZod } from '@conform-to/zod'
import { z } from 'zod'
import { Button } from "~/components/ui/button"
import { Input } from "~/components/ui/input"

const urlSchema = z.object({
url: z.string().url("有効なURLを入力してください"),
})

export function URLInputForm() {
const navigation = useNavigation()

const [form, field] = useForm({
id: "url-form",
onValidate({ formData }) {
return parseWithZod(formData, { schema: urlSchema })
},
})

return (
<Form method="post" {...getFormProps(form)} className="space-y-4">
<div className="flex space-x-2">
<Input
type="url"
name="url"
placeholder="URLを入力"
required
className="flex-grow"
/>
<Button
type="submit"
disabled={navigation.state === "submitting"}
>
{navigation.state === "submitting" ? "処理中..." : "翻訳を開始"}
</Button>
</div>
</Form>
)
}
37 changes: 37 additions & 0 deletions web/app/utils/userReadHistory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { prisma } from "./prisma";

export async function updateUserReadHistory(userId: number, pageVersionId: number, number: number) {
await prisma.userReadHistory.upsert({
where: {
userId_pageVersionId: {
userId: userId,
pageVersionId: pageVersionId,
},
},
update: {
lastReadDataNumber: number,
readAt: new Date(),
},
create: {
userId: userId,
pageVersionId: pageVersionId,
lastReadDataNumber: number,
},
});
}

export async function getLastReadDataNumber(userId: number, pageVersionId: number) {
const readHistory = await prisma.userReadHistory.findUnique({
where: {
userId_pageVersionId: {
userId: userId,
pageVersionId: pageVersionId,
},
},
select: {
lastReadDataNumber: true,
},
});

return readHistory?.lastReadDataNumber ?? 0;
}
25 changes: 25 additions & 0 deletions web/prisma/migrations/20240714151356_/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- CreateTable
CREATE TABLE "user_read_history" (
"id" SERIAL NOT NULL,
"user_id" INTEGER NOT NULL,
"page_version_id" INTEGER NOT NULL,
"read_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"last_read_data_number" INTEGER NOT NULL DEFAULT 0,

CONSTRAINT "user_read_history_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE INDEX "user_read_history_user_id_idx" ON "user_read_history"("user_id");

-- CreateIndex
CREATE INDEX "user_read_history_page_version_id_idx" ON "user_read_history"("page_version_id");

-- CreateIndex
CREATE UNIQUE INDEX "user_read_history_user_id_page_version_id_key" ON "user_read_history"("user_id", "page_version_id");

-- AddForeignKey
ALTER TABLE "user_read_history" ADD CONSTRAINT "user_read_history_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "user_read_history" ADD CONSTRAINT "user_read_history_page_version_id_fkey" FOREIGN KEY ("page_version_id") REFERENCES "page_versions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
17 changes: 17 additions & 0 deletions web/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,28 @@ model User {
provider String @default("Credentials")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
userReadHistory UserReadHistory[]
apiUsages ApiUsage[]
translations TranslateText[]
votes Vote[]
@@map("users")
}
model UserReadHistory {
id Int @id @default(autoincrement())
userId Int @map("user_id")
pageVersionId Int @map("page_version_id")
readAt DateTime @default(now()) @map("read_at")
lastReadDataNumber Int @default(0) @map("last_read_data_number")
user User @relation(fields: [userId], references: [id])
pageVersion PageVersion @relation(fields: [pageVersionId], references: [id])
@@unique([userId, pageVersionId])
@@index([userId])
@@index([pageVersionId])
@@map("user_read_history")
}


model Page {
id Int @id @default(autoincrement())
Expand Down Expand Up @@ -58,6 +74,7 @@ model PageVersion {
page Page @relation(fields: [pageId], references: [id])
sourceTexts SourceText[]
translationStatus TranslationStatus[]
userReadHistory UserReadHistory[]
@@unique([url, createdAt])
@@map("page_versions")
Expand Down

0 comments on commit 0ddc2e5

Please sign in to comment.