- Solved the bug on Diagnostic where the exams weren't loading;
- Removed the Layout appearance and made it so the abandon popup appears on click and not on enter
This commit is contained in:
@@ -3,60 +3,53 @@ import {Fragment} from "react";
|
|||||||
import Button from "./Low/Button";
|
import Button from "./Low/Button";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
abandonPopupTitle: string;
|
abandonPopupTitle: string;
|
||||||
abandonPopupDescription: string;
|
abandonPopupDescription: string;
|
||||||
abandonConfirmButtonText: string;
|
abandonConfirmButtonText: string;
|
||||||
onAbandon: Function;
|
onAbandon: () => void;
|
||||||
onCancel: Function;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AbandonPopup({
|
export default function AbandonPopup({isOpen, abandonPopupTitle, abandonPopupDescription, abandonConfirmButtonText, onAbandon, onCancel}: Props) {
|
||||||
isOpen,
|
return (
|
||||||
abandonPopupTitle,
|
<Transition show={isOpen} as={Fragment}>
|
||||||
abandonPopupDescription,
|
<Dialog onClose={onCancel} className="relative z-50">
|
||||||
abandonConfirmButtonText,
|
<Transition.Child
|
||||||
onAbandon,
|
as={Fragment}
|
||||||
onCancel,
|
enter="ease-out duration-300"
|
||||||
}: Props) {
|
enterFrom="opacity-0"
|
||||||
return (
|
enterTo="opacity-100"
|
||||||
<Transition show={isOpen} as={Fragment}>
|
leave="ease-in duration-200"
|
||||||
<Dialog onClose={onCancel} className="relative z-50">
|
leaveFrom="opacity-100"
|
||||||
<Transition.Child
|
leaveTo="opacity-0">
|
||||||
as={Fragment}
|
<div className="fixed inset-0 bg-black/30" />
|
||||||
enter="ease-out duration-300"
|
</Transition.Child>
|
||||||
enterFrom="opacity-0"
|
|
||||||
enterTo="opacity-100"
|
<Transition.Child
|
||||||
leave="ease-in duration-200"
|
as={Fragment}
|
||||||
leaveFrom="opacity-100"
|
enter="ease-out duration-300"
|
||||||
leaveTo="opacity-0">
|
enterFrom="opacity-0 scale-95"
|
||||||
<div className="fixed inset-0 bg-black/30" />
|
enterTo="opacity-100 scale-100"
|
||||||
</Transition.Child>
|
leave="ease-in duration-200"
|
||||||
|
leaveFrom="opacity-100 scale-100"
|
||||||
<Transition.Child
|
leaveTo="opacity-0 scale-95">
|
||||||
as={Fragment}
|
<div className="fixed inset-0 flex items-center justify-center p-4">
|
||||||
enter="ease-out duration-300"
|
<Dialog.Panel className="w-full max-w-2xl h-fit p-8 rounded-xl bg-white flex flex-col gap-4">
|
||||||
enterFrom="opacity-0 scale-95"
|
<Dialog.Title className="font-bold text-xl">{abandonPopupTitle}</Dialog.Title>
|
||||||
enterTo="opacity-100 scale-100"
|
<span>{abandonPopupDescription}</span>
|
||||||
leave="ease-in duration-200"
|
<div className="w-full flex justify-between mt-8">
|
||||||
leaveFrom="opacity-100 scale-100"
|
<Button color="purple" onClick={onCancel} variant="outline" className="max-w-[200px] self-end w-full">
|
||||||
leaveTo="opacity-0 scale-95">
|
Cancel
|
||||||
<div className="fixed inset-0 flex items-center justify-center p-4">
|
</Button>
|
||||||
<Dialog.Panel className="w-full max-w-2xl h-fit p-8 rounded-xl bg-white flex flex-col gap-4">
|
<Button color="purple" onClick={onAbandon} className="max-w-[200px] self-end w-full">
|
||||||
<Dialog.Title className="font-bold text-xl">{abandonPopupTitle}</Dialog.Title>
|
{abandonConfirmButtonText}
|
||||||
<span>{abandonPopupDescription}</span>
|
</Button>
|
||||||
<div className="w-full flex justify-between mt-8">
|
</div>
|
||||||
<Button color="purple" onClick={onCancel} variant="outline" className="max-w-[200px] self-end w-full">
|
</Dialog.Panel>
|
||||||
Cancel
|
</div>
|
||||||
</Button>
|
</Transition.Child>
|
||||||
<Button color="purple" onClick={onAbandon} className="max-w-[200px] self-end w-full">
|
</Dialog>
|
||||||
{abandonConfirmButtonText}
|
</Transition>
|
||||||
</Button>
|
);
|
||||||
</div>
|
}
|
||||||
</Dialog.Panel>
|
|
||||||
</div>
|
|
||||||
</Transition.Child>
|
|
||||||
</Dialog>
|
|
||||||
</Transition>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import axios from "axios";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import {capitalize} from "lodash";
|
import {capitalize} from "lodash";
|
||||||
import {useRouter} from "next/router";
|
import {useRouter} from "next/router";
|
||||||
import {useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {BsBook, BsChevronDown, BsHeadphones, BsMegaphone, BsPen, BsQuestionSquare} from "react-icons/bs";
|
import {BsBook, BsChevronDown, BsHeadphones, BsMegaphone, BsPen, BsQuestionSquare} from "react-icons/bs";
|
||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
import Button from "./Low/Button";
|
import Button from "./Low/Button";
|
||||||
@@ -23,7 +23,7 @@ interface Props {
|
|||||||
const DIAGNOSTIC_EXAMS = [
|
const DIAGNOSTIC_EXAMS = [
|
||||||
["reading", "CurQtQoxWmHaJHeN0JW2"],
|
["reading", "CurQtQoxWmHaJHeN0JW2"],
|
||||||
["listening", "Y6cMao8kUcVnPQOo6teV"],
|
["listening", "Y6cMao8kUcVnPQOo6teV"],
|
||||||
["writing", "hbueuDaEZXV37EW7I12A"],
|
["writing", "B1J90R4Lmdn2dwjdHEwj"],
|
||||||
["speaking", "QVFm4pdcziJQZN2iUTDo"],
|
["speaking", "QVFm4pdcziJQZN2iUTDo"],
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ export default function Diagnostic({onFinish}: Props) {
|
|||||||
if (exams.every((x) => !!x)) {
|
if (exams.every((x) => !!x)) {
|
||||||
setExams(exams.map((x) => x!));
|
setExams(exams.map((x) => x!));
|
||||||
setSelectedModules(exams.map((x) => x!.module));
|
setSelectedModules(exams.map((x) => x!.module));
|
||||||
router.push("/exam");
|
router.push("/exercises");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -58,7 +58,7 @@ export default function Diagnostic({onFinish}: Props) {
|
|||||||
axios
|
axios
|
||||||
.patch("/api/users/update", {
|
.patch("/api/users/update", {
|
||||||
focus,
|
focus,
|
||||||
levels: Object.values(levels).includes(-1) ? {reading: -1, listening: -1, writing: -1, speaking: -1} : levels,
|
levels: Object.values(levels).includes(-1) ? {reading: 0, listening: 0, writing: 0, speaking: 0} : levels,
|
||||||
desiredLevels,
|
desiredLevels,
|
||||||
isFirstLogin: false,
|
isFirstLogin: false,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onFocusLayerMouseEnter: Function,
|
onFocusLayerMouseEnter?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function FocusLayer({
|
export default function FocusLayer({onFocusLayerMouseEnter}: Props) {
|
||||||
onFocusLayerMouseEnter,
|
return <div className="absolute top-0 left-0 bottom-0 right-0" onMouseDown={onFocusLayerMouseEnter} />;
|
||||||
}: Props) {
|
|
||||||
return (
|
|
||||||
<div className="bg-gray-700 bg-opacity-30 absolute top-0 left-0 bottom-0 right-0" onMouseEnter={onFocusLayerMouseEnter}/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,18 +9,18 @@ interface Props {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
navDisabled?: boolean;
|
navDisabled?: boolean;
|
||||||
focusMode?: boolean
|
focusMode?: boolean;
|
||||||
onFocusLayerMouseEnter?: Function;
|
onFocusLayerMouseEnter?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Layout({user, children, className, navDisabled = false, focusMode = false, onFocusLayerMouseEnter }: Props) {
|
export default function Layout({user, children, className, navDisabled = false, focusMode = false, onFocusLayerMouseEnter}: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="w-full min-h-full h-screen flex flex-col bg-mti-gray-smoke">
|
<main className="w-full min-h-full h-screen flex flex-col bg-mti-gray-smoke">
|
||||||
<Navbar user={user} navDisabled={navDisabled} focusMode={focusMode} onFocusLayerMouseEnter={onFocusLayerMouseEnter} />
|
<Navbar user={user} navDisabled={navDisabled} focusMode={focusMode} onFocusLayerMouseEnter={onFocusLayerMouseEnter} />
|
||||||
<div className="h-full w-full flex gap-2">
|
<div className="h-full w-full flex gap-2">
|
||||||
<Sidebar path={router.pathname} navDisabled={navDisabled} focusMode={focusMode} onFocusLayerMouseEnter={onFocusLayerMouseEnter}/>
|
<Sidebar path={router.pathname} navDisabled={navDisabled} focusMode={focusMode} onFocusLayerMouseEnter={onFocusLayerMouseEnter} />
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"w-5/6 min-h-full h-fit mr-8 bg-white shadow-md rounded-2xl p-12 pb-8 flex flex-col gap-12 relative overflow-hidden mt-2",
|
"w-5/6 min-h-full h-fit mr-8 bg-white shadow-md rounded-2xl p-12 pb-8 flex flex-col gap-12 relative overflow-hidden mt-2",
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import {User} from "@/interfaces/user";
|
import {User} from "@/interfaces/user";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import {Avatar} from "primereact/avatar";
|
import {Avatar} from "primereact/avatar";
|
||||||
import FocusLayer from '@/components/FocusLayer';
|
import FocusLayer from "@/components/FocusLayer";
|
||||||
import { preventNavigation } from "@/utils/navigation.disabled";
|
import {preventNavigation} from "@/utils/navigation.disabled";
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
user: User;
|
user: User;
|
||||||
navDisabled?: boolean;
|
navDisabled?: boolean;
|
||||||
focusMode?: boolean;
|
focusMode?: boolean;
|
||||||
onFocusLayerMouseEnter?: Function;
|
onFocusLayerMouseEnter?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable @next/next/no-img-element */
|
/* eslint-disable @next/next/no-img-element */
|
||||||
@@ -26,7 +25,7 @@ export default function Navbar({user, navDisabled = false, focusMode = false, on
|
|||||||
<span className="text-right">{user.name}</span>
|
<span className="text-right">{user.name}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{focusMode && <FocusLayer onFocusLayerMouseEnter={onFocusLayerMouseEnter}/>}
|
{focusMode && <FocusLayer onFocusLayerMouseEnter={onFocusLayerMouseEnter} />}
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -321,25 +321,22 @@ export default function Page() {
|
|||||||
user={user}
|
user={user}
|
||||||
className="justify-between"
|
className="justify-between"
|
||||||
focusMode={selectedModules.length !== 0}
|
focusMode={selectedModules.length !== 0}
|
||||||
onFocusLayerMouseEnter={() => setShowAbandonPopup(true)}
|
onFocusLayerMouseEnter={() => setShowAbandonPopup(true)}>
|
||||||
>
|
<>
|
||||||
<>
|
|
||||||
{renderScreen()}
|
{renderScreen()}
|
||||||
<AbandonPopup
|
<AbandonPopup
|
||||||
isOpen={showAbandonPopup}
|
isOpen={showAbandonPopup}
|
||||||
abandonPopupTitle="Leave Exam"
|
abandonPopupTitle="Leave Exercise"
|
||||||
abandonPopupDescription="Are you sure you want to leave the exam? You will lose all your progress."
|
abandonPopupDescription="Are you sure you want to leave the exercise? You will lose all your progress."
|
||||||
abandonConfirmButtonText="Confirm"
|
abandonConfirmButtonText="Confirm"
|
||||||
onAbandon={() => {
|
onAbandon={() => {
|
||||||
console.log('TODO: Handle Abandon');
|
|
||||||
setExam(undefined);
|
setExam(undefined);
|
||||||
setSelectedModules([]);
|
setSelectedModules([]);
|
||||||
setShowAbandonPopup(false)
|
setShowAbandonPopup(false);
|
||||||
return true;
|
|
||||||
}}
|
}}
|
||||||
onCancel={() => setShowAbandonPopup(false)}
|
onCancel={() => setShowAbandonPopup(false)}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
</Layout>
|
</Layout>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -323,25 +323,22 @@ export default function Page() {
|
|||||||
user={user}
|
user={user}
|
||||||
className="justify-between"
|
className="justify-between"
|
||||||
focusMode={selectedModules.length !== 0}
|
focusMode={selectedModules.length !== 0}
|
||||||
onFocusLayerMouseEnter={() => setShowAbandonPopup(true)}
|
onFocusLayerMouseEnter={() => setShowAbandonPopup(true)}>
|
||||||
>
|
|
||||||
<>
|
<>
|
||||||
{renderScreen()}
|
{renderScreen()}
|
||||||
<AbandonPopup
|
<AbandonPopup
|
||||||
isOpen={showAbandonPopup}
|
isOpen={showAbandonPopup}
|
||||||
|
abandonPopupTitle="Leave Exercise"
|
||||||
abandonPopupTitle="Leave Exercise"
|
abandonPopupDescription="Are you sure you want to leave the exercise? You will lose all your progress."
|
||||||
abandonPopupDescription="Are you sure you want to leave the exercise? You will lose all your progress."
|
abandonConfirmButtonText="Confirm"
|
||||||
abandonConfirmButtonText="Confirm"
|
onAbandon={() => {
|
||||||
onAbandon={() => {
|
setExam(undefined);
|
||||||
setExam(undefined);
|
setSelectedModules([]);
|
||||||
setSelectedModules([]);
|
setShowAbandonPopup(false);
|
||||||
setShowAbandonPopup(false)
|
}}
|
||||||
return true;
|
onCancel={() => setShowAbandonPopup(false)}
|
||||||
}}
|
/>
|
||||||
onCancel={() => setShowAbandonPopup(false)}
|
</>
|
||||||
/>
|
|
||||||
</>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user