ENCOA-274
This commit is contained in:
@@ -185,12 +185,12 @@ export default function BatchCreateUser({ user, entities = [], permissions, onFi
|
||||
if (!confirm(`You are about to ${[newUsersSentence, existingUsersSentence].filter((x) => !!x).join(" and ")}, are you sure you want to continue?`))
|
||||
return;
|
||||
|
||||
/*Promise.all(duplicatedUsers.map(async (u) => await axios.post(`/api/invites`, {to: u.id, entity, from: user.id})))
|
||||
.then(() => toast.success(`Successfully invited ${duplicatedUsers.length} registered student(s)!`))
|
||||
Promise.all(newUsers.map(async (u) => await axios.post(`/api/invites`, {to: u.id, entity, from: user.id})))
|
||||
.then(() => toast.success(`Successfully invited ${newUsers.length} registered student(s)!`))
|
||||
.finally(() => {
|
||||
if (newUsers.length === 0) setIsLoading(false);
|
||||
});
|
||||
*/
|
||||
|
||||
if (newUsers.length > 0) {
|
||||
setIsLoading(true);
|
||||
|
||||
@@ -392,6 +392,7 @@ export default function BatchCreateUser({ user, entities = [], permissions, onFi
|
||||
<UserTable users={duplicatedUsers} />
|
||||
</div>
|
||||
)}
|
||||
{(duplicatedUsers.length !== 0 && newUsers.length === 0) && <span className="text-red-500 font-bold">The imported .csv only contains duplicated users!</span>}
|
||||
<Button className="my-auto mt-4" onClick={makeUsers} disabled={newUsers.length === 0}>
|
||||
Create {newUsers.length !== 0 ? `${newUsers.length} New Users` : ''}
|
||||
</Button>
|
||||
|
||||
@@ -11,7 +11,7 @@ import Reading from "@/exams/Reading";
|
||||
import Selection from "@/exams/Selection";
|
||||
import Speaking from "@/exams/Speaking";
|
||||
import Writing from "@/exams/Writing";
|
||||
import { Exam, LevelExam, UserSolution, Variant } from "@/interfaces/exam";
|
||||
import { Exam, LevelExam, UserSolution, Variant, WritingExam } from "@/interfaces/exam";
|
||||
import { User } from "@/interfaces/user";
|
||||
import { evaluateSpeakingAnswer, evaluateWritingAnswer } from "@/utils/evaluation";
|
||||
import { getExam } from "@/utils/exams";
|
||||
@@ -126,7 +126,7 @@ export default function ExamPage({ page, user, destination = "/", hideSidebar =
|
||||
await Promise.all(
|
||||
exam.exercises.map(async (exercise, index) => {
|
||||
if (exercise.type === "writing")
|
||||
await evaluateWritingAnswer(user.id, sessionId, exercise, index + 1, userSolutions.find((x) => x.exercise === exercise.id)!);
|
||||
await evaluateWritingAnswer(user.id, sessionId, exercise, index + 1, userSolutions.find((x) => x.exercise === exercise.id)!, exercise.attachment?.url);
|
||||
|
||||
if (exercise.type === "interactiveSpeaking" || exercise.type === "speaking"){
|
||||
await evaluateSpeakingAnswer(
|
||||
|
||||
@@ -65,7 +65,8 @@ async function POST(req: NextApiRequest, res: NextApiResponse) {
|
||||
// Check whether the id of the exam matches another exam with different
|
||||
// owners, throw exception if there is, else allow editing
|
||||
const ownersSet = new Set(docSnap?.owners || []);
|
||||
if (docSnap?.owners?.length === exam.owners.lenght && exam.owners.every((e: string) => ownersSet.has(e))) {
|
||||
|
||||
if (docSnap !== null && docSnap?.owners?.length === exam.owners.lenght && exam.owners.every((e: string) => ownersSet.has(e))) {
|
||||
throw new Error("Name already exists");
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!req.session.user) return res.status(401).json({ ok: false });
|
||||
|
||||
const queryParams = queryToURLSearchParams(req);
|
||||
|
||||
let endpoint = queryParams.getAll('module').join("/");
|
||||
|
||||
if (endpoint.startsWith("level")) {
|
||||
@@ -41,12 +42,27 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
||||
endpoint = "reading/"
|
||||
}
|
||||
|
||||
const result = await axios.post(`${process.env.BACKEND_URL}/${endpoint}`,
|
||||
req.body,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${process.env.BACKEND_JWT}` },
|
||||
},
|
||||
);
|
||||
queryParams.delete('module');
|
||||
const queryString = queryParams.toString();
|
||||
|
||||
res.status(200).json(result.data);
|
||||
}
|
||||
const hasFiles = req.headers['content-type']?.startsWith('multipart/form-data');
|
||||
|
||||
// https://github.com/vercel/next.js/discussions/36153#discussioncomment-3029675
|
||||
// This just proxies the request
|
||||
|
||||
const { data } = await axios.post(
|
||||
`${process.env.BACKEND_URL}/${endpoint}${hasFiles ? '/attachment' : ''}${queryString.length > 0 ? `?${queryString}` : ''}`, req, {
|
||||
responseType: "stream",
|
||||
headers: {
|
||||
"Content-Type": req.headers["content-type"],
|
||||
Authorization: `Bearer ${process.env.BACKEND_JWT}`,
|
||||
},
|
||||
});
|
||||
data.pipe(res);
|
||||
}
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
bodyParser: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -93,6 +93,11 @@ export default function Generation({ id, user, exam, examModule, permissions }:
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
const state = modules;
|
||||
|
||||
if (state.writing.academic_url) {
|
||||
URL.revokeObjectURL(state.writing.academic_url);
|
||||
}
|
||||
|
||||
state.listening.sections.forEach(section => {
|
||||
const listeningPart = section.state as ListeningPart;
|
||||
if (listeningPart.audio?.source) {
|
||||
|
||||
Reference in New Issue
Block a user