This commit is contained in:
@@ -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>
|
||||
))}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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)} />;
|
||||
|
||||
Reference in New Issue
Block a user