From 017312413212342ee96fac55563bba9a9b670345 Mon Sep 17 00:00:00 2001
From: Afonso Santos <113265283+Afonso-santos@users.noreply.github.com>
Date: Thu, 6 Jul 2023 16:38:04 +0100
Subject: [PATCH] [App] Add presences list (#186)
* Starting the presences list
* visual aspect done
* presences_list call api
* Presences list done
* correct some details
* correct some erros
* request changes done
* request changes done
* request changes done
* request changes done
* some details
---
apps/app/components/AppMenu/index.tsx | 1 +
apps/app/components/LectureForm/index.js | 3 +-
.../pages/admin/lectures/presences/index.tsx | 309 ++++++++++++++++++
packages/bokkenjs/lib/lectures/lectures.ts | 1 +
4 files changed, 312 insertions(+), 2 deletions(-)
create mode 100644 apps/app/pages/admin/lectures/presences/index.tsx
diff --git a/apps/app/components/AppMenu/index.tsx b/apps/app/components/AppMenu/index.tsx
index 26cbd9c8..5ae11d8a 100644
--- a/apps/app/components/AppMenu/index.tsx
+++ b/apps/app/components/AppMenu/index.tsx
@@ -143,6 +143,7 @@ function AppMenu({ hidePrimaryMenu, collapsed }: any) {
} title="Sessões">
- Listar sessões
- Criar sessão
+ - Presenças
>
)}
diff --git a/apps/app/components/LectureForm/index.js b/apps/app/components/LectureForm/index.js
index 9be1bb0d..248bc5ca 100644
--- a/apps/app/components/LectureForm/index.js
+++ b/apps/app/components/LectureForm/index.js
@@ -3,6 +3,7 @@ import Link from "next/link";
import { useRouter } from "next/router";
import { Button, Col, Form, Row, Select, Space, Typography } from "antd";
import { CloseOutlined, SaveOutlined } from "@ant-design/icons";
+
import {
getNinjaEvents,
listEvents,
@@ -33,7 +34,6 @@ export default function LectureForm({ id }) {
setEvents(response.data);
});
}, []);
-
useEffect(() => {
if (id !== "new") {
listEvents().then((response) => {
@@ -137,7 +137,6 @@ export default function LectureForm({ id }) {
});
}
};
-
return (
<>
diff --git a/apps/app/pages/admin/lectures/presences/index.tsx b/apps/app/pages/admin/lectures/presences/index.tsx
new file mode 100644
index 00000000..7a399dc8
--- /dev/null
+++ b/apps/app/pages/admin/lectures/presences/index.tsx
@@ -0,0 +1,309 @@
+import { useEffect, useState } from "react";
+import { useRouter } from "next/router";
+import { Button, Row, Select, Space, Table, Typography } from "antd";
+import { CloseOutlined, EditOutlined, SaveOutlined } from "@ant-design/icons";
+
+import {
+ getNinjaEvents,
+ listEvents,
+ listLectures,
+ listMentors,
+} from "bokkenjs";
+import * as api from "bokkenjs";
+import { notifyError, notifyInfo } from "~/components/Notification";
+import AppLayout from "~/layouts/AppLayout";
+import { set } from "lodash-es";
+const { Title } = Typography;
+
+type Event = {
+ id: string;
+ title: string;
+};
+
+type Lecture = {
+ id: string;
+ event: Event;
+ attendance: string;
+};
+
+export default function Presences() {
+ const [editButtonVisible, setEditButtonVisible] = useState(true);
+ const [saveButtonVisible, setSaveButtonVisible] = useState(false);
+ const [cancelButtonVisible, setCancelButtonVisible] = useState(false);
+ const [data, setData] = useState([]);
+ const [originalData, setOriginalData] = useState([]);
+ const [events, setEvents] = useState([]);
+ const [selectedEvent, setSelectedEvent] = useState("");
+ const [lectures, setLectures] = useState([]);
+ const [selectedLectures, setSelectedLectures] = useState([]);
+ const [locations, setLocations] = useState([]);
+ const router = useRouter();
+ const onFinish = (values: any, lectureId: string) => {
+ api
+ .updateLecture(lectureId, values)
+ .then(() => {
+ notifyInfo("Os dados da sessão foram atualizados com sucesso", "");
+
+ // Update the corresponding lecture in lectures state with the new data
+ const updatedLectures = lectures.map((lecture) => {
+ if (lecture.id === lectureId) {
+ return {
+ ...lecture,
+ attendance: values.attendance,
+ };
+ }
+ return lecture;
+ });
+
+ setLectures(updatedLectures);
+ })
+ .catch((error) => {
+ notifyError(
+ "Ocorreu um erro",
+ "Não foi possível atualizar os dados da sessão"
+ );
+ });
+ };
+
+ useEffect(() => {
+ api
+ .listEvents()
+ .then((response: any) => setEvents(response.data))
+ .catch((error) => {
+ notifyError(
+ "Ocorreu um erro",
+ "Não foi possível atualizar os dados da sessão"
+ );
+ });
+ }, []);
+
+ useEffect(() => {
+ api
+ .listLectures()
+ .then((response: any) => setLectures(response.data))
+
+ .catch((error) => {
+ notifyError(
+ "Ocorreu um erro",
+ "Não foi possível atualizar os dados da sessão"
+ );
+ });
+
+ selectedLectures.forEach((lecture) => {
+ if (lecture.attendance == null) {
+ lecture.attendance = "both_absent";
+ }
+ data.push({
+ presences: `${lecture.attendance}`,
+ key: lecture.id,
+ });
+ });
+ }, []);
+
+ useEffect(() => {
+ api
+ .getLocations()
+ .then((response: any) => setLocations(response.data))
+ .catch((error) => {
+ notifyError(
+ "Ocorreu um erro",
+ "Não foi possível atualizar os dados da sessão"
+ );
+ });
+ }, []);
+
+ useEffect(() => {
+ if (selectedEvent !== "") {
+ setSelectedLectures(
+ lectures.filter((lecture) => lecture.event.id === selectedEvent)
+ );
+ }
+ }, [selectedEvent, lectures]);
+
+ useEffect(() => {
+ generateData();
+ }, [selectedLectures]);
+
+ const generateData = () => {
+ const data: any[] = [];
+
+ selectedLectures.map((lecture: any) => {
+ if (lecture.attendance == null) {
+ lecture.attendance = "both_absent";
+ }
+ data.push({
+ ninja: `${lecture.ninja.first_name} ${lecture.ninja.last_name}`,
+ mentor: `${lecture.mentor.first_name} ${lecture.mentor.last_name}`,
+ presences: `${lecture.attendance}`,
+ key: lecture.id,
+ });
+ });
+
+ setData(data);
+ };
+
+ const handleEditButtonClick = () => {
+ setEditButtonVisible(false);
+ setSaveButtonVisible(true);
+ setCancelButtonVisible(true);
+ };
+
+ const handleSaveButtonClick = () => {
+ const hasChanges = JSON.stringify(data) !== JSON.stringify(originalData);
+
+ if (hasChanges) {
+ data.forEach((item) => {
+ const lectureId = item.key;
+ const values = { attendance: item.presences };
+
+ onFinish(values, lectureId);
+ });
+ }
+
+ setOriginalData([...data]);
+ setSaveButtonVisible(false);
+ setCancelButtonVisible(false);
+ setEditButtonVisible(true);
+ };
+
+ const handleCancelButtonClick = () => {
+ setSaveButtonVisible(false);
+ setCancelButtonVisible(false);
+ setEditButtonVisible(true);
+ };
+
+ const handleComboBoxChange = (key: string) => (value: string) => {
+ const updatedData = [...data];
+ const dataIndex = updatedData.findIndex((item) => item.key === key);
+ if (dataIndex > -1) {
+ updatedData[dataIndex].presences = value;
+ setData(updatedData);
+ }
+ };
+
+ const getPresencesLabel = (value: string) => {
+ switch (value) {
+ case "both_absent":
+ return "Nenhum";
+ case "ninja_absent":
+ return "Ninja Faltou";
+ case "mentor_absent":
+ return "Mentor Faltou";
+ case "both_present":
+ return "Presentes";
+ default:
+ return "";
+ }
+ };
+ const columns = [
+ {
+ title: "Ninja",
+ dataIndex: "ninja",
+ width: "33%",
+ },
+ {
+ title: "Mentor",
+ dataIndex: "mentor",
+ width: "33%",
+ },
+ {
+ title: "Presenças",
+ dataIndex: "presences",
+ width: "33%",
+ render: (_: any, record: any) => {
+ const label = getPresencesLabel(record.presences);
+ if (editButtonVisible) {
+ return {label};
+ } else {
+ return (
+
+ );
+ }
+ },
+ },
+ ];
+
+ return (
+ <>
+
+
+ Presenças
+
+ {editButtonVisible && (
+ }
+ onClick={handleEditButtonClick}
+ disabled={!editButtonVisible}
+ />
+ )}
+ {saveButtonVisible && (
+ }
+ onClick={handleSaveButtonClick}
+ disabled={!saveButtonVisible}
+ />
+ )}
+ {cancelButtonVisible && (
+ }
+ onClick={handleCancelButtonClick}
+ disabled={!cancelButtonVisible}
+ />
+ )}
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/packages/bokkenjs/lib/lectures/lectures.ts b/packages/bokkenjs/lib/lectures/lectures.ts
index 0752475a..190f6317 100644
--- a/packages/bokkenjs/lib/lectures/lectures.ts
+++ b/packages/bokkenjs/lib/lectures/lectures.ts
@@ -13,6 +13,7 @@ export async function updateLecture(lecture_id: string, data: any) {
lecture: {
summary: data.summary,
notes: data.notes,
+ attendance: data.attendance,
},
},
{