From 608c3801192f10f5fa9496273642eb4424298160 Mon Sep 17 00:00:00 2001 From: hei98 Date: Mon, 12 Feb 2024 20:12:46 +0100 Subject: [PATCH 1/5] Edit interview notes --- .../InterviewNotesAdminPage.tsx | 67 +++++++++++++++---- frontend/src/i18n/constants.ts | 1 + frontend/src/i18n/translations.ts | 2 + frontend/src/routes/frontend.ts | 2 +- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx b/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx index 6b8ed1344..6b452bfa9 100644 --- a/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx +++ b/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx @@ -1,35 +1,78 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { useParams } from 'react-router-dom'; +import { toast } from 'react-toastify'; import { Button } from '~/Components'; import { TextAreaField } from '~/Components/TextAreaField/TextAreaField'; +import { getRecruitmentAdmissionsForGang, putRecruitmentAdmissionInterview } from '~/api'; +import { InterviewDto, RecruitmentAdmissionDto } from '~/dto'; import { KEY } from '~/i18n/constants'; import { AdminPageLayout } from '../AdminPageLayout/AdminPageLayout'; import styles from './InterviewNotesAdminPage.module.scss'; export function InterviewNotesPage() { - //TODO: interview notes from backend + const recruitmentId = useParams().recruitmentId; + const gangId = useParams().gangId; + const positionId = useParams().positionId; + const interviewId = useParams().interviewId; const [editingMode, setEditingMode] = useState(false); - const [text, setText] = useState('Notater fra intervjuet her...'); //TODO: place the text from the backend here. - const posId = 1; //TODO: get the posId from the backend. + const [recruitmentAdmission, setRecruitmentAdmission] = useState([]); + const [interview, setInterview] = useState(null); + const [disabled, setdisabled] = useState(true); + const [nameUser, setNameUser] = useState(''); const { t } = useTranslation(); - function handleEditSave() { - if (editingMode) { - //TODO: save the text in the textbox and send it to the backend + useEffect(() => { + if (positionId && recruitmentId && gangId && interviewId) { + getRecruitmentAdmissionsForGang(gangId, recruitmentId).then((response) => { + const recruitmentAdmissions = response.data; + const admission = recruitmentAdmissions.filter( + (admission) => + admission.recruitment_position && + admission.recruitment_position.toString() === positionId && + admission.interview.id.toString() === interviewId && + admission.interview.interview_time !== null, + ); + if (admission.length !== 0) { + setdisabled(false); + setRecruitmentAdmission(admission); + setInterview(admission[0].interview); + setNameUser( + admission[0].user.first_name ? admission[0].user.first_name + ' ' + admission[0].user.last_name : '', + ); + } + }); + } + }, [recruitmentId, positionId, gangId, interviewId, t]); + + async function handleEditSave() { + if (editingMode && interview) { + try { + await putRecruitmentAdmissionInterview(interview.id.toString(), interview); + toast.success(t(KEY.common_save_successful)); + } catch (error) { + toast.error(t(KEY.common_something_went_wrong)); + } } setEditingMode(!editingMode); } - //TODO: make handleSave function to save the text in the textbox and send it to the backend - return (
- -
diff --git a/frontend/src/i18n/constants.ts b/frontend/src/i18n/constants.ts index 0da06c03d..ffcbfedff 100644 --- a/frontend/src/i18n/constants.ts +++ b/frontend/src/i18n/constants.ts @@ -114,6 +114,7 @@ export const KEY = { common_long_description: 'common_long_description', common_short_description: 'common_short_description', common_back_to_samfundet: 'common_back_to_samfundet', + common_save_successful: 'common_save_successful', common_delete_successful: 'common_delete_successful', common_update_successful: 'common_update_successful', common_creation_successful: 'common_creation_successful', diff --git a/frontend/src/i18n/translations.ts b/frontend/src/i18n/translations.ts index b3070c7af..b30607d87 100644 --- a/frontend/src/i18n/translations.ts +++ b/frontend/src/i18n/translations.ts @@ -100,6 +100,7 @@ export const nb: Record = { [KEY.common_long_description]: 'Lang beskrivelse', [KEY.common_short_description]: 'Kort beskrivelse', [KEY.common_back_to_samfundet]: 'Tilbake til samfundet.no', + [KEY.common_save_successful]: 'Lagring var vellykket', [KEY.common_delete_successful]: 'Slettingen var vellykket', [KEY.common_update_successful]: 'Oppdateringen var vellykket', [KEY.common_see_in_django_admin]: 'Se i django admin-panel', @@ -380,6 +381,7 @@ export const en: Record = { [KEY.common_long_description]: 'Long description', [KEY.common_short_description]: 'Short description', [KEY.common_back_to_samfundet]: 'Back to samfundet.no', + [KEY.common_save_successful]: 'Saving was successful', [KEY.common_delete_successful]: 'Deletion was successful', [KEY.common_update_successful]: 'The update was successful', [KEY.common_see_in_django_admin]: 'See in django admin-panel', diff --git a/frontend/src/routes/frontend.ts b/frontend/src/routes/frontend.ts index fd1eb1066..7ccab33bc 100644 --- a/frontend/src/routes/frontend.ts +++ b/frontend/src/routes/frontend.ts @@ -70,7 +70,7 @@ export const ROUTES_FRONTEND = { admin_recruitment_gang_position_applicants_overview: '/control-panel/recruitment/:recruitmentId/gang/:gangId/position/:positionId', admin_recruitment_gang_position_applicants_interview_notes: - '/control-panel/recruitment/:recruitmentId/gang/:gangId/position/:positionId/notesId', //fix when backend is done + '/control-panel/recruitment/:recruitmentId/gang/:gangId/position/:positionId/interview-notes/:interviewId', admin_sulten_menu: '/control-panel/lyche/menu', // ==================== // // Development // From 2547a37ea52861e5cacd0a3ae118b272efc49d52 Mon Sep 17 00:00:00 2001 From: hei98 Date: Mon, 12 Feb 2024 20:14:04 +0100 Subject: [PATCH 2/5] Add putRecruitmentAdmissionInterview to edit interview in backend --- backend/samfundet/serializers.py | 1 + frontend/src/api.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/backend/samfundet/serializers.py b/backend/samfundet/serializers.py index fbb10cac2..3b53535d9 100644 --- a/backend/samfundet/serializers.py +++ b/backend/samfundet/serializers.py @@ -691,6 +691,7 @@ def update(self, instance: RecruitmentAdmission, validated_data: dict) -> Recrui interview_instance = instance.interview interview_instance.interview_location = interview_data.get('interview_location', interview_instance.interview_location) interview_instance.interview_time = interview_data.get('interview_time', interview_instance.interview_time) + interview_instance.notes = interview_data.get('notes', interview_instance.notes) interview_instance.save() # Update other fields of RecruitmentAdmission instance diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 50b3aa418..2a5ad1933 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -11,6 +11,7 @@ import { ImageDto, ImagePostDto, InformationPageDto, + InterviewDto, KeyValueDto, MenuDto, MenuItemDto, @@ -705,3 +706,17 @@ export async function putRecruitmentAdmission(admission: Partial, +): Promise { + const url = + BACKEND_DOMAIN + + reverse({ + pattern: ROUTES.backend.samfundet__interview_detail, + urlParams: { pk: interviewId }, + }); + const response = await axios.put(url, interview, { withCredentials: true }); + return response; +} From 0e5fb6caa51e1964ff4571e36d27ec12079aa7af Mon Sep 17 00:00:00 2001 From: hei98 Date: Mon, 19 Feb 2024 00:08:24 +0100 Subject: [PATCH 3/5] Add help functions and util functions --- .../InterviewNotesAdminPage.tsx | 30 ++++++++----------- .../InterviewNotesAdminPage/utils.ts | 20 +++++++++++++ 2 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 frontend/src/PagesAdmin/InterviewNotesAdminPage/utils.ts diff --git a/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx b/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx index 6b452bfa9..9619475ed 100644 --- a/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx +++ b/frontend/src/PagesAdmin/InterviewNotesAdminPage/InterviewNotesAdminPage.tsx @@ -9,6 +9,7 @@ import { InterviewDto, RecruitmentAdmissionDto } from '~/dto'; import { KEY } from '~/i18n/constants'; import { AdminPageLayout } from '../AdminPageLayout/AdminPageLayout'; import styles from './InterviewNotesAdminPage.module.scss'; +import { filterRecruitmentAdmission, getNameUser } from './utils'; export function InterviewNotesPage() { const recruitmentId = useParams().recruitmentId; @@ -25,30 +26,21 @@ export function InterviewNotesPage() { useEffect(() => { if (positionId && recruitmentId && gangId && interviewId) { getRecruitmentAdmissionsForGang(gangId, recruitmentId).then((response) => { - const recruitmentAdmissions = response.data; - const admission = recruitmentAdmissions.filter( - (admission) => - admission.recruitment_position && - admission.recruitment_position.toString() === positionId && - admission.interview.id.toString() === interviewId && - admission.interview.interview_time !== null, - ); + const admission = filterRecruitmentAdmission(response.data, positionId, interviewId); if (admission.length !== 0) { setdisabled(false); setRecruitmentAdmission(admission); setInterview(admission[0].interview); - setNameUser( - admission[0].user.first_name ? admission[0].user.first_name + ' ' + admission[0].user.last_name : '', - ); + setNameUser(getNameUser(admission[0])); } }); } - }, [recruitmentId, positionId, gangId, interviewId, t]); + }, [recruitmentId, positionId, gangId, interviewId]); async function handleEditSave() { if (editingMode && interview) { try { - await putRecruitmentAdmissionInterview(interview.id.toString(), interview); + await putRecruitmentAdmissionInterview(interview.id, interview); toast.success(t(KEY.common_save_successful)); } catch (error) { toast.error(t(KEY.common_something_went_wrong)); @@ -57,6 +49,12 @@ export function InterviewNotesPage() { setEditingMode(!editingMode); } + function handleUpdateNotes(value: string) { + const updatedNotes = value; + const updatedInterview: InterviewDto = { ...recruitmentAdmission[0].interview, notes: updatedNotes }; + setInterview(updatedInterview); + } + return (
@@ -65,11 +63,7 @@ export function InterviewNotesPage() { { - const updatedNotes = value; - const updatedInterview: InterviewDto = { ...recruitmentAdmission[0].interview, notes: updatedNotes }; - setInterview(updatedInterview); - }} + onChange={handleUpdateNotes} disabled={!editingMode} >