将Navbar下放到子页面
This commit is contained in:
@@ -4,6 +4,7 @@ import Button from "@/components/Button";
|
|||||||
import { Letter, SupportedAlphabets } from "@/interfaces";
|
import { Letter, SupportedAlphabets } from "@/interfaces";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import MemoryCard from "./MemoryCard";
|
import MemoryCard from "./MemoryCard";
|
||||||
|
import { Navbar } from "@/components/Navbar";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [chosenAlphabet, setChosenAlphabet] = useState<SupportedAlphabets | null>(null);
|
const [chosenAlphabet, setChosenAlphabet] = useState<SupportedAlphabets | null>(null);
|
||||||
@@ -43,7 +44,8 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
}, [loadingState]);
|
}, [loadingState]);
|
||||||
|
|
||||||
if (!chosenAlphabet) return (
|
if (!chosenAlphabet) return (<>
|
||||||
|
<Navbar></Navbar>
|
||||||
<div className="border border-gray-200 m-4 mt-4 flex flex-col justify-center items-center p-4 rounded-2xl gap-2">
|
<div className="border border-gray-200 m-4 mt-4 flex flex-col justify-center items-center p-4 rounded-2xl gap-2">
|
||||||
<span className="text-2xl md:text-3xl">请选择您想学习的字符</span>
|
<span className="text-2xl md:text-3xl">请选择您想学习的字符</span>
|
||||||
<div className="flex gap-1 flex-wrap">
|
<div className="flex gap-1 flex-wrap">
|
||||||
@@ -52,7 +54,9 @@ export default function Home() {
|
|||||||
<Button label="维吾尔字母" onClick={() => setChosenAlphabet('uyghur')}></Button>
|
<Button label="维吾尔字母" onClick={() => setChosenAlphabet('uyghur')}></Button>
|
||||||
<Button label="世界语字母" onClick={() => setChosenAlphabet('esperanto')}></Button>
|
<Button label="世界语字母" onClick={() => setChosenAlphabet('esperanto')}></Button>
|
||||||
</div>
|
</div>
|
||||||
</div>);
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
if (loadingState === 'loading') {
|
if (loadingState === 'loading') {
|
||||||
return '加载中...';
|
return '加载中...';
|
||||||
}
|
}
|
||||||
@@ -60,11 +64,14 @@ export default function Home() {
|
|||||||
return '加载失败,请重试';
|
return '加载失败,请重试';
|
||||||
}
|
}
|
||||||
if (loadingState === 'success' && alphabetData[chosenAlphabet]) {
|
if (loadingState === 'success' && alphabetData[chosenAlphabet]) {
|
||||||
return (<MemoryCard
|
return (<>
|
||||||
language={chosenAlphabet}
|
<Navbar></Navbar>
|
||||||
alphabet={alphabetData[chosenAlphabet]}
|
<MemoryCard
|
||||||
setChosenAlphabet={setChosenAlphabet}>
|
language={chosenAlphabet}
|
||||||
</MemoryCard>);
|
alphabet={alphabetData[chosenAlphabet]}
|
||||||
|
setChosenAlphabet={setChosenAlphabet}>
|
||||||
|
</MemoryCard>
|
||||||
|
</>);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,6 @@ import type { Metadata } from "next";
|
|||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import type { Viewport } from 'next'
|
import type { Viewport } from 'next'
|
||||||
import Link from "next/link";
|
|
||||||
import Image from "next/image";
|
|
||||||
|
|
||||||
export const viewport: Viewport = {
|
export const viewport: Viewport = {
|
||||||
width: 'device-width',
|
width: 'device-width',
|
||||||
@@ -25,33 +23,7 @@ export const metadata: Metadata = {
|
|||||||
description: "A Website to Learn Languages",
|
description: "A Website to Learn Languages",
|
||||||
};
|
};
|
||||||
|
|
||||||
function MyLink(
|
|
||||||
{ href, label }: { href: string, label: string }
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<Link className="font-bold" href={href}>{label}</Link>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
function Navbar() {
|
|
||||||
return (
|
|
||||||
<div className="flex justify-between items-center w-full h-16 px-8 bg-[#35786f] text-white">
|
|
||||||
<Link href={'/'} className="text-xl flex">
|
|
||||||
<Image
|
|
||||||
src={'/favicon.ico'}
|
|
||||||
alt="logo"
|
|
||||||
width="32"
|
|
||||||
height="32"
|
|
||||||
className="rounded-4xl">
|
|
||||||
</Image>
|
|
||||||
<span className="font-bold">学语言</span>
|
|
||||||
</Link>
|
|
||||||
<div className="flex gap-4 text-xl">
|
|
||||||
<MyLink href="/changelog.txt" label="关于"></MyLink>
|
|
||||||
<MyLink href="https://github.com/GoddoNebianU/learn-languages" label="源码"></MyLink>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
@@ -63,7 +35,6 @@ export default function RootLayout({
|
|||||||
<body
|
<body
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||||
>
|
>
|
||||||
<Navbar></Navbar>
|
|
||||||
{children}
|
{children}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Navbar } from "@/components/Navbar";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
function TopArea() {
|
function TopArea() {
|
||||||
@@ -91,6 +92,7 @@ function Explore() {
|
|||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Navbar></Navbar>
|
||||||
<TopArea></TopArea>
|
<TopArea></TopArea>
|
||||||
<Fortune></Fortune>
|
<Fortune></Fortune>
|
||||||
<Explore></Explore>
|
<Explore></Explore>
|
||||||
|
|||||||
@@ -3,23 +3,25 @@
|
|||||||
import { KeyboardEvent, useRef, useState } from "react";
|
import { KeyboardEvent, useRef, useState } from "react";
|
||||||
import UploadArea from "./UploadArea";
|
import UploadArea from "./UploadArea";
|
||||||
import VideoPanel from "./VideoPlayer/VideoPanel";
|
import VideoPanel from "./VideoPlayer/VideoPanel";
|
||||||
|
import { Navbar } from "@/components/Navbar";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const videoRef = useRef<HTMLVideoElement>(null);
|
const videoRef = useRef<HTMLVideoElement>(null);
|
||||||
|
|
||||||
const [videoUrl, setVideoUrl] = useState<string | null>(null);
|
const [videoUrl, setVideoUrl] = useState<string | null>(null);
|
||||||
const [srtUrl, setSrtUrl] = useState<string | null>(null);
|
const [srtUrl, setSrtUrl] = useState<string | null>(null);
|
||||||
return (
|
return (<>
|
||||||
<div className="flex w-screen pt-8 items-center justify-center" onKeyDown={(e: KeyboardEvent<HTMLDivElement>) => e.preventDefault()}>
|
<Navbar></Navbar>
|
||||||
<div className="w-[80vw] md:w-[45vw] flex items-center flex-col">
|
<div className="flex w-screen pt-8 items-center justify-center" onKeyDown={(e: KeyboardEvent<HTMLDivElement>) => e.preventDefault()}>
|
||||||
<VideoPanel
|
<div className="w-[80vw] md:w-[45vw] flex items-center flex-col">
|
||||||
videoUrl={videoUrl}
|
<VideoPanel
|
||||||
srtUrl={srtUrl}
|
videoUrl={videoUrl}
|
||||||
ref={videoRef} />
|
srtUrl={srtUrl}
|
||||||
<UploadArea
|
ref={videoRef} />
|
||||||
setVideoUrl={setVideoUrl}
|
<UploadArea
|
||||||
setSrtUrl={setSrtUrl} />
|
setVideoUrl={setVideoUrl}
|
||||||
|
setSrtUrl={setSrtUrl} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { ChangeEvent, useEffect, useRef, useState } from "react";
|
|||||||
import SaveList from "./SaveList";
|
import SaveList from "./SaveList";
|
||||||
import { TextSpeakerItemSchema } from "@/interfaces";
|
import { TextSpeakerItemSchema } from "@/interfaces";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
|
import { Navbar } from "@/components/Navbar";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
@@ -228,6 +229,7 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
|
<Navbar></Navbar>
|
||||||
<div className="my-4 p-4 mx-4 md:mx-32 border-1 border-gray-200 rounded-2xl" style={{ fontFamily: 'Times New Roman, serif' }}>
|
<div className="my-4 p-4 mx-4 md:mx-32 border-1 border-gray-200 rounded-2xl" style={{ fontFamily: 'Times New Roman, serif' }}>
|
||||||
<textarea className="text-2xl resize-none focus:outline-0 min-h-64 w-full border-gray-200 border-b"
|
<textarea className="text-2xl resize-none focus:outline-0 min-h-64 w-full border-gray-200 border-b"
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import IconClick from "@/components/IconClick";
|
|||||||
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
|
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
|
||||||
import IMAGES from "@/config/images";
|
import IMAGES from "@/config/images";
|
||||||
import { getTTSAudioUrl } from "@/utils";
|
import { getTTSAudioUrl } from "@/utils";
|
||||||
|
import { Navbar } from "@/components/Navbar";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [ipaEnabled, setIPAEnabled] = useState(true);
|
const [ipaEnabled, setIPAEnabled] = useState(true);
|
||||||
@@ -187,6 +188,7 @@ export default function Home() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Navbar></Navbar>
|
||||||
<div className="w-screen flex flex-col md:flex-row md:justify-between gap-2 p-2">
|
<div className="w-screen flex flex-col md:flex-row md:justify-between gap-2 p-2">
|
||||||
<div className="card1 w-full md:w-1/2 flex flex-col-reverse gap-2">
|
<div className="card1 w-full md:w-1/2 flex flex-col-reverse gap-2">
|
||||||
<div className="textarea1 border-1 border-gray-200 rounded-2xl w-full h-64 p-2">
|
<div className="textarea1 border-1 border-gray-200 rounded-2xl w-full h-64 p-2">
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { KeyboardEvent, useRef, useState } from "react";
|
|||||||
import { Word } from "@/interfaces";
|
import { Word } from "@/interfaces";
|
||||||
import { BOARD_WIDTH, TEXT_WIDTH, BOARD_HEIGHT, TEXT_SIZE } from "@/config/word-board-config";
|
import { BOARD_WIDTH, TEXT_WIDTH, BOARD_HEIGHT, TEXT_SIZE } from "@/config/word-board-config";
|
||||||
import { inspect } from "@/utils";
|
import { inspect } from "@/utils";
|
||||||
|
import { Navbar } from "@/components/Navbar";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -139,21 +140,25 @@ export default function Home() {
|
|||||||
// inputRef.current.value = '';
|
// inputRef.current.value = '';
|
||||||
// }
|
// }
|
||||||
return (
|
return (
|
||||||
<div className="flex w-screen h-screen justify-center items-center">
|
<>
|
||||||
<div onKeyDown={handleKeyDown} className="p-5 bg-gray-200 rounded shadow-2xl">
|
<Navbar></Navbar>
|
||||||
<WordBoard selectWord={selectWord} words={words as [Word]} setWords={setWords} />
|
<div className="flex w-screen h-screen justify-center items-center">
|
||||||
<div className="flex justify-center rounded mt-3 gap-1">
|
<div onKeyDown={handleKeyDown} className="p-5 bg-gray-200 rounded shadow-2xl">
|
||||||
<input ref={inputRef} placeholder="word to operate" type="text" className="focus:outline-none border-b-2 border-black" />
|
<WordBoard selectWord={selectWord} words={words as [Word]} setWords={setWords} />
|
||||||
<Button label="插入" onClick={insertWord}></Button>
|
<div className="flex justify-center rounded mt-3 gap-1">
|
||||||
<Button label="删除" onClick={deleteWord}></Button>
|
<input ref={inputRef} placeholder="word to operate" type="text" className="focus:outline-none border-b-2 border-black" />
|
||||||
<Button label="搜索" onClick={searchWord}></Button>
|
<Button label="插入" onClick={insertWord}></Button>
|
||||||
<Button label="导入" onClick={importWords}></Button>
|
<Button label="删除" onClick={deleteWord}></Button>
|
||||||
<Button label="导出" onClick={exportWords}></Button>
|
<Button label="搜索" onClick={searchWord}></Button>
|
||||||
<Button label="删光" onClick={deleteAll}></Button>
|
<Button label="导入" onClick={importWords}></Button>
|
||||||
{/* <Button label="朗读" onClick={readWordAloud}></Button> */}
|
<Button label="导出" onClick={exportWords}></Button>
|
||||||
|
<Button label="删光" onClick={deleteAll}></Button>
|
||||||
|
{/* <Button label="朗读" onClick={readWordAloud}></Button> */}
|
||||||
|
</div>
|
||||||
|
<input type="file" ref={inputFileRef} className="hidden" accept="application/json" onChange={handleFileChange}></input>
|
||||||
</div>
|
</div>
|
||||||
<input type="file" ref={inputFileRef} className="hidden" accept="application/json" onChange={handleFileChange}></input>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/components/Navbar.tsx
Normal file
30
src/components/Navbar.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
function MyLink(
|
||||||
|
{ href, label }: { href: string, label: string }
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<Link className="font-bold" href={href}>{label}</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export function Navbar() {
|
||||||
|
return (
|
||||||
|
<div className="flex justify-between items-center w-full h-16 px-8 bg-[#35786f] text-white">
|
||||||
|
<Link href={'/'} className="text-xl flex">
|
||||||
|
<Image
|
||||||
|
src={'/favicon.ico'}
|
||||||
|
alt="logo"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
className="rounded-4xl">
|
||||||
|
</Image>
|
||||||
|
<span className="font-bold">学语言</span>
|
||||||
|
</Link>
|
||||||
|
<div className="flex gap-4 text-xl">
|
||||||
|
<MyLink href="/changelog.txt" label="关于"></MyLink>
|
||||||
|
<MyLink href="https://github.com/GoddoNebianU/learn-languages" label="源码"></MyLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user