今天做了好多工作啊
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-12-04 21:07:54 +08:00
parent fcc20fc2e0
commit 41005a4aac
27 changed files with 733 additions and 6294 deletions

View File

@@ -1,15 +1,15 @@
"use client";
import Container from "@/components/cards/Container";
import { folder } from "../../../../generated/prisma/client";
import { Folder } from "lucide-react";
import { useRouter } from "next/navigation";
import { Center } from "@/components/Center";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { Folder } from "../../../../generated/prisma/browser";
import { Folder as Fd } from "lucide-react";
interface FolderSelectorProps {
folders: (folder & { total_pairs: number })[];
folders: (Folder & { total: number })[];
}
const FolderSelector: React.FC<FolderSelectorProps> = ({ folders }) => {
@@ -41,13 +41,13 @@ const FolderSelector: React.FC<FolderSelectorProps> = ({ folders }) => {
}
className="flex flex-row justify-center items-center group p-2 gap-2 hover:cursor-pointer hover:bg-gray-50"
>
<Folder />
<Fd />
<div className="flex-1 flex gap-2">
<span className="group-hover:text-blue-500">
{t("folderInfo", {
id: folder.id,
name: folder.name,
count: folder.total_pairs,
count: folder.total,
})}
</span>
</div>

View File

@@ -1,8 +1,5 @@
"use client";
import { Center } from "@/components/Center";
import { text_pair } from "../../../../generated/prisma/browser";
import Container from "@/components/cards/Container";
import { useEffect, useState } from "react";
import LightButton from "@/components/buttons/LightButton";
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
@@ -11,13 +8,14 @@ import { VOICES } from "@/config/locales";
import { useTranslations } from "next-intl";
import localFont from "next/font/local";
import { isNonNegativeInteger } from "@/lib/utils";
import { Pair } from "../../../../generated/prisma/browser";
const myFont = localFont({
src: "../../../../public/fonts/NotoNaskhArabic-VariableFont_wght.ttf",
});
interface MemorizeProps {
textPairs: text_pair[];
textPairs: Pair[];
}
const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
@@ -29,7 +27,7 @@ const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
const [show, setShow] = useState<"question" | "answer">("question");
const { load, play } = useAudioPlayer();
const [disorderedTextPairs, setDisorderedTextPairs] = useState<text_pair[]>(
const [disorderedTextPairs, setDisorderedTextPairs] = useState<Pair[]>(
[],
);
@@ -66,7 +64,7 @@ const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
{index + 1}
{"/" + getTextPairs().length}
</div>
<div className="h-[40dvh] px-16">
<div className={`h-[40dvh] md:px-16 px-4 ${myFont.className}`}>
{(() => {
const createText = (text: string) => {
return (

View File

@@ -1,24 +1,24 @@
"use server";
import { redirect } from "next/navigation";
import { getServerSession } from "next-auth";
import { getTranslations } from "next-intl/server";
import {
getFoldersWithTotalPairsByOwner,
getOwnerByFolderId,
getFoldersWithTotalPairsByUserId,
getUserIdByFolderId,
} from "@/lib/actions/services/folderService";
import { isNonNegativeInteger } from "@/lib/utils";
import FolderSelector from "./FolderSelector";
import Memorize from "./Memorize";
import { getTextPairsByFolderId } from "@/lib/actions/services/textPairService";
import { getPairsByFolderId } from "@/lib/actions/services/pairService";
import { auth } from "@/auth";
export default async function MemorizePage({
searchParams,
}: {
searchParams: Promise<{ folder_id?: string }>;
}) {
const session = await getServerSession();
const username = session?.user?.name;
const session = await auth();
const userId = session?.user?.id;
const t = await getTranslations("memorize.page");
const tParam = (await searchParams).folder_id;
@@ -28,23 +28,26 @@ export default async function MemorizePage({
: null
: null;
if (!username)
if (!userId) {
redirect(
`/login?redirect=/memorize${folder_id ? `?folder_id=${folder_id}` : ""}`,
);
}
const uid = Number(userId);
if (!folder_id) {
return (
<FolderSelector
folders={await getFoldersWithTotalPairsByOwner(username)}
folders={await getFoldersWithTotalPairsByUserId(uid)}
/>
);
}
const owner = await getOwnerByFolderId(folder_id);
if (owner !== username) {
const owner = await getUserIdByFolderId(folder_id);
if (owner !== uid) {
return <p>{t("unauthorized")}</p>;
}
return <Memorize textPairs={await getTextPairsByFolderId(folder_id)} />;
return <Memorize textPairs={await getPairsByFolderId(folder_id)} />;
}

View File

@@ -4,10 +4,10 @@ import { TranslationHistorySchema } from "@/lib/interfaces";
import { useSession } from "next-auth/react";
import { Dispatch, useEffect, useState } from "react";
import z from "zod";
import { folder } from "../../../../generated/prisma/browser";
import { getFoldersByOwner } from "@/lib/actions/services/folderService";
import { Folder } from "lucide-react";
import { createTextPair } from "@/lib/actions/services/textPairService";
import { Folder } from "../../../../generated/prisma/browser";
import { getFoldersByUserId } from "@/lib/actions/services/folderService";
import { Folder as Fd } from "lucide-react";
import { createPair } from "@/lib/actions/services/pairService";
import { toast } from "sonner";
import { useTranslations } from "next-intl";
@@ -18,13 +18,13 @@ interface AddToFolderProps {
const AddToFolder: React.FC<AddToFolderProps> = ({ item, setShow }) => {
const session = useSession();
const [folders, setFolders] = useState<folder[]>([]);
const [folders, setFolders] = useState<Folder[]>([]);
const t = useTranslations("translator.add_to_folder");
const [loading, setLoading] = useState(true);
useEffect(() => {
const username = session.data!.user!.name as string;
getFoldersByOwner(username)
const userId = Number(session.data!.user!.id);
getFoldersByUserId(userId)
.then(setFolders)
.then(() => setLoading(false));
}, [session.data]);
@@ -50,12 +50,12 @@ const AddToFolder: React.FC<AddToFolderProps> = ({ item, setShow }) => {
key={folder.id}
className="p-2 flex items-center justify-start hover:bg-gray-50 gap-2 hover:cursor-pointer w-full border-b border-gray-200"
onClick={() => {
createTextPair({
createPair({
text1: item.text1,
text2: item.text2,
locale1: item.locale1,
locale2: item.locale2,
folders: {
folder: {
connect: {
id: folder.id,
},
@@ -70,7 +70,7 @@ const AddToFolder: React.FC<AddToFolderProps> = ({ item, setShow }) => {
});
}}
>
<Folder />
<Fd />
{t("folderInfo", { id: folder.id, name: folder.name })}
</button>
))) || <div>{t("noFolders")}</div>}

View File

@@ -1,29 +1,29 @@
import Container from "@/components/cards/Container";
import { useEffect, useState } from "react";
import { folder } from "../../../../generated/prisma/browser";
import { getFoldersByOwner } from "@/lib/actions/services/folderService";
import { Folder } from "../../../../generated/prisma/browser";
import { getFoldersByUserId } from "@/lib/actions/services/folderService";
import LightButton from "@/components/buttons/LightButton";
import { Folder } from "lucide-react";
import { Folder as Fd } from "lucide-react";
interface FolderSelectorProps {
setSelectedFolderId: (id: number) => void;
username: string;
userId: number;
cancel: () => void;
}
const FolderSelector: React.FC<FolderSelectorProps> = ({
setSelectedFolderId,
username,
userId,
cancel,
}) => {
const [loading, setLoading] = useState(false);
const [folders, setFolders] = useState<folder[]>([]);
const [folders, setFolders] = useState<Folder[]>([]);
useEffect(() => {
getFoldersByOwner(username)
getFoldersByUserId(userId)
.then(setFolders)
.then(() => setLoading(false));
}, [username]);
}, [userId]);
return (
<div
@@ -41,7 +41,7 @@ const FolderSelector: React.FC<FolderSelectorProps> = ({
key={folder.id}
onClick={() => setSelectedFolderId(folder.id)}
>
<Folder />
<Fd />
{folder.id}. {folder.name}
</button>
))}

View File

@@ -21,7 +21,7 @@ import {
import { toast } from "sonner";
import FolderSelector from "./FolderSelector";
import { useSession } from "next-auth/react";
import { createTextPair } from "@/lib/actions/services/textPairService";
import { createPair } from "@/lib/actions/services/pairService";
import { shallowEqual } from "@/lib/utils";
export default function TranslatorPage() {
@@ -109,12 +109,12 @@ export default function TranslatorPage() {
}),
);
if (autoSave && autoSaveFolderId) {
createTextPair({
createPair({
text1: llmres.text1,
text2: llmres.text2,
locale1: llmres.locale1,
locale2: llmres.locale2,
folders: {
folder: {
connect: {
id: autoSaveFolderId,
},
@@ -128,10 +128,10 @@ export default function TranslatorPage() {
.catch((error) => {
toast.error(
llmres.text1 +
"保存到文件夹" +
autoSaveFolderId +
"失败:" +
error.message,
"保存到文件夹" +
autoSaveFolderId +
"失败:" +
error.message,
);
});
}
@@ -364,7 +364,7 @@ export default function TranslatorPage() {
)}
{autoSave && !autoSaveFolderId && (
<FolderSelector
username={session.data!.user!.name as string}
userId={Number(session.data!.user!.id)}
cancel={() => setAutoSave(false)}
setSelectedFolderId={(id) => setAutoSaveFolderId(id)}
/>