Skip to content

Commit 51afe92

Browse files
committed
pulsante cancellazione degree e curriculum
1 parent 6244689 commit 51afe92

8 files changed

Lines changed: 151 additions & 50 deletions

File tree

api/controllers/CurriculaController.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ const CurriculaController = {
6868

6969
post: async req => {
7070
return await ModelController.post(Curriculum, req.body)
71+
},
72+
73+
delete: async req => {
74+
const { id } = req.params;
75+
return await ModelController.delete(Curriculum, id);
7176
}
7277
}
7378

api/controllers/DegreesController.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ const DegreesController = {
6060
const { id } = req.params;
6161
const data = req.body
6262
return await ModelController.patch(Degree, id, req.body)
63+
},
64+
65+
delete: async req => {
66+
const { id } = req.params;
67+
return await ModelController.delete(Degree, id)
6368
}
6469
}
6570

api/router.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,13 @@ router.get('/degrees', require_user, response_envelope(Degrees.index))
148148
router.get('/degrees/:id', require_user, response_envelope(Degrees.view))
149149
router.patch('/degrees/:id', require_admin, response_envelope(Degrees.patch))
150150
router.post('/degrees', require_admin, response_envelope(Degrees.post))
151+
router.delete('/degrees/:id', require_admin, response_envelope(Degrees.delete))
151152

152153
router.get('/curricula', require_user, response_envelope(Curricula.index))
153154
router.get('/curricula/:id', require_user, response_envelope(Curricula.view))
155+
router.patch('/curricula/:id', require_admin, response_envelope(Curricula.patch))
156+
router.post('/curricula', require_admin, response_envelope(Curricula.post))
157+
router.delete('/curricula/:id', require_admin, response_envelope(Curricula.delete))
154158

155159
router.get('/form_templates/', require_admin, response_envelope(FormTemplates.index))
156160
router.get('/form_templates/:id', require_admin, response_envelope(FormTemplates.view))

frontend/src/components/Flash.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import React from "react";
22
import Card from "./Card";
33
import FA from "react-fontawesome";
44

