Fix export/import of students, add grade card view
This commit is contained in:
parent
5d94bba15f
commit
292ef17be6
@ -23,6 +23,8 @@ import SupervisorSchedule from './views/supervisor/SupervisorSchedule'
|
|||||||
import Home from './views/coordinator/Home'
|
import Home from './views/coordinator/Home'
|
||||||
import SupervisorAvailabilities from './views/coordinator/SupervisorAvailabilities'
|
import SupervisorAvailabilities from './views/coordinator/SupervisorAvailabilities'
|
||||||
import AvailabilitySchedule from './views/coordinator/AvailabilitySchedule'
|
import AvailabilitySchedule from './views/coordinator/AvailabilitySchedule'
|
||||||
|
import GradeCard from './views/GradeCard'
|
||||||
|
import Group from './views/coordinator/Group'
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
@ -41,6 +43,7 @@ function App() {
|
|||||||
<Route path="coordinator" element={<Coordinator />}>
|
<Route path="coordinator" element={<Coordinator />}>
|
||||||
<Route index element={<Home />} />
|
<Route index element={<Home />} />
|
||||||
<Route path="groups" element={<Groups />} />
|
<Route path="groups" element={<Groups />} />
|
||||||
|
<Route path="groups/:id" element={<Group />} />
|
||||||
<Route path="students" element={<Students />} />
|
<Route path="students" element={<Students />} />
|
||||||
<Route path="leaders" element={<Leaders />} />
|
<Route path="leaders" element={<Leaders />} />
|
||||||
<Route path="add-student" element={<AddStudent />} />
|
<Route path="add-student" element={<AddStudent />} />
|
||||||
@ -52,6 +55,7 @@ function App() {
|
|||||||
path="supervisors_availability"
|
path="supervisors_availability"
|
||||||
element={<SupervisorAvailabilities />}
|
element={<SupervisorAvailabilities />}
|
||||||
/>
|
/>
|
||||||
|
<Route path="groups/:id/grade-card" element={<GradeCard />} />
|
||||||
<Route
|
<Route
|
||||||
path="supervisors_availability/:id"
|
path="supervisors_availability/:id"
|
||||||
element={<AvailabilitySchedule />}
|
element={<AvailabilitySchedule />}
|
||||||
|
33
frontend/src/api/grades.ts
Normal file
33
frontend/src/api/grades.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import axiosInstance from './axiosInstance'
|
||||||
|
|
||||||
|
export const updateGradesFirstTerm = (
|
||||||
|
groupId: number,
|
||||||
|
supervisorId: number,
|
||||||
|
payload: any,
|
||||||
|
) => {
|
||||||
|
return axiosInstance.patch(
|
||||||
|
`project_supervisor/project-grade-sheet/group/${groupId}/first-term/?id=${supervisorId}`,
|
||||||
|
payload,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateGradesSecondTerm = (
|
||||||
|
groupId: number,
|
||||||
|
supervisorId: number,
|
||||||
|
payload: any,
|
||||||
|
) => {
|
||||||
|
return axiosInstance.patch(
|
||||||
|
`project_supervisor/project-grade-sheet/group/${groupId}/second-term/?id=${supervisorId}`,
|
||||||
|
payload,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getGradesForSupervisor = (
|
||||||
|
groupId: number,
|
||||||
|
term: number,
|
||||||
|
supervisorId: number,
|
||||||
|
) => {
|
||||||
|
return axiosInstance.get<{ [key: string]: any }>(
|
||||||
|
`project_supervisor/project-grade-sheet/group/${groupId}/?term=${term}&id=${supervisorId}`,
|
||||||
|
)
|
||||||
|
}
|
@ -38,3 +38,6 @@ export const createGroup = (year_group_id: number, payload: CreateGroup) =>
|
|||||||
|
|
||||||
export const deleteGroup = (id: number) =>
|
export const deleteGroup = (id: number) =>
|
||||||
axiosInstance.delete(`coordinator/groups/${id}/`)
|
axiosInstance.delete(`coordinator/groups/${id}/`)
|
||||||
|
|
||||||
|
export const getGroup = (id: number) =>
|
||||||
|
axiosInstance.get<Group>(`coordinator/groups/${id}/detail/`)
|
||||||
|
@ -35,13 +35,21 @@ export const getStudents = (
|
|||||||
export const createStudent = (payload: Student & { year_group_id: number }) =>
|
export const createStudent = (payload: Student & { year_group_id: number }) =>
|
||||||
axiosInstance.post('coordinator/students/', payload)
|
axiosInstance.post('coordinator/students/', payload)
|
||||||
|
|
||||||
export const uploadStudents = (payload: FormData) =>
|
export const uploadStudents = (payload: FormData, year_group_id: number) =>
|
||||||
axiosInstance.post('coordinator/students/upload/', payload)
|
axiosInstance.post(
|
||||||
|
`coordinator/students/upload/?id=${year_group_id}`,
|
||||||
|
payload,
|
||||||
|
)
|
||||||
|
|
||||||
export const deleteStudent = (index: number) =>
|
export const deleteStudent = (index: number) =>
|
||||||
axiosInstance.delete(`coordinator/students/${index}/`)
|
axiosInstance.delete(`coordinator/students/${index}/`)
|
||||||
|
|
||||||
export const downloadStudents = (mode: boolean) =>
|
export const downloadStudents = (mode: boolean, year_group_id: number) =>
|
||||||
axiosInstance.post(`coordinator/students/download/?mode=${Number(mode)}`, {
|
axiosInstance.post(
|
||||||
responseType: 'blob',
|
`coordinator/students/download/?mode=${Number(
|
||||||
})
|
mode,
|
||||||
|
)}&year_group_id=${year_group_id}`,
|
||||||
|
{
|
||||||
|
responseType: 'blob',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
13
frontend/src/views/GradeCard.module.css
Normal file
13
frontend/src/views/GradeCard.module.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.grade-table td,
|
||||||
|
.grade-table th {
|
||||||
|
border: 1px solid lightgray;
|
||||||
|
}
|
||||||
|
.grade-table th {
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
||||||
|
.grade-table input {
|
||||||
|
background: #f2f2f2;
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
width: 100px;
|
||||||
|
}
|
721
frontend/src/views/GradeCard.tsx
Normal file
721
frontend/src/views/GradeCard.tsx
Normal file
@ -0,0 +1,721 @@
|
|||||||
|
import { useForm } from 'react-hook-form'
|
||||||
|
import { useMutation, useQuery } from 'react-query'
|
||||||
|
import { useParams } from 'react-router-dom'
|
||||||
|
import useLocalStorageState from 'use-local-storage-state'
|
||||||
|
import {
|
||||||
|
getGradesForSupervisor,
|
||||||
|
updateGradesFirstTerm,
|
||||||
|
updateGradesSecondTerm,
|
||||||
|
} from '../api/grades'
|
||||||
|
import styles from './GradeCard.module.css' // Import css modules stylesheet as styles
|
||||||
|
|
||||||
|
const GradeCard = () => {
|
||||||
|
const { register, handleSubmit, setValue } = useForm()
|
||||||
|
const { id } = useParams<{ id: string }>()
|
||||||
|
const [supervisorId] = useLocalStorageState('supervisorId')
|
||||||
|
|
||||||
|
useQuery(
|
||||||
|
['getGradesFirst'],
|
||||||
|
() => getGradesForSupervisor(Number(id), 1, Number(supervisorId)),
|
||||||
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
for (const [key, value] of Object.entries(data.data)) {
|
||||||
|
if (key !== 'id') setValue(key, value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
useQuery(
|
||||||
|
['getGradesSecond'],
|
||||||
|
() => getGradesForSupervisor(Number(id), 2, Number(supervisorId)),
|
||||||
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
for (const [key, value] of Object.entries(data.data)) {
|
||||||
|
if (key !== 'id') setValue(key, value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const { mutate: mutateGradesFirstTerm } = useMutation(
|
||||||
|
'update_grades_first',
|
||||||
|
(payload: any) => updateGradesFirstTerm(1, 1, payload),
|
||||||
|
)
|
||||||
|
|
||||||
|
const { mutate: mutateGradesSecondTerm } = useMutation(
|
||||||
|
'update_grades_second',
|
||||||
|
(payload: any) => updateGradesSecondTerm(1, 1, payload),
|
||||||
|
)
|
||||||
|
|
||||||
|
const onSubmit = (data: any) => {
|
||||||
|
let firstTermGrades: { [key: string]: any } = {}
|
||||||
|
let secondTermGrades: { [key: string]: any } = {}
|
||||||
|
for (const [key, value] of Object.entries(data)) {
|
||||||
|
if (key.endsWith('_1')) {
|
||||||
|
firstTermGrades[key] = Number(value)
|
||||||
|
} else {
|
||||||
|
secondTermGrades[key] = Number(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutateGradesFirstTerm(firstTermGrades)
|
||||||
|
mutateGradesSecondTerm(secondTermGrades)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles['grade-table']}>
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<button className="btn btn-success mb-2">ZAPISZ</button>
|
||||||
|
</div>
|
||||||
|
<table className=" table-normal border-collapse">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Kryterium</th>
|
||||||
|
<th>Waga I semestr</th>
|
||||||
|
<th>Waga II semestr</th>
|
||||||
|
<th>Punkty I semestr [0,1,3,4]</th>
|
||||||
|
<th>Punkty II semestr [0,1,3,4]</th>
|
||||||
|
<th>Udział I</th>
|
||||||
|
<th>Udział II</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h3 className="text-xl font-bold">Prezentacja</h3>
|
||||||
|
</td>
|
||||||
|
<td>1,5</td>
|
||||||
|
<td>1,5</td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Czy prezentacja zawierała wszystkie wymagane treści (cel i
|
||||||
|
założenia projektowe, podział prac na semestry, przegląd
|
||||||
|
zrealizowanych funkcjonalności, architektura i użyte
|
||||||
|
technologie, role osób w zespole, demo systemu)? * (oceniane
|
||||||
|
podczas obrony semestralnej)
|
||||||
|
</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('presentation_required_content_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('presentation_required_content_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>3,5%</td>
|
||||||
|
<td>1,2%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Czy prezentacja (omówienie projektu i jego demonstracja) była
|
||||||
|
przeprowadzona zgodnie ze sztuką? (oceniane podczas obrony
|
||||||
|
semestralnej)
|
||||||
|
</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('presentation_was_compatible_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('presentation_was_compatible_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>4,6%</td>
|
||||||
|
<td>4,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Demonstracja systemu * (oceniane podczas obrony semestralnej)
|
||||||
|
</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>6</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('presentation_showing_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('presentation_showing_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>4,6%</td>
|
||||||
|
<td>6,9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Odpowiedzi na pytania komisji (oceniane podczas obrony
|
||||||
|
semestralnej)
|
||||||
|
</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register(
|
||||||
|
'presentation_answers_to_questions_from_committee_1',
|
||||||
|
{},
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register(
|
||||||
|
'presentation_answers_to_questions_from_committee_2',
|
||||||
|
{},
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>2,3%</td>
|
||||||
|
<td>2,3%</td>
|
||||||
|
</tr>
|
||||||
|
{/* */}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{' '}
|
||||||
|
<h3 className="text-xl font-bold">Dokumentacja</h3>
|
||||||
|
</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Dokument wizji projektu *</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_project_vision_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_project_vision_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>7,5%</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Dokument wymagań projektowych *</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_requirements_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_requirements_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>7,5%</td>
|
||||||
|
<td>2,9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Dokumentacja dla klienta/grupy docelowej/użytkownika</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_for_clients_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_for_clients_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
<td>2,9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Dokumentacja deweloperska</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_for_developers_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_for_developers_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>2,5%</td>
|
||||||
|
<td>2,9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Licencja i podział praw własności</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_license_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('documentation_license_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>2,5%</td>
|
||||||
|
<td>1,4%</td>
|
||||||
|
</tr>
|
||||||
|
{/* */}
|
||||||
|
<tr>
|
||||||
|
<td>Praca grupy w semestrze</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Systematyczność pracy w semestrze *</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_regularity_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_regularity_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>7,9%</td>
|
||||||
|
<td>6,5%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Podział prac w semestrze * (obowiązkowe w II sem)</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_division_of_work_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_division_of_work_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>4,7%</td>
|
||||||
|
<td>3,9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Kontakt z klientem/grupą docelową, testy w grupie docelowej
|
||||||
|
</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_contact_with_client_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_contact_with_client_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>6,3%</td>
|
||||||
|
<td>5,2%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Zarządzanie ryzykiem i zakresem projektu</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_management_of_risk_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_management_of_risk_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>3,2%</td>
|
||||||
|
<td>3,9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Metodyka pracy i narzędzia ją wspierające *</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_work_methodology_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_work_methodology_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>4,7%</td>
|
||||||
|
<td>3,9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Zarządzanie kodem źródłowym *</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_management_of_source_code_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('group_work_management_of_source_code_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>3,2%</td>
|
||||||
|
<td>2,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DevOps</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" {...register('group_work_devops_1', {})} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" {...register('group_work_devops_2', {})} />
|
||||||
|
</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
<td>3,9%</td>
|
||||||
|
</tr>
|
||||||
|
{/* */}
|
||||||
|
<tr>
|
||||||
|
<td>Produkty projektu</td>
|
||||||
|
<td>3,5</td>
|
||||||
|
<td>4,5</td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Czy złożoność produktu projektu odpowiada wielkości zespołu? Czy
|
||||||
|
jakość produktu odpowiada wielkości projektu *
|
||||||
|
</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_complexity_of_product_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_complexity_of_product_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>4,8%</td>
|
||||||
|
<td>6,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Dostęp do produktu projektu dla komisji do testów podczas
|
||||||
|
prezentacji * (obowiązkowe w II sem) (oceniane podczas obrony
|
||||||
|
semestralnej)
|
||||||
|
</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_access_to_application_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_access_to_application_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>1,6%</td>
|
||||||
|
<td>1,3%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Brak krytycznych błędów w tym: bezpieczeństwa oraz
|
||||||
|
uniemożliwiających korzystanie z systemu * (oceniane podczas
|
||||||
|
obrony semestralnej)
|
||||||
|
</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_security_issues_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_security_issues_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
<td>2,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Dostęp do produktu projektu dla komisji do testów tydzień przed
|
||||||
|
prezentacją (oceniane podczas obrony semestralnej)
|
||||||
|
</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register(
|
||||||
|
'products_project_access_to_test_application_1',
|
||||||
|
{},
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register(
|
||||||
|
'products_project_access_to_test_application_2',
|
||||||
|
{},
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
<td>6,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Spełnienie kryteriów akceptacji *</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_acceptance_criteria_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_acceptance_criteria_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>8,0%</td>
|
||||||
|
<td>6,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Czy wdrożone zostały wszystkie zakładane na dany semestr
|
||||||
|
funkcjonalności (ocenia prowadzący)?
|
||||||
|
</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_expected_functionality_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_expected_functionality_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>3,2%</td>
|
||||||
|
<td>2,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Czy projekt dobrze rokuje?</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_promises_well_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_promises_well_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>8,0%</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Czy projekt został wdrożony?</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_has_been_implemented_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_has_been_implemented_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
<td>4,0%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Czy projekt jest użyteczny dla grupy docelowej; Czy spełnia
|
||||||
|
kryteria użyteczności i został przetestowany pod tym kątem?
|
||||||
|
</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_is_useful_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_is_useful_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>4,8%</td>
|
||||||
|
<td>6,6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Czy przygotowano prototyp projektu zgodnie ze sztuką? *</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_prototype_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_prototype_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>3,2%</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Czy przeprowadzono i udokumentowano testy, w tym testy:
|
||||||
|
jednostkowe, integracyjne, akceptacyjne, obciążeniowe,
|
||||||
|
funkcjonalne (kryterium nie obejmuje testów użyteczności) oraz
|
||||||
|
statyczna analiza jakości kodu
|
||||||
|
</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_tests_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_tests_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>0,0%</td>
|
||||||
|
<td>5,3%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Dobór techologii i architektury systemu do rozwiązywanego
|
||||||
|
problemu
|
||||||
|
</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_technology_1', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
{...register('products_project_technology_2', {})}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>1,6%</td>
|
||||||
|
<td>2,6%</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<button className="btn btn-success mt-2">ZAPISZ</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GradeCard
|
24
frontend/src/views/coordinator/Group.tsx
Normal file
24
frontend/src/views/coordinator/Group.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { useQuery } from 'react-query'
|
||||||
|
import { Link, useParams } from 'react-router-dom'
|
||||||
|
import { getGroup } from '../../api/groups'
|
||||||
|
|
||||||
|
const Group = () => {
|
||||||
|
const { id } = useParams<{ id: string }>()
|
||||||
|
|
||||||
|
const { data: groups } = useQuery(['getGroup'], () => getGroup(Number(id)))
|
||||||
|
const { name, project_supervisor } = groups?.data || {}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1 className="font-bold text-xl">{name}</h1>
|
||||||
|
<h2 className="">
|
||||||
|
Opiekun: {project_supervisor?.first_name}{' '}
|
||||||
|
{project_supervisor?.last_name}
|
||||||
|
</h2>
|
||||||
|
<Link to={`/coordinator/groups/${id}/grade-card`}>
|
||||||
|
<button className="btn btn-success mt-2">KARTA OCENY</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Group
|
@ -5,6 +5,7 @@ import { useNavigate } from 'react-router-dom'
|
|||||||
import useLocalStorageState from 'use-local-storage-state'
|
import useLocalStorageState from 'use-local-storage-state'
|
||||||
import { deleteGroup, getGroups } from '../../api/groups'
|
import { deleteGroup, getGroups } from '../../api/groups'
|
||||||
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
const Groups = () => {
|
const Groups = () => {
|
||||||
let navigate = useNavigate()
|
let navigate = useNavigate()
|
||||||
@ -94,7 +95,14 @@ const Groups = () => {
|
|||||||
points_for_second_term,
|
points_for_second_term,
|
||||||
}) => (
|
}) => (
|
||||||
<tr key={id}>
|
<tr key={id}>
|
||||||
<td>{name}</td>
|
<td>
|
||||||
|
<Link
|
||||||
|
to={`/coordinator/groups/${id}`}
|
||||||
|
className="underline font-bold"
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{`${project_supervisor.first_name} ${project_supervisor.last_name}`}
|
{`${project_supervisor.first_name} ${project_supervisor.last_name}`}
|
||||||
</td>
|
</td>
|
||||||
|
@ -53,7 +53,7 @@ const Students = () => {
|
|||||||
|
|
||||||
const { mutate: mutateDownload } = useMutation(
|
const { mutate: mutateDownload } = useMutation(
|
||||||
'downloadStudents',
|
'downloadStudents',
|
||||||
(mode: boolean) => downloadStudents(mode),
|
(mode: boolean) => downloadStudents(mode, Number(yearGroupId)),
|
||||||
{
|
{
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
const url = window.URL.createObjectURL(new Blob([res.data]))
|
const url = window.URL.createObjectURL(new Blob([res.data]))
|
||||||
@ -68,7 +68,7 @@ const Students = () => {
|
|||||||
|
|
||||||
const { mutate: mutateUpload } = useMutation(
|
const { mutate: mutateUpload } = useMutation(
|
||||||
'uploadStudents',
|
'uploadStudents',
|
||||||
(payload: FormData) => uploadStudents(payload),
|
(payload: FormData) => uploadStudents(payload, Number(yearGroupId)),
|
||||||
{
|
{
|
||||||
onSuccess: () => refetchStudents(),
|
onSuccess: () => refetchStudents(),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user