split into meanings / reading
This commit is contained in:
parent
fb9d068bd0
commit
7ecabbe72f
8 changed files with 183 additions and 48 deletions
28
package-lock.json
generated
28
package-lock.json
generated
|
@ -13,10 +13,12 @@
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@tauri-apps/api": "^1.3.0",
|
"@tauri-apps/api": "^1.3.0",
|
||||||
|
"@types/lodash-es": "^4.17.7",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"flowbite": "^1.6.5",
|
"flowbite": "^1.6.5",
|
||||||
"framer-motion": "^10.12.16",
|
"framer-motion": "^10.12.16",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router": "^6.11.2",
|
"react-router": "^6.11.2",
|
||||||
|
@ -2017,6 +2019,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz",
|
||||||
"integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg=="
|
"integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/lodash-es": {
|
||||||
|
"version": "4.17.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz",
|
||||||
|
"integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/lodash": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/lodash.mergewith": {
|
"node_modules/@types/lodash.mergewith": {
|
||||||
"version": "4.6.7",
|
"version": "4.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz",
|
||||||
|
@ -2949,6 +2959,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
|
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash-es": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||||
|
},
|
||||||
"node_modules/lodash.mergewith": {
|
"node_modules/lodash.mergewith": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
||||||
|
@ -5493,6 +5508,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz",
|
||||||
"integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg=="
|
"integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg=="
|
||||||
},
|
},
|
||||||
|
"@types/lodash-es": {
|
||||||
|
"version": "4.17.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz",
|
||||||
|
"integrity": "sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/lodash": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/lodash.mergewith": {
|
"@types/lodash.mergewith": {
|
||||||
"version": "4.6.7",
|
"version": "4.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz",
|
||||||
|
@ -6197,6 +6220,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
|
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
|
||||||
},
|
},
|
||||||
|
"lodash-es": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||||
|
},
|
||||||
"lodash.mergewith": {
|
"lodash.mergewith": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"flowbite": "^1.6.5",
|
"flowbite": "^1.6.5",
|
||||||
"framer-motion": "^10.12.16",
|
"framer-motion": "^10.12.16",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router": "^6.11.2",
|
"react-router": "^6.11.2",
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^1.3.1",
|
"@tauri-apps/cli": "^1.3.1",
|
||||||
"@types/node": "^18.7.10",
|
"@types/node": "^18.7.10",
|
||||||
|
"@types/lodash-es": "^4.17.7",
|
||||||
"@types/react": "^18.0.15",
|
"@types/react": "^18.0.15",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"@types/react-timeago": "^4.1.3",
|
"@types/react-timeago": "^4.1.3",
|
||||||
|
|
|
@ -124,6 +124,7 @@ fn default_batch_size() -> u32 {
|
||||||
pub struct SrsEntry {
|
pub struct SrsEntry {
|
||||||
current_grade: u32,
|
current_grade: u32,
|
||||||
meanings: Vec<String>,
|
meanings: Vec<String>,
|
||||||
|
readings: Vec<String>,
|
||||||
associated_kanji: String,
|
associated_kanji: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,9 +154,14 @@ pub async fn generate_review_batch(
|
||||||
.map(|row| {
|
.map(|row| {
|
||||||
let meanings: String = row.get("Meanings");
|
let meanings: String = row.get("Meanings");
|
||||||
let meanings = meanings.split(",").map(|s| s.to_owned()).collect();
|
let meanings = meanings.split(",").map(|s| s.to_owned()).collect();
|
||||||
|
|
||||||
|
let readings: String = row.get("Readings");
|
||||||
|
let readings = readings.split(",").map(|s| s.to_owned()).collect();
|
||||||
|
|
||||||
SrsEntry {
|
SrsEntry {
|
||||||
current_grade: row.get("CurrentGrade"),
|
current_grade: row.get("CurrentGrade"),
|
||||||
meanings,
|
meanings,
|
||||||
|
readings,
|
||||||
associated_kanji: row.get("AssociatedKanji"),
|
associated_kanji: row.get("AssociatedKanji"),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
$kanjiCharacterSize: 28px;
|
||||||
|
|
||||||
.kanji-list {
|
.kanji-list {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -20,6 +22,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kanji-link-character {
|
||||||
|
font-size: $kanjiCharacterSize;
|
||||||
|
line-height: $kanjiCharacterSize;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.kanji-list-scroll {
|
.kanji-list-scroll {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import styles from "./KanjiList.module.scss";
|
||||||
import { Kanji } from "../types/Kanji";
|
import { Kanji } from "../types/Kanji";
|
||||||
import { Input, Spinner } from "@chakra-ui/react";
|
import { Input, Spinner } from "@chakra-ui/react";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
import SearchBar from "./SearchBar";
|
||||||
|
|
||||||
export interface KanjiListProps {
|
export interface KanjiListProps {
|
||||||
kanjiList: Kanji[];
|
kanjiList: Kanji[];
|
||||||
|
@ -56,8 +57,8 @@ export function KanjiList({
|
||||||
const className = classNames(styles["kanji-link"], active && styles["kanji-link-active"]);
|
const className = classNames(styles["kanji-link"], active && styles["kanji-link-active"]);
|
||||||
return (
|
return (
|
||||||
<Link key={kanji.character} className={className} to={`/kanji/${kanji.character}`}>
|
<Link key={kanji.character} className={className} to={`/kanji/${kanji.character}`}>
|
||||||
<Grid templateRows="repeat(2, 1fr)" templateColumns="1fr 3fr">
|
<Grid templateRows="repeat(2, 1fr)" templateColumns="auto 1fr" columnGap={4}>
|
||||||
<GridItem rowSpan={2} style={{ fontSize: "24px", textAlign: "center" }}>
|
<GridItem rowSpan={2} className={styles["kanji-link-character"]}>
|
||||||
{kanji.character}
|
{kanji.character}
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem>{kanji.meanings[0].meaning}</GridItem>
|
<GridItem>{kanji.meanings[0].meaning}</GridItem>
|
||||||
|
@ -72,7 +73,7 @@ export function KanjiList({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles["search-container"]}>
|
<div className={styles["search-container"]}>
|
||||||
<Input autoFocus placeholder="Search..." />
|
<SearchBar />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<small className={styles["result-count"]}>
|
<small className={styles["result-count"]}>
|
||||||
|
|
23
src/components/SearchBar.tsx
Normal file
23
src/components/SearchBar.tsx
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { SearchIcon } from "@chakra-ui/icons";
|
||||||
|
import { Input, InputGroup, InputRightElement, Spinner } from "@chakra-ui/react";
|
||||||
|
import { FormEvent, useState } from "react";
|
||||||
|
|
||||||
|
export default function SearchBar() {
|
||||||
|
const [status, setStatus] = useState("idle");
|
||||||
|
|
||||||
|
const onSubmit = (evt: FormEvent) => {
|
||||||
|
evt.preventDefault();
|
||||||
|
setStatus("loading");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={onSubmit}>
|
||||||
|
<InputGroup>
|
||||||
|
<Input autoFocus placeholder="Search..." />
|
||||||
|
<InputRightElement>
|
||||||
|
{{ idle: <SearchIcon />, loading: <Spinner /> }[status]}
|
||||||
|
</InputRightElement>
|
||||||
|
</InputGroup>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
37
src/lib/ConfirmQuitModal.tsx
Normal file
37
src/lib/ConfirmQuitModal.tsx
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalContent,
|
||||||
|
ModalFooter,
|
||||||
|
ModalHeader,
|
||||||
|
ModalOverlay,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
export default function ConfirmQuitModal({ isOpen, onClose }) {
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Confirm Quit</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody>
|
||||||
|
Are you sure you want to go back? Your current progress into this batch will not be saved.
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
<Button variant="ghost" onClick={onClose}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Link to="/">
|
||||||
|
<Button colorScheme="red" mr={3}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
|
@ -18,15 +18,31 @@ import {
|
||||||
import styles from "./SrsReviewPane.module.scss";
|
import styles from "./SrsReviewPane.module.scss";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { invoke } from "@tauri-apps/api/tauri";
|
import { invoke } from "@tauri-apps/api/tauri";
|
||||||
import { Link } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { ArrowBackIcon, CheckIcon } from "@chakra-ui/icons";
|
import { ArrowBackIcon, CheckIcon } from "@chakra-ui/icons";
|
||||||
import { FormEvent } from "react";
|
import { FormEvent } from "react";
|
||||||
|
import ConfirmQuitModal from "../lib/ConfirmQuitModal";
|
||||||
|
import * as _ from "lodash-es";
|
||||||
|
|
||||||
export interface SrsEntry {
|
export interface SrsEntry {
|
||||||
associated_kanji: string;
|
associated_kanji: string;
|
||||||
|
current_grade: number;
|
||||||
|
meanings: string[];
|
||||||
|
readings: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const startingSize = 10;
|
export enum ReviewItemType {
|
||||||
|
MEANING,
|
||||||
|
READING,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReviewItem {
|
||||||
|
type: ReviewItemType;
|
||||||
|
challenge: string;
|
||||||
|
possibleAnswers: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const batchSize = 10;
|
||||||
|
|
||||||
function Done() {
|
function Done() {
|
||||||
return (
|
return (
|
||||||
|
@ -42,54 +58,77 @@ function Done() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SrsReviewPane() {
|
export default function SrsReviewPane() {
|
||||||
const [reviewBatch, setReviewBatch] = useState<SrsEntry[] | null>(null);
|
// null = has not started, (.length == 0) = finished
|
||||||
|
const [reviewQueue, setReviewQueue] = useState<ReviewItem[] | null>(null);
|
||||||
|
const [anyProgress, setAnyProgress] = useState(false);
|
||||||
|
const [startingSize, setStartingSize] = useState<number | null>(null);
|
||||||
const [currentAnswer, setCurrentAnswer] = useState("");
|
const [currentAnswer, setCurrentAnswer] = useState("");
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!reviewBatch) {
|
if (!reviewQueue) {
|
||||||
invoke<SrsEntry[]>("generate_review_batch")
|
invoke<SrsEntry[]>("generate_review_batch")
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
console.log(result);
|
// setReviewBatch(result);
|
||||||
setReviewBatch(result);
|
const newReviews: ReviewItem[] = result.flatMap((srsEntry) => [
|
||||||
|
{
|
||||||
|
type: ReviewItemType.MEANING,
|
||||||
|
challenge: srsEntry.associated_kanji,
|
||||||
|
possibleAnswers: srsEntry.meanings,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: ReviewItemType.READING,
|
||||||
|
challenge: srsEntry.associated_kanji,
|
||||||
|
possibleAnswers: srsEntry.readings,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const newReviewsShuffled = _.shuffle(newReviews);
|
||||||
|
|
||||||
|
setReviewQueue(newReviewsShuffled);
|
||||||
|
setStartingSize(newReviews.length);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error("fuck!", err);
|
console.error("fuck!", err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [reviewBatch, setReviewBatch]);
|
}, [reviewQueue]);
|
||||||
|
|
||||||
const formSubmit = (evt: FormEvent) => {
|
const formSubmit = (evt: FormEvent) => {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
if (reviewBatch == null) return;
|
if (!reviewQueue) return;
|
||||||
|
|
||||||
// Check the answer
|
// Check the answer
|
||||||
|
|
||||||
// Set up for next question!
|
// Set up for next question!
|
||||||
|
setAnyProgress(true);
|
||||||
setCurrentAnswer("");
|
setCurrentAnswer("");
|
||||||
const [_, ...rest] = reviewBatch;
|
const [_, ...rest] = reviewQueue;
|
||||||
setReviewBatch(rest);
|
setReviewQueue(rest);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderInside = () => {
|
const renderInside = () => {
|
||||||
if (!reviewBatch) return <Spinner />;
|
if (!reviewQueue) return <Spinner />;
|
||||||
|
|
||||||
if (reviewBatch.length == 0) return <Done />;
|
if (reviewQueue.length == 0) return <Done />;
|
||||||
|
|
||||||
const progressValue = startingSize - reviewBatch.length;
|
const nextItem = reviewQueue[0];
|
||||||
const nextItem = reviewBatch[0];
|
|
||||||
|
console.log("next item", nextItem);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{startingSize && (
|
||||||
<Progress
|
<Progress
|
||||||
colorScheme="linkedin"
|
colorScheme="linkedin"
|
||||||
hasStripe
|
hasStripe
|
||||||
isAnimated
|
isAnimated
|
||||||
max={startingSize}
|
max={startingSize}
|
||||||
value={progressValue}
|
value={startingSize - reviewQueue.length}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<h1 className={styles["test-word"]}>{nextItem.associated_kanji}</h1>
|
<h1 className={styles["test-word"]}>{nextItem.challenge}</h1>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Debug</summary>
|
<summary>Debug</summary>
|
||||||
|
@ -117,38 +156,25 @@ export default function SrsReviewPane() {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const quit = () => {
|
||||||
|
if (!reviewQueue || !anyProgress) {
|
||||||
|
return navigate("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpen();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
<Container>
|
<Container>
|
||||||
<Button onClick={onOpen}>
|
<Button onClick={quit}>
|
||||||
<ArrowBackIcon />
|
<ArrowBackIcon />
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
<div className={styles.container}>{renderInside()}</div>
|
<div className={styles.container}>{renderInside()}</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<Modal isOpen={isOpen} onClose={onClose}>
|
<ConfirmQuitModal isOpen={isOpen} onClose={onClose} />
|
||||||
<ModalOverlay />
|
|
||||||
<ModalContent>
|
|
||||||
<ModalHeader>Confirm Quit</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
|
||||||
<ModalBody>
|
|
||||||
Are you sure you want to go back? Your current progress into this batch will not be
|
|
||||||
saved.
|
|
||||||
</ModalBody>
|
|
||||||
|
|
||||||
<ModalFooter>
|
|
||||||
<Button variant="ghost" onClick={onClose}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<Link to="/">
|
|
||||||
<Button colorScheme="red" mr={3}>
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue