Skip to content

Commit

Permalink
refactoring: adding typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
paolini committed Oct 20, 2023
1 parent 5d556c2 commit 42ccea6
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 65 deletions.
2 changes: 2 additions & 0 deletions api/models/Exam.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ const Exam = mongoose.model('Exam', {
},
})



module.exports = Exam;
2 changes: 1 addition & 1 deletion frontend/src/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function Card({
title?: string,
customHeader?: JSX.Element,
onClick?: () => void,
children?: JSX.Element | JSX.Element[]
children?: React.ReactNode,
}) {
let cardClass = classWithDefault(className, 'shadow my-2');
// let headerClass = titleBg || 'bg-primary';
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ function LocalLogin({}) {
<div>Credenziali locali</div>
</div>
</div>
<div id="local-login" className="collapse">
<div id="local-login" className="collapse_">
{/* collapse not working anymore !?!*/}
<div className="card-body">
<div className="input form-group">
<label htmlFor="username">Username</label>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function NavBar() {
</NavItem>

<NavItem>
<NavLink className="nav-link" href="/proposals/edit/">
<NavLink className="nav-link" href="/proposals/edit/__new__">
<svg className="svg-inline--fa fa-plus-square fa-w-14 mr-1" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="plus-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><path fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"></path></svg>
<span>Nuovo piano di studio</span>
</NavLink>
Expand Down
168 changes: 164 additions & 4 deletions frontend/src/modules/engine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ export function useCreateEngine(): Engine {
}
}

export function useGet(path:string, id:string|undefined) {
return useQuery<any,any>({
export function useGet<T>(path:string, id:string|undefined) {
return useQuery<T,any>({
queryKey: [path, id],
queryFn: async () => {
const res = await axios.get(`${api_root}${path}${id}`)
Expand All @@ -180,8 +180,8 @@ export function useGet(path:string, id:string|undefined) {
})
}

export function useIndex(path:string, query={}) {
return useQuery({
export function useIndex<T>(path:string, query={}) {
return useQuery<{items: T[]}>({
queryKey: [path, query],
queryFn: async () => {
const res = await axios.get(`${api_root}${path}`, { params: query })
Expand Down Expand Up @@ -228,3 +228,163 @@ export function usePatch(path:string, id:string) {
})
}

export type ExamGet = {
_id: string,
name: string,
code: string,
sector: string,
credits: number,
tags: string[],
notes: string,
}

export function useGetExam(id:string|undefined) {
return useGet<ExamGet>('exams/', id)
}

export function useIndexExam(query={}) {
return useIndex<ExamGet>('exams/', query)
}

export type DegreeGet = {
_id: string
name: string,
academic_year: number,
years: number,
groups: {
[key: string]: string[],
},
enabled: boolean,
enable_sharing: boolean,
default_group: string,
approval_confirmation: boolean,
rejection_confirmation: boolean,
submission_confirmation: boolean,
approval_message: string,
rejection_message: string,
submission_message: string,
free_choice_message: string,
}

export function useGetDegree(id:string|undefined) {
return useGet<DegreeGet>('degrees/', id)
}

export function useIndexDegree(query={}) {
return useIndex<DegreeGet>('degrees/', query)
}

export function useDeleteDegree(id:string) {
return useDelete('degrees/', id)
}

export type CurriculumGet = {
_id: string,
name: string,
notes: string,
degree_id: string,
degree: {
enabled: boolean,
name: string,
academic_year: number,
}
years: {
credits: number,
exams: CurriculumExamGet[]
}[]
}

export type CurriculumExamGet = {
_id: string,
__t: 'CompulsoryExam',
exam_id: string,
}|{
_id: string,
__t: 'CompulsoryGroup',
group: string,
}|{
_id: string,
__t: 'FreeChoiceExam',
}|{
_id: string,
__t: 'FreeChoiceGroup',
group: string,
}

export function useGetCurriculum(id:string|undefined) {
return useGet<CurriculumGet>('curricula/', id)
}

export function useIndexCurriculum(query={}) {
return useIndex<CurriculumGet>('curricula/', query)
}

export type ProposalGet = {
_id: string,
degree_id: string,
degree_academic_year: number,
degree_name: string,
curriculum_id: string,
curriculum_name: string,
user_id: string,
user_last_name: string,
user_first_name: string,
user_name: string,
user_id_number: string,
user_email: string,
user_username: string,
state: 'draft'|'submitted'|'approved'|'rejected',
date_modified: string,
date_submitted: string,
date_managed: string,
exams: ProposalExamGet[][],
attachments: ProposalAttachmentGet[],
}

export type ProposalExamGet = {
__t: "CompulsoryExam",
exam_id: string,
exam_name: string,
exam_code: string,
exam_credits: number,
}|{
__t: "CompulsoryGroup",
group: string,
exam_id: string,
exam_name: string,
exam_code: string,
exam_credits: number,
}|{
__t: "FreeChoiceGroup",
group: string,
exam_id: string,
exam_name: string,
exam_code: string,
exam_credits: number,
}|{
__t: "FreeChoiceExam",
exam_id: string,
exam_name: string,
exam_code: string,
exam_credits: number,
}|{
__t: "ExternalExam",
exam_name: string,
exam_credits: number,
}

export interface ProposalAttachmentGet {
}

export function useGetProposal(id:string|undefined) {
return useGet<ProposalGet>('proposals/', id)
}

export function useIndexProposal(query={}) {
return useIndex<ProposalGet>('proposals/', query)
}

export function useDeleteProposal(id:string) {
return useDelete('proposals/', id)
}

29 changes: 15 additions & 14 deletions frontend/src/pages/CurriculumPage.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import React from 'react'
import { useParams } from "react-router-dom"

import { useGet } from '../modules/engine'
import { useGetExam, useGetCurriculum } from '../modules/engine'
import Card from '../components/Card'
import LoadingMessage from '../components/LoadingMessage'
import { displayAcademicYears } from '../modules/utils'

const path = "/curricula/"
const exam_path = "/exams/"
const degree_path = "/degrees/"

function CompulsoryExam({ exam_id }) {
const query = useGet(exam_path, exam_id);
const query = useGetExam(exam_id);

if (query.isLoading) return <tr>
if (query.isError) return <tr>
<th>esame obbligatorio</th>
<td>...</td>
<td>???</td>
</tr>

const exam = query.data;

if (query.isError) return <tr>
if (!exam) return <tr>
<th>esame obbligatorio</th>
<td>???</td>
<td>...</td>
</tr>

const exam = query.data;


return <tr>
<th>esame obbligatorio</th>
Expand All @@ -47,12 +47,13 @@ function ExamEntry({ entry }) {

export default function CurriculumPage() {
const { id } = useParams()
const query = useGet(path, id || '')
const query = useGetCurriculum(id || '')
const curriculum = query.data
const degree = curriculum?.degree

if (query.isLoading) return <LoadingMessage>caricamento curriculum...</LoadingMessage>

if (query.isError) return <div>errore caricamento curriculum</div>
if (!curriculum) return <LoadingMessage>caricamento curriculum...</LoadingMessage>

const degree = curriculum.degree

console.log(`curriculum: ${JSON.stringify(curriculum)}`)

Expand All @@ -61,7 +62,7 @@ export default function CurriculumPage() {
<h3>{ degree?.name } { degree.academic_year ? displayAcademicYears(degree.academic_year) : '????-????'}</h3>
{ curriculum.years.map((year_section, year_count) =>
<Card key={`year-${year_count}`} title={`${ordinal(year_count+1)} anno`}>
Crediti: { year_section.credits } <br />
Crediti: { `${year_section.credits}` } <br />
<table>
<tbody>
{ year_section.exams.map(entry => <ExamEntry key={entry._id} entry={entry} />)}
Expand Down
Loading

0 comments on commit 42ccea6

Please sign in to comment.