fixed moodle logic
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
HUB_SERVER_PORT=3003
|
||||
MOODLE_TOKEN=ac346f0324647b68488d13fd52a9bbe8
|
||||
MOODLE_API_TOKEN=ac346f0324647b68488d13fd52a9bbe8
|
||||
NEXT_PUBLIC_HUB_URL=http://localhost:3000
|
||||
MOODLE_URL=http://localhost:8081
|
||||
NEXT_PUBLIC_MOODLE_URL=
|
||||
MAIL_SERVER="asmtp.mail.hostpoint.ch"
|
||||
MAIL_USER="noreply@virtualairrescue.com"
|
||||
MAIL_PASSWORD="b7316PB8aDPCC%-&"
|
||||
|
||||
@@ -4,8 +4,12 @@ export const getMoodleUserById = async (id: string) => {
|
||||
const { data: user } = await axios.get(
|
||||
`${process.env.NEXT_PUBLIC_MOODLE_URL}/webservice/rest/server.php`,
|
||||
{
|
||||
auth: {
|
||||
username: "moodleuser",
|
||||
password: "Xo1SXaLYBa7Yb6WW",
|
||||
},
|
||||
params: {
|
||||
wstoken: process.env.MOODLE_TOKEN,
|
||||
wstoken: process.env.MOODLE_API_TOKEN,
|
||||
wsfunction: "core_user_get_users_by_field",
|
||||
moodlewsrestformat: "json",
|
||||
field: "idnumber",
|
||||
@@ -33,8 +37,12 @@ export const getMoodleQuizResult = async (userId: string, quizId: string) => {
|
||||
const { data: quizzes } = await axios.get(
|
||||
`${process.env.NEXT_PUBLIC_MOODLE_URL}/webservice/rest/server.php`,
|
||||
{
|
||||
auth: {
|
||||
username: "moodleuser",
|
||||
password: "Xo1SXaLYBa7Yb6WW",
|
||||
},
|
||||
params: {
|
||||
wstoken: process.env.MOODLE_TOKEN,
|
||||
wstoken: process.env.MOODLE_API_TOKEN,
|
||||
wsfunction: "mod_quiz_get_user_attempts",
|
||||
moodlewsrestformat: "json",
|
||||
quizid: quizId,
|
||||
@@ -49,8 +57,12 @@ export const getMoodleCourseCompletionStatus = async (userId: string, courseId:
|
||||
const { data: completionStatus } = await axios.get(
|
||||
`${process.env.NEXT_PUBLIC_MOODLE_URL}/webservice/rest/server.php`,
|
||||
{
|
||||
auth: {
|
||||
username: "moodleuser",
|
||||
password: "Xo1SXaLYBa7Yb6WW",
|
||||
},
|
||||
params: {
|
||||
wstoken: process.env.MOODLE_TOKEN,
|
||||
wstoken: process.env.MOODLE_API_TOKEN,
|
||||
wsfunction: "core_completion_get_course_completion_status",
|
||||
moodlewsrestformat: "json",
|
||||
userid: userId,
|
||||
|
||||
@@ -25,7 +25,6 @@ router.post("/handle-participant-finished", async (req, res) => {
|
||||
},
|
||||
},
|
||||
});
|
||||
console.log("Handeling Participant-completed", participant?.User.publicId);
|
||||
if (!participant) {
|
||||
res.status(404).json({ error: "Participant not found" });
|
||||
return;
|
||||
@@ -62,11 +61,16 @@ router.post("/check-moodle-results", async (req, res) => {
|
||||
res.status(400).json({ error: "Teilnehmer hat keine Moodle-ID" });
|
||||
return;
|
||||
}
|
||||
const quizzResult = await getMoodleCourseCompletionStatus(
|
||||
const courseStatus = await getMoodleCourseCompletionStatus(
|
||||
participant.User.moodleId.toString(),
|
||||
participant.Event.finisherMoodleCourseId!,
|
||||
);
|
||||
if (quizzResult?.completionstatus?.completed === true) {
|
||||
|
||||
if (courseStatus?.completionstatus?.completed === true) {
|
||||
prisma.participant.update({
|
||||
where: { id: participant.id },
|
||||
data: { finisherMoodleCurseCompleted: true },
|
||||
});
|
||||
await handleParticipantFinished(participant.Event, participant, participant.User);
|
||||
res
|
||||
.status(200)
|
||||
|
||||
@@ -9,6 +9,6 @@ DISCORD_BOT_TOKEN=
|
||||
NEXT_PUBLIC_DISCORD_URL=
|
||||
DISCORD_REDIRECT=
|
||||
MOODLE_PW=var-api-user-P1
|
||||
MOODLE_TOKEN=ac346f0324647b68488d13fd52a9bbe8
|
||||
MOODLE_API_TOKEN=ac346f0324647b68488d13fd52a9bbe8
|
||||
NEXT_PUBLIC_MOODLE_URL=http://localhost:8081
|
||||
NEXT_PUBLIC_DISPATCH_URL=http://localhost:3001
|
||||
@@ -62,15 +62,6 @@ export const AppointmentModal = ({
|
||||
timeCaption="Uhrzeit"
|
||||
showTimeCaption
|
||||
/>
|
||||
{/* <Input
|
||||
form={appointmentForm}
|
||||
type="datetime-local"
|
||||
label="Datum"
|
||||
name="appointmentDate"
|
||||
formOptions={{
|
||||
valueAsDate: true,
|
||||
}}
|
||||
/> */}
|
||||
<div>
|
||||
<PaginatedTable
|
||||
hide={appointmentForm.watch("id") === undefined}
|
||||
|
||||
@@ -55,23 +55,28 @@ export const ParticipantModal = ({ participantForm, ref }: ParticipantModalProps
|
||||
<Button
|
||||
className="btn-sm"
|
||||
onClick={async () => {
|
||||
if (!participantForm.watch("id")) return;
|
||||
try {
|
||||
if (!participantForm.watch("id")) return;
|
||||
|
||||
const participant = participantForm.getValues();
|
||||
await handleParticipantFinished(participant.id.toString()).catch((e) => {
|
||||
const error = e as AxiosError;
|
||||
const participant = participantForm.getValues();
|
||||
await handleParticipantFinished(participant.id.toString()).catch((e) => {
|
||||
const error = e as AxiosError;
|
||||
});
|
||||
|
||||
toast.success("Workflow erfolgreich ausgeführt");
|
||||
router.refresh();
|
||||
} catch (error) {
|
||||
const e = error as AxiosError;
|
||||
if (
|
||||
error.response?.data &&
|
||||
typeof error.response.data === "object" &&
|
||||
"error" in error.response.data
|
||||
e.response?.data &&
|
||||
typeof e.response.data === "object" &&
|
||||
"error" in e.response.data
|
||||
) {
|
||||
toast.error(`Fehler: ${error.response.data.error}`);
|
||||
toast.error(`Fehler: ${e.response.data.error}`);
|
||||
} else {
|
||||
toast.error("Unbekannter Fehler beim ausführen des Workflows");
|
||||
}
|
||||
});
|
||||
toast.success("Workflow erfolgreich ausgeführt");
|
||||
router.refresh();
|
||||
}
|
||||
}}
|
||||
>
|
||||
Event-abgeschlossen Workflow ausführen
|
||||
|
||||
@@ -158,7 +158,7 @@ export const ProfileForm: React.FC<ProfileFormProps> = ({ user }: ProfileFormPro
|
||||
form={form}
|
||||
name="permissions"
|
||||
label="Permissions"
|
||||
isDisabled={user.permissions.length > (session.data?.user?.permissions?.length ?? 0)}
|
||||
isDisabled={!session.data?.user.permissions.includes("ADMIN_USER_ADVANCED")}
|
||||
options={Object.entries(PERMISSION).map(([key, value]) => ({
|
||||
label: value,
|
||||
value: key,
|
||||
@@ -325,6 +325,7 @@ export const ConnectionHistory: React.FC<{ user: User }> = ({ user }: { user: Us
|
||||
export const UserPenalties = ({ user }: { user: User }) => {
|
||||
const createdUser = useSession().data?.user;
|
||||
const penaltyTable = useRef<PaginatedTableRef>(null);
|
||||
const session = useSession();
|
||||
return (
|
||||
<div className="card-body">
|
||||
<h2 className="card-title flex justify-between">
|
||||
@@ -353,25 +354,27 @@ export const UserPenalties = ({ user }: { user: User }) => {
|
||||
btnTip="Timeban hinzufügen"
|
||||
showDatePicker={true}
|
||||
/>
|
||||
<PenaltyDropdown
|
||||
Icon={<LockKeyhole size={15} />}
|
||||
onClick={async ({ reason }) => {
|
||||
if (!reason) return toast.error("Bitte gib einen Grund für die Strafe an.");
|
||||
if (!createdUser)
|
||||
return toast.error("Du musst eingeloggt sein, um eine Strafe zu erstellen.");
|
||||
await addPenalty({
|
||||
reason,
|
||||
type: "BAN",
|
||||
userId: user.id,
|
||||
createdUserId: createdUser.id,
|
||||
});
|
||||
await editUser(user.id, { isBanned: true });
|
||||
penaltyTable.current?.refresh();
|
||||
toast.success("Ban wurde hinzugefügt!");
|
||||
}}
|
||||
btnClassName="btn btn-outline btn-error tooltip-error"
|
||||
btnTip="Rechte-entzug hinzufügen"
|
||||
/>
|
||||
{session.data?.user.permissions.includes("ADMIN_USER_ADVANCED") && (
|
||||
<PenaltyDropdown
|
||||
Icon={<LockKeyhole size={15} />}
|
||||
onClick={async ({ reason }) => {
|
||||
if (!reason) return toast.error("Bitte gib einen Grund für die Strafe an.");
|
||||
if (!createdUser)
|
||||
return toast.error("Du musst eingeloggt sein, um eine Strafe zu erstellen.");
|
||||
await addPenalty({
|
||||
reason,
|
||||
type: "BAN",
|
||||
userId: user.id,
|
||||
createdUserId: createdUser.id,
|
||||
});
|
||||
await editUser(user.id, { isBanned: true });
|
||||
penaltyTable.current?.refresh();
|
||||
toast.success("Ban wurde hinzugefügt!");
|
||||
}}
|
||||
btnClassName="btn btn-outline btn-error tooltip-error"
|
||||
btnTip="Nutzerkonto sperren"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</h2>
|
||||
<PaginatedTable
|
||||
@@ -484,7 +487,7 @@ export const AdminForm = ({
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{user.isBanned && (
|
||||
{user.isBanned && session?.user.permissions.includes("ADMIN_USER_ADVANCED") && (
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await editUser(user.id, { isBanned: false });
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
import { use, useEffect } from "react";
|
||||
import { CheckCircledIcon, CalendarIcon, EnterIcon } from "@radix-ui/react-icons";
|
||||
import { Event, EventAppointment, Participant, User } from "@repo/db";
|
||||
import { cn } from "../../../../helper/cn";
|
||||
@@ -87,6 +87,10 @@ const ModalBtn = ({
|
||||
? (selectedDate as any)?.Participants?.length + 1
|
||||
: ownIndexInParticipantList + 1;
|
||||
|
||||
const missingRequirements =
|
||||
event.requiredBadges?.length > 0 &&
|
||||
!event.requiredBadges.some((badge) => user.badges.includes(badge));
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
@@ -96,14 +100,20 @@ const ModalBtn = ({
|
||||
eventCompleted(event, participant) && "btn-success",
|
||||
)}
|
||||
onClick={openModal}
|
||||
disabled={eventCompleted(event, participant)}
|
||||
disabled={eventCompleted(event, participant) || missingRequirements}
|
||||
>
|
||||
{participant && !eventCompleted(event, participant) && (
|
||||
{missingRequirements && (
|
||||
<>
|
||||
<TriangleAlert className="h-6 w-6 shrink-0 stroke-current" fill="none" />
|
||||
fehlende Anforderungen
|
||||
</>
|
||||
)}
|
||||
{participant && !eventCompleted(event, participant) && !missingRequirements && (
|
||||
<>
|
||||
<EyeIcon /> Anzeigen
|
||||
</>
|
||||
)}
|
||||
{!participant && (
|
||||
{!participant && !missingRequirements && (
|
||||
<>
|
||||
<EnterIcon /> Anmelden
|
||||
</>
|
||||
@@ -287,16 +297,20 @@ const MoodleCourseIndicator = ({
|
||||
<button
|
||||
className="btn btn-xs btn-info ml-2"
|
||||
onClick={async () => {
|
||||
await upsertParticipant({
|
||||
eventId: event.id,
|
||||
userId: user.id,
|
||||
finisherMoodleCurseCompleted: false,
|
||||
});
|
||||
try {
|
||||
await upsertParticipant({
|
||||
eventId: event.id,
|
||||
userId: user.id,
|
||||
finisherMoodleCurseCompleted: false,
|
||||
});
|
||||
|
||||
if (user.moodleId) {
|
||||
await inscribeToMoodleCourse(moodleCourseId, user.moodleId);
|
||||
if (user.moodleId) {
|
||||
await inscribeToMoodleCourse(moodleCourseId, user.moodleId);
|
||||
}
|
||||
window.open(courseUrl, "_blank");
|
||||
} catch (error) {
|
||||
console.log("Fehler beim öffnen des Moodle-Kurses", error);
|
||||
}
|
||||
window.open(courseUrl, "_blank");
|
||||
}}
|
||||
>
|
||||
Zum Moodle Kurs
|
||||
|
||||
@@ -11,21 +11,12 @@ export default async function Page() {
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: session.user.id,
|
||||
Penaltys: {
|
||||
some: {
|
||||
until: {
|
||||
gte: new Date(),
|
||||
},
|
||||
suspended: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
discordAccounts: true,
|
||||
Penaltys: true,
|
||||
},
|
||||
});
|
||||
console.log("User", session, user);
|
||||
const userPenaltys = await prisma.penalty.findMany({
|
||||
where: {
|
||||
userId: session.user.id,
|
||||
|
||||
@@ -33,7 +33,7 @@ export const VerticalNav = async () => {
|
||||
<li>
|
||||
<Link href="/logbook">
|
||||
<ReaderIcon />
|
||||
Logbook
|
||||
Logbuch
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { DiscordAccount, prisma, User } from "@repo/db";
|
||||
import bcrypt from "bcryptjs";
|
||||
import oldUser from "./var.User.json";
|
||||
import { OldUser } from "../../../../types/oldUser";
|
||||
import { sendVerificationLink } from "(app)/admin/user/action";
|
||||
|
||||
export const options: AuthOptions = {
|
||||
providers: [
|
||||
@@ -69,6 +70,7 @@ export const options: AuthOptions = {
|
||||
},
|
||||
});
|
||||
}
|
||||
await sendVerificationLink(newUser.id);
|
||||
return newUser;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ export const GET = async (req: NextRequest) => {
|
||||
if (!user) return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||
setTimeout(async () => {
|
||||
const moodleUser = await getMoodleUserById(user.id);
|
||||
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: user.id,
|
||||
|
||||
@@ -1,37 +1,44 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const enrollUserInCourse = async (
|
||||
courseid: number | string,
|
||||
userid: number | string,
|
||||
) => {
|
||||
const { data: enrollmentResponse } = await axios.get(
|
||||
`${process.env.NEXT_PUBLIC_MOODLE_URL}/webservice/rest/server.php`,
|
||||
{
|
||||
params: {
|
||||
wstoken: process.env.MOODLE_TOKEN,
|
||||
wsfunction: "enrol_manual_enrol_users",
|
||||
moodlewsrestformat: "json",
|
||||
enrolments: [
|
||||
{
|
||||
roleid: 5,
|
||||
userid: typeof userid === "string" ? parseInt(userid) : userid,
|
||||
courseid:
|
||||
typeof courseid === "string" ? parseInt(courseid) : courseid,
|
||||
},
|
||||
],
|
||||
export const enrollUserInCourse = async (courseid: number | string, userid: number | string) => {
|
||||
try {
|
||||
const { data: enrollmentResponse } = await axios.get(
|
||||
`${process.env.NEXT_PUBLIC_MOODLE_URL}/webservice/rest/server.php`,
|
||||
{
|
||||
auth: {
|
||||
username: "moodleuser",
|
||||
password: "Xo1SXaLYBa7Yb6WW",
|
||||
},
|
||||
params: {
|
||||
wstoken: process.env.MOODLE_API_TOKEN,
|
||||
wsfunction: "enrol_manual_enrol_users",
|
||||
moodlewsrestformat: "json",
|
||||
enrolments: [
|
||||
{
|
||||
roleid: 5,
|
||||
userid: typeof userid === "string" ? parseInt(userid) : userid,
|
||||
courseid: typeof courseid === "string" ? parseInt(courseid) : courseid,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
if (enrollmentResponse !== null) console.error(enrollmentResponse);
|
||||
return enrollmentResponse;
|
||||
);
|
||||
return enrollmentResponse;
|
||||
} catch (error) {
|
||||
return new Error("Failed to enroll user in course");
|
||||
}
|
||||
};
|
||||
|
||||
export const getMoodleUserById = async (id: string) => {
|
||||
const { data: user } = await axios.get(
|
||||
`${process.env.NEXT_PUBLIC_MOODLE_URL}/webservice/rest/server.php`,
|
||||
{
|
||||
auth: {
|
||||
username: "moodleuser",
|
||||
password: "Xo1SXaLYBa7Yb6WW",
|
||||
},
|
||||
params: {
|
||||
wstoken: process.env.MOODLE_TOKEN,
|
||||
wstoken: process.env.MOODLE_API_TOKEN,
|
||||
wsfunction: "core_user_get_users_by_field",
|
||||
moodlewsrestformat: "json",
|
||||
field: "idnumber",
|
||||
@@ -42,6 +49,7 @@ export const getMoodleUserById = async (id: string) => {
|
||||
},
|
||||
},
|
||||
);
|
||||
console.log("Moodle User", user);
|
||||
const u = user[0];
|
||||
return (
|
||||
(u as {
|
||||
|
||||
Reference in New Issue
Block a user