5+
export interface FlashMessage {
6+
type: 'error' | 'success' | 'info';
7+
message: string;
8+
}
9+
510
export function FlashCard({className, message, onClick}:{
611
className: string,
712
message: string,
@@ -17,7 +22,10 @@ export function FlashCard({className, message, onClick}:{
1722
</Card>;
1823
}
1924

20-
export default function Flash({ messages, onClick }) {
25+
export default function Flash({ messages, onClick }:{
26+
messages: FlashMessage[],
27+
onClick?: () => void
28+
}) {
2129
function classForType(type) {
2230
switch(type) {
2331
case 'error': return "danger";

frontend/src/modules/engine.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,18 @@ export type CurriculumGet = {
339339
}[]
340340
}
341341

342+
export function usePatchCurriculum(id:string) {
343+
return usePatch<CurriculumGet>(['curricula'], id)
344+
}
345+
346+
export function usePostCurriculum() {
347+
return usePost<CurriculumGet>(['curricula'])
348+
}
349+
350+
export function useDeleteCurriculum(id:string) {
351+
return useDelete(['curricula'], id)
352+
}
353+
342354
export type CurriculumExamGet = {
343355
__t: 'CompulsoryExam',
344356
exam_id: string,

frontend/src/pages/CurriculumPage.tsx

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,87 @@
1-
import React from 'react'
2-
import { useParams } from "react-router-dom"
1+
import React, { useState } from 'react'
2+
import { Link, useParams, useNavigate } from "react-router-dom"
33

4-
import { useGetExam, useGetCurriculum } from '../modules/engine'
4+
import { useGetExam, useGetCurriculum, useDeleteCurriculum } from '../modules/engine'
55
import Card from '../components/Card'
66
import LoadingMessage from '../components/LoadingMessage'
77
import { displayAcademicYears } from '../modules/utils'
8+
import { useEngine } from '../modules/engine'
9+
10+
export default function CurriculumPage() {
11+
const { id } = useParams()
12+
const query = useGetCurriculum(id || '')
13+
const deleter = useDeleteCurriculum(id || '')
14+
const engine = useEngine()
15+
const navigate = useNavigate()
16+
17+
const curriculum = query.data
18+
19+
if (query.isError) return <div>errore caricamento curriculum</div>
20+
if (query.isLoading || !curriculum) return <LoadingMessage>caricamento curriculum...</LoadingMessage>
21+
22+
const degree = curriculum.degree
23+
24+
return <>
25+
<h1>{ curriculum.name }</h1>
26+
<Card>
27+
<div className="d-flex mb-2">
28+
<Link to="/degrees">
29+
<button type="button" className="btn btn-sm mr-2 btn-primary">
30+
<i className="fas fa-arrow-left mr-2"></i>
31+
Tutti i curricula
32+
</button>
33+
</Link>
34+
<a href={`/curricula/edit/${id}`}>
35+
<button type="button" className="btn btn-sm mr-2 btn-primary">
36+
Modifica
37+
</button>
38+
</a>
39+
<a href="#" onClick={ () => deleteCurriculum() }>
40+
<button type="button" className="btn btn-sm mr-2 btn-danger">Elimina</button>
41+
</a>
42+
43+
<div className="flex-fill"></div>
44+
45+
<div className="btn btn-sm btn-primary mr-2" >
46+
<i className="fas fa-download mr-2"></i> Esporta in CSV
47+
</div>
48+
</div>
49+
</Card>
50+
<h3>{ degree?.name } { degree.academic_year ? displayAcademicYears(degree.academic_year) : '????-????'}</h3>
51+
{ curriculum.years.map((year_section, year_count) =>
52+
<Card key={`year-${year_count}`} title={`${ordinal(year_count+1)} anno`}>
53+
Crediti: { `${year_section.credits}` } <br />
54+
<table>
55+
<tbody>
56+
{ year_section.exams.map((entry,i) => <ExamEntry key={i} entry={entry} />)}
57+
</tbody>
58+
</table>
59+
</Card>
60+
)}
61+
</>
62+
63+
function deleteCurriculum() {
64+
if (!confirm("Sei sicuro di voler cancellare questo curriculum?"))
65+
return false;
66+
67+
debugger
68+
69+
deleter.mutate(id, {
70+
onSuccess: () => {
71+
console.log("Curriculum cancellato con successo")
72+
engine.flashSuccess("Curriculum cancellato con successo")
73+
navigate('/curricula')
74+
},
75+
onError: (err) => {
76+
console.error("Errore durante la cancellazione del curriculum", err)
77+
engine.flashError(`${err}`)
78+
}
79+
})
80+
}
81+
82+
83+
}
884

9-
const degree_path = "/degrees/"
1085

1186
function CompulsoryExam({ exam_id }) {
1287
const query = useGetExam(exam_id);
@@ -45,34 +120,6 @@ function ExamEntry({ entry }) {
45120
else return <tr><td>???</td></tr>
46121
}
47122

48-
export default function CurriculumPage() {
49-
const { id } = useParams()
50-
const query = useGetCurriculum(id || '')
51-
const curriculum = query.data
52-
53-
if (query.isError) return <div>errore caricamento curriculum</div>
54-
if (!curriculum) return <LoadingMessage>caricamento curriculum...</LoadingMessage>
55-
56-
const degree = curriculum.degree
57-
58-
console.log(`curriculum: ${JSON.stringify(curriculum)}`)
59-
60-
return <>
61-
<h1>{ curriculum.name }</h1>
62-
<h3>{ degree?.name } { degree.academic_year ? displayAcademicYears(degree.academic_year) : '????-????'}</h3>
63-
{ curriculum.years.map((year_section, year_count) =>
64-
<Card key={`year-${year_count}`} title={`${ordinal(year_count+1)} anno`}>
65-
Crediti: { `${year_section.credits}` } <br />
66-
<table>
67-
<tbody>
68-
{ year_section.exams.map((entry,i) => <ExamEntry key={i} entry={entry} />)}
69-
</tbody>
70-
</table>
71-
</Card>
72-
)}
73-
</>
74-
}
75-
76123
function ordinal(n) {
77124
const ordinals = [ "zero",
78125
"primo", "secondo", "terzo", "quarto", "quinto",

frontend/src/pages/DegreePage.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Form } from "react-bootstrap"
44
import Select from "react-select"
55
import Button from 'react-bootstrap/Button'
66

7-
import { useEngine, useGetDegree, useIndexExam, usePostDegree, usePatchDegree, ExamGet } from '../modules/engine'
7+
import { useEngine, useGetDegree, useIndexExam, usePostDegree, usePatchDegree, useDeleteDegree, ExamGet } from '../modules/engine'
88
import Card from '../components/Card'
99
import Group from '../components/Group'
1010
import LoadingMessage from '../components/LoadingMessage'
@@ -13,6 +13,9 @@ import HTMLEditor from '../components/HTMLEditor'
1313
export default function DegreePage() {
1414
const { id } = useParams();
1515
const query = useGetDegree(id || '')
16+
const deleter = useDeleteDegree(id || '')
17+
const engine = useEngine()
18+
const navigate = useNavigate()
1619

1720
if (query.isLoading) return <LoadingMessage>caricamento corso di studi...</LoadingMessage>
1821
if (query.data === undefined) return <div>errore caricamento corso di studi</div>
@@ -34,7 +37,7 @@ export default function DegreePage() {
3437
Modifica
3538
</button>
3639
</a>
37-
<a href="#" onClick={ () => confirm('Sei sicuro di voler cancellare questo esame?')}>
40+
<a href="#" onClick={() => deleteDegree()}>
3841
<button type="button" className="btn btn-sm mr-2 btn-danger">Elimina</button>
3942
</a>
4043

@@ -135,6 +138,22 @@ export default function DegreePage() {
135138
</table>
136139
</Card>
137140
</>
141+
142+
function deleteDegree() {
143+
if (!confirm("Sei sicuro di voler cancellare questo corso di Laurea?"))
144+
return false;
145+
146+
deleter.mutate(id, {
147+
onSuccess: () => {
148+
engine.flashSuccess("Corso di Laurea cancellato con successo")
149+
navigate('/degrees')
150+
},
151+
onError: (err) => {
152+
console.error("Errore durante la cancellazione del corso di Laurea", err)
153+
engine.flashError(`${err}`)
154+
}
155+
})
156+
}
138157
}
139158

140159
function ExamGroup({ name, exam_ids }) {

frontend/src/pages/ExamPage.tsx

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,21 +123,6 @@ export default function ExamPage() {
123123
const navigate = useNavigate()
124124
const deleter = useDeleteExam(id || '')
125125

126-
function deleteExam() {
127-
if (!confirm("Sei sicuro di voler cancellare questo esame?"))
128-
return false;
129-
130-
deleter.mutate(id, {
131-
onSuccess: () => {
132-
engine.flashSuccess("Esame cancellato con successo")
133-
navigate('/exams')
134-
},
135-
onError: (err) => {
136-
engine.flashError(`${err}`)
137-
}
138-
})
139-
}
140-
141126
if (query.isError) return <div>Errore: {query.error.message}</div>
142127
if (query.data === undefined) return <LoadingMessage>caricamento esame...</LoadingMessage>
143128

@@ -236,6 +221,22 @@ export default function ExamPage() {
236221
</table>
237222
</Card>
238223
</>
224+
225+
function deleteExam() {
226+
if (!confirm("Sei sicuro di voler cancellare questo esame?"))
227+
return false;
228+
229+
deleter.mutate(id, {
230+
onSuccess: () => {
231+
engine.flashSuccess("Esame cancellato con successo")
232+
navigate('/exams')
233+
},
234+
onError: (err) => {
235+
engine.flashError(`${err}`)
236+
}
237+
})
238+
}
239+
239240
}
240241

241242

0 commit comments

Comments
 (0)