补全翻译
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-11-16 12:44:52 +08:00
parent 30fc4ed64d
commit 7c5fc40209
31 changed files with 279 additions and 54 deletions

View File

@@ -5,24 +5,26 @@ 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";
interface FolderSelectorProps {
folders: (folder & { total_pairs: number })[];
}
const FolderSelector: React.FC<FolderSelectorProps> = ({ folders }) => {
const t = useTranslations("memorize/folder-selector");
const router = useRouter();
return (
<Center>
<Container className="p-6 gap-4 flex flex-col">
{(folders.length === 0 && (
<h1 className="text-2xl text-gray-900 font-light">
No folders found.
{t("noFolders")}
</h1>
)) || (
<>
<h1 className="text-2xl text-gray-900 font-light">
Select a folder:
{t("selectFolder")}
</h1>
<div className="text-gray-900 border border-gray-200 rounded-2xl max-h-96 overflow-y-auto">
{folders.map((folder) => (
@@ -36,9 +38,12 @@ const FolderSelector: React.FC<FolderSelectorProps> = ({ folders }) => {
<Folder />
<div className="flex-1 flex gap-2">
<span className="group-hover:text-blue-500">
{folder.id}. {folder.name}
{t("folderInfo", {
id: folder.id,
name: folder.name,
count: folder.total_pairs,
})}
</span>
<span>({folder.total_pairs})</span>
</div>
</div>
))}

View File

@@ -8,12 +8,14 @@ import LightButton from "@/components/buttons/LightButton";
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
import { getTTSAudioUrl } from "@/lib/tts";
import { VOICES } from "@/config/locales";
import { useTranslations } from "next-intl";
interface MemorizeProps {
textPairs: text_pair[];
}
const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
const t = useTranslations("memorize.memorize");
const [reverse, setReverse] = useState(false);
const [dictation, setDictation] = useState(false);
const [index, setIndex] = useState(0);
@@ -27,7 +29,7 @@ const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
<>
<div className="h-36 flex flex-col gap-2 justify-start items-center font-serif text-3xl">
<div className="text-sm text-gray-500">
{index + 1}/{textPairs.length}
{t("progress", { current: index + 1, total: textPairs.length })}
</div>
{dictation ? (
show === "question" ? (
@@ -86,7 +88,7 @@ const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
setShow(show === "question" ? "answer" : "question");
}}
>
{show === "question" ? "Show Answer" : "Next"}
{show === "question" ? t("showAnswer") : t("next")}
</LightButton>
<LightButton
onClick={() => {
@@ -94,7 +96,7 @@ const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
}}
selected={reverse}
>
Reverse
{t("reverse")}
</LightButton>
<LightButton
onClick={() => {
@@ -102,11 +104,11 @@ const Memorize: React.FC<MemorizeProps> = ({ textPairs }) => {
}}
selected={dictation}
>
Dictation
{t("dictation")}
</LightButton>
</div>
</>
)) || <p>No text pairs available</p>}
)) || <p>{t("noTextPairs")}</p>}
</Container>
</Center>
);

View File

@@ -2,6 +2,7 @@
import { redirect } from "next/navigation";
import { getServerSession } from "next-auth";
import { getTranslations } from "next-intl/server";
import {
getFoldersWithTotalPairsByOwner,
getOwnerByFolderId,
@@ -18,9 +19,14 @@ export default async function MemorizePage({
}) {
const session = await getServerSession();
const username = session?.user?.name;
const t = await getTranslations("memorize.page");
const t = (await searchParams).folder_id;
const folder_id = t ? (isNonNegativeInteger(t) ? parseInt(t) : null) : null;
const tParam = (await searchParams).folder_id;
const folder_id = tParam
? isNonNegativeInteger(tParam)
? parseInt(tParam)
: null
: null;
if (!username)
redirect(
@@ -37,7 +43,7 @@ export default async function MemorizePage({
const owner = await getOwnerByFolderId(folder_id);
if (owner !== username) {
return <p>访</p>;
return <p>{t("unauthorized")}</p>;
}
return <Memorize textPairs={await getTextPairsByFolderId(folder_id)} />;