diff --git a/app/models/note.server.ts b/app/models/note.server.ts deleted file mode 100644 index f385491..0000000 --- a/app/models/note.server.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { User, Note } from "@prisma/client"; - -import { prisma } from "~/db.server"; - -export function getNote({ - id, - userId, -}: Pick & { - userId: User["id"]; -}) { - return prisma.note.findFirst({ - select: { id: true, body: true, title: true }, - where: { id, userId }, - }); -} - -export function getNoteListItems({ userId }: { userId: User["id"] }) { - return prisma.note.findMany({ - where: { userId }, - select: { id: true, title: true }, - orderBy: { updatedAt: "desc" }, - }); -} - -export function createNote({ - body, - title, - userId, -}: Pick & { - userId: User["id"]; -}) { - return prisma.note.create({ - data: { - title, - body, - user: { - connect: { - id: userId, - }, - }, - }, - }); -} - -export function deleteNote({ - id, - userId, -}: Pick & { userId: User["id"] }) { - return prisma.note.deleteMany({ - where: { id, userId }, - }); -} diff --git a/app/models/translation.server.ts b/app/models/translation.server.ts new file mode 100644 index 0000000..29db1c8 --- /dev/null +++ b/app/models/translation.server.ts @@ -0,0 +1,52 @@ +import type { User, Translation } from "@prisma/client"; + +import { prisma } from "~/db.server"; + +export function getTranslation({ + id, + userId, +}: Pick & { + userId: User["id"]; +}) { + return prisma.translation.findFirst({ + where: { id, userId }, + }); +} + +export function getTranslationsListItems({ userId }: { userId: User["id"] }) { + return prisma.translation.findMany({ + where: { userId }, + orderBy: { updatedAt: "desc" }, + }); +} + +export function createTranslation({ + lang, + text, + result, + userId, +}: Pick & { + userId: User["id"]; +}) { + return prisma.translation.create({ + data: { + lang, + text, + result, + user: { + connect: { + id: userId, + }, + }, + }, + }); +} + +export function deleteTranslation({ + id, + userId, +}: Pick & { userId: User["id"] }) { + return prisma.translation.deleteMany({ + where: { id, userId }, + }); +} diff --git a/app/models/user.server.ts b/app/models/user.server.ts index cce401e..8209ce4 100644 --- a/app/models/user.server.ts +++ b/app/models/user.server.ts @@ -28,6 +28,34 @@ export async function createUser(email: User["email"], password: string) { }); } +export async function updateUser( + email: User["email"], + data: { + openAIKey?: User["openAIKey"]; + password?: string; + } +) { + let userData: { [key: string]: any } = {}; + if (data.openAIKey) { + userData.openAIKey = data.openAIKey; + } + if (data.password) { + const hashedPassword = await bcrypt.hash(data.password, 10); + userData.password = { + create: { + hash: hashedPassword, + }, + }; + } + + if (Object.values(userData).length === 0) return; + + return prisma.user.update({ + where: { email }, + data: userData, + }); +} + export async function deleteUserByEmail(email: User["email"]) { return prisma.user.delete({ where: { email } }); } diff --git a/app/routes/account.tsx b/app/routes/account.tsx new file mode 100644 index 0000000..e69de29 diff --git a/app/routes/notes._index.tsx b/app/routes/notes._index.tsx deleted file mode 100644 index aa858a9..0000000 --- a/app/routes/notes._index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Link } from "@remix-run/react"; - -export default function NoteIndexPage() { - return ( -

- No note selected. Select a note on the left, or{" "} - - create a new note. - -

- ); -} diff --git a/app/routes/notes.$noteId.tsx b/app/routes/t.$translationId.tsx similarity index 63% rename from app/routes/notes.$noteId.tsx rename to app/routes/t.$translationId.tsx index 0f83fd8..f980b80 100644 --- a/app/routes/notes.$noteId.tsx +++ b/app/routes/t.$translationId.tsx @@ -8,37 +8,42 @@ import { } from "@remix-run/react"; import invariant from "tiny-invariant"; -import { deleteNote, getNote } from "~/models/note.server"; +import { deleteTranslation, getTranslation } from "~/models/translation.server"; import { requireUserId } from "~/session.server"; export const loader = async ({ params, request }: LoaderArgs) => { const userId = await requireUserId(request); - invariant(params.noteId, "noteId not found"); + invariant(params.translationId, "translationId not found"); - const note = await getNote({ id: params.noteId, userId }); - if (!note) { + const translation = await getTranslation({ + id: params.translationId, + userId, + }); + if (!translation) { throw new Response("Not Found", { status: 404 }); } - return json({ note }); + return json({ translation }); }; export const action = async ({ params, request }: ActionArgs) => { const userId = await requireUserId(request); - invariant(params.noteId, "noteId not found"); + invariant(params.translationId, "translationId not found"); - await deleteNote({ id: params.noteId, userId }); + await deleteTranslation({ id: params.translationId, userId }); - return redirect("/notes"); + return redirect("/t"); }; -export default function NoteDetailsPage() { +export default function TranslationDetailsPage() { const data = useLoaderData(); return (
-

{data.note.title}

-

{data.note.body}

+

To: {data.translation.lang}

+

{data.translation.text}


+

Result:

+

{data.translation.result}

; + return
Translation not found
; } return
An unexpected error occurred: {error.statusText}
; diff --git a/app/routes/t._index.tsx b/app/routes/t._index.tsx new file mode 100644 index 0000000..5f3e2b0 --- /dev/null +++ b/app/routes/t._index.tsx @@ -0,0 +1,13 @@ +import { Link } from "@remix-run/react"; + +export default function TranslationsIndexPage() { + return ( +

+ No translation selected. Select one the left, or{" "} + + start a new translation + + . +

+ ); +} diff --git a/app/routes/notes.new.tsx b/app/routes/t.new.tsx similarity index 52% rename from app/routes/notes.new.tsx rename to app/routes/t.new.tsx index 6afcf5c..2925391 100644 --- a/app/routes/notes.new.tsx +++ b/app/routes/t.new.tsx @@ -3,45 +3,47 @@ import { json, redirect } from "@remix-run/node"; import { Form, useActionData } from "@remix-run/react"; import { useEffect, useRef } from "react"; -import { createNote } from "~/models/note.server"; +import { createTranslation } from "~/models/translation.server"; import { requireUserId } from "~/session.server"; export const action = async ({ request }: ActionArgs) => { const userId = await requireUserId(request); const formData = await request.formData(); - const title = formData.get("title"); - const body = formData.get("body"); + const lang = formData.get("lang"); + const text = formData.get("text"); - if (typeof title !== "string" || title.length === 0) { + if (typeof lang !== "string" || lang.length === 0) { return json( - { errors: { body: null, title: "Title is required" } }, + { errors: { text: null, lang: "Lang is required" } }, { status: 400 } ); } - if (typeof body !== "string" || body.length === 0) { + if (typeof text !== "string" || text.length === 0) { return json( - { errors: { body: "Body is required", title: null } }, + { errors: { text: "Text is required", lang: null } }, { status: 400 } ); } - const note = await createNote({ body, title, userId }); + const result = "test"; - return redirect(`/notes/${note.id}`); + const t = await createTranslation({ lang, text, result, userId }); + + return redirect(`/t/${t.id}`); }; -export default function NewNotePage() { +export default function NewTranslationPage() { const actionData = useActionData(); - const titleRef = useRef(null); - const bodyRef = useRef(null); + const langRef = useRef(null); + const textRef = useRef(null); useEffect(() => { - if (actionData?.errors?.title) { - titleRef.current?.focus(); - } else if (actionData?.errors?.body) { - bodyRef.current?.focus(); + if (actionData?.errors?.lang) { + langRef.current?.focus(); + } else if (actionData?.errors?.text) { + textRef.current?.focus(); } }, [actionData]); @@ -57,41 +59,41 @@ export default function NewNotePage() { >
- {actionData?.errors?.title ? ( -
- {actionData.errors.title} + {actionData?.errors?.lang ? ( +
+ {actionData.errors.lang}
) : null}