change way od storage with user is loin in

This commit is contained in:
patrol16d 2022-12-16 06:50:55 +01:00
parent 075e792025
commit ec5733213e
9 changed files with 123 additions and 276 deletions

View File

@ -4,7 +4,7 @@ System organizacji PRI
## Usage ## Usage
First create `.env` file and fill with similar data like `./backend/.env.example`. First create `.env` files in `./backend` and `./frontend` and fill with similar data like `.env.example`.
Run application and init database Run application and init database
```bash ```bash

View File

@ -1,89 +0,0 @@
"""empty message
Revision ID: 13d387439f43
Revises: 7deb011753b2
Create Date: 2022-12-15 18:06:57.906228
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '13d387439f43'
down_revision = '7deb011753b2'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('project_grade_sheets',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('group_id', sa.Integer(), nullable=True),
sa.Column('presentation_required_content_1', sa.Integer(), nullable=True),
sa.Column('presentation_required_content_2', sa.Integer(), nullable=True),
sa.Column('presentation_was_compatible_1', sa.Integer(), nullable=True),
sa.Column('presentation_was_compatible_2', sa.Integer(), nullable=True),
sa.Column('presentation_showing_1', sa.Integer(), nullable=True),
sa.Column('presentation_showing_2', sa.Integer(), nullable=True),
sa.Column('presentation_answers_to_questions_from_committee_1', sa.Integer(), nullable=True),
sa.Column('presentation_answers_to_questions_from_committee_2', sa.Integer(), nullable=True),
sa.Column('documentation_project_vision_1', sa.Integer(), nullable=True),
sa.Column('documentation_project_vision_2', sa.Integer(), nullable=True),
sa.Column('documentation_requirements_1', sa.Integer(), nullable=True),
sa.Column('documentation_requirements_2', sa.Integer(), nullable=True),
sa.Column('documentation_for_clients_1', sa.Integer(), nullable=True),
sa.Column('documentation_for_clients_2', sa.Integer(), nullable=True),
sa.Column('documentation_for_developers_1', sa.Integer(), nullable=True),
sa.Column('documentation_for_developers_2', sa.Integer(), nullable=True),
sa.Column('documentation_license_1', sa.Integer(), nullable=True),
sa.Column('documentation_license_2', sa.Integer(), nullable=True),
sa.Column('group_work_regularity_1', sa.Integer(), nullable=True),
sa.Column('group_work_regularity_2', sa.Integer(), nullable=True),
sa.Column('group_work_division_of_work_1', sa.Integer(), nullable=True),
sa.Column('group_work_division_of_work_2', sa.Integer(), nullable=True),
sa.Column('group_work_contact_with_client_1', sa.Integer(), nullable=True),
sa.Column('group_work_contact_with_client_2', sa.Integer(), nullable=True),
sa.Column('group_work_management_of_risk_1', sa.Integer(), nullable=True),
sa.Column('group_work_management_of_risk_2', sa.Integer(), nullable=True),
sa.Column('group_work_work_methodology_1', sa.Integer(), nullable=True),
sa.Column('group_work_work_methodology_2', sa.Integer(), nullable=True),
sa.Column('group_work_management_of_source_code_1', sa.Integer(), nullable=True),
sa.Column('group_work_management_of_source_code_2', sa.Integer(), nullable=True),
sa.Column('group_work_devops_1', sa.Integer(), nullable=True),
sa.Column('group_work_devops_2', sa.Integer(), nullable=True),
sa.Column('products_project_complexity_of_product_1', sa.Integer(), nullable=True),
sa.Column('products_project_complexity_of_product_2', sa.Integer(), nullable=True),
sa.Column('products_project_access_to_application_1', sa.Integer(), nullable=True),
sa.Column('products_project_access_to_application_2', sa.Integer(), nullable=True),
sa.Column('products_project_security_issues_1', sa.Integer(), nullable=True),
sa.Column('products_project_security_issues_2', sa.Integer(), nullable=True),
sa.Column('products_project_access_to_test_application_1', sa.Integer(), nullable=True),
sa.Column('products_project_access_to_test_application_2', sa.Integer(), nullable=True),
sa.Column('products_project_acceptance_criteria_1', sa.Integer(), nullable=True),
sa.Column('products_project_acceptance_criteria_2', sa.Integer(), nullable=True),
sa.Column('products_project_expected_functionality_1', sa.Integer(), nullable=True),
sa.Column('products_project_expected_functionality_2', sa.Integer(), nullable=True),
sa.Column('products_project_promises_well_1', sa.Integer(), nullable=True),
sa.Column('products_project_promises_well_2', sa.Integer(), nullable=True),
sa.Column('products_project_has_been_implemented_1', sa.Integer(), nullable=True),
sa.Column('products_project_has_been_implemented_2', sa.Integer(), nullable=True),
sa.Column('products_project_is_useful_1', sa.Integer(), nullable=True),
sa.Column('products_project_is_useful_2', sa.Integer(), nullable=True),
sa.Column('products_project_prototype_1', sa.Integer(), nullable=True),
sa.Column('products_project_prototype_2', sa.Integer(), nullable=True),
sa.Column('products_project_tests_1', sa.Integer(), nullable=True),
sa.Column('products_project_tests_2', sa.Integer(), nullable=True),
sa.Column('products_project_technology_1', sa.Integer(), nullable=True),
sa.Column('products_project_technology_2', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('project_grade_sheets')
# ### end Alembic commands ###

View File

@ -1,145 +0,0 @@
"""empty message
Revision ID: 7deb011753b2
Revises:
Create Date: 2022-11-16 22:48:36.220156
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '7deb011753b2'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('project_supervisors',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('first_name', sa.String(length=255), nullable=False),
sa.Column('last_name', sa.String(length=255), nullable=False),
sa.Column('email', sa.String(length=120), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('email')
)
op.create_index(op.f('ix_project_supervisors_first_name'), 'project_supervisors', ['first_name'], unique=False)
op.create_index(op.f('ix_project_supervisors_last_name'), 'project_supervisors', ['last_name'], unique=False)
op.create_table('students',
sa.Column('first_name', sa.String(length=255), nullable=False),
sa.Column('last_name', sa.String(length=255), nullable=False),
sa.Column('email', sa.String(length=120), nullable=True),
sa.Column('pesel', sa.String(length=11), nullable=True),
sa.Column('index', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('index'),
sa.UniqueConstraint('email')
)
op.create_index(op.f('ix_students_first_name'), 'students', ['first_name'], unique=False)
op.create_index(op.f('ix_students_last_name'), 'students', ['last_name'], unique=False)
op.create_table('year_groups',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=50), nullable=False),
sa.Column('mode', sa.String(length=1), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('examination_schedules',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('title', sa.String(length=100), nullable=False),
sa.Column('duration_time', sa.Integer(), nullable=False),
sa.Column('start_date_for_enrollment_students', sa.DateTime(), nullable=True),
sa.Column('end_date_for_enrollment_students', sa.DateTime(), nullable=True),
sa.Column('start_date', sa.DateTime(), nullable=False),
sa.Column('end_date', sa.DateTime(), nullable=False),
sa.Column('year_group_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['year_group_id'], ['year_groups.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('title')
)
op.create_table('groups',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=60), nullable=False),
sa.Column('cdyd_kod', sa.String(length=60), nullable=True),
sa.Column('prz_kod', sa.String(length=60), nullable=True),
sa.Column('tzaj_kod', sa.String(length=60), nullable=True),
sa.Column('project_supervisor_id', sa.Integer(), nullable=True),
sa.Column('year_group_id', sa.Integer(), nullable=True),
sa.Column('points_for_first_term', sa.Integer(), nullable=False),
sa.Column('points_for_second_term', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['project_supervisor_id'], ['project_supervisors.id'], ),
sa.ForeignKeyConstraint(['year_group_id'], ['year_groups.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('year_group_project_supervisors',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('project_supervisor_id', sa.Integer(), nullable=False),
sa.Column('year_group_id', sa.Integer(), nullable=False),
sa.Column('limit_group', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['project_supervisor_id'], ['project_supervisors.id'], ),
sa.ForeignKeyConstraint(['year_group_id'], ['year_groups.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('year_group_students',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('year_group_id', sa.Integer(), nullable=True),
sa.Column('student_index', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['student_index'], ['students.index'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['year_group_id'], ['year_groups.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_table('students_groups',
sa.Column('group_id', sa.Integer(), nullable=False),
sa.Column('student_index', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
sa.ForeignKeyConstraint(['student_index'], ['students.index'], )
)
op.create_table('temporary_availabilities',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('start_date', sa.DateTime(), nullable=False),
sa.Column('end_date', sa.DateTime(), nullable=False),
sa.Column('examination_schedule_id', sa.Integer(), nullable=False),
sa.Column('project_supervisor_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['examination_schedule_id'], ['examination_schedules.id'], ),
sa.ForeignKeyConstraint(['project_supervisor_id'], ['project_supervisors.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('term_of_defences',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('start_date', sa.DateTime(), nullable=False),
sa.Column('end_date', sa.DateTime(), nullable=False),
sa.Column('examination_schedule_id', sa.Integer(), nullable=True),
sa.Column('group_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['examination_schedule_id'], ['examination_schedules.id'], ),
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('committees',
sa.Column('term_of_defence_id', sa.Integer(), nullable=True),
sa.Column('project_supervisor_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['project_supervisor_id'], ['project_supervisors.id'], ),
sa.ForeignKeyConstraint(['term_of_defence_id'], ['term_of_defences.id'], )
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('committees')
op.drop_table('term_of_defences')
op.drop_table('temporary_availabilities')
op.drop_table('students_groups')
op.drop_table('year_group_students')
op.drop_table('year_group_project_supervisors')
op.drop_table('groups')
op.drop_table('examination_schedules')
op.drop_table('year_groups')
op.drop_index(op.f('ix_students_last_name'), table_name='students')
op.drop_index(op.f('ix_students_first_name'), table_name='students')
op.drop_table('students')
op.drop_index(op.f('ix_project_supervisors_last_name'), table_name='project_supervisors')
op.drop_index(op.f('ix_project_supervisors_first_name'), table_name='project_supervisors')
op.drop_table('project_supervisors')
# ### end Alembic commands ###

View File

@ -12,7 +12,6 @@ export interface Leader {
first_name: string first_name: string
last_name: string last_name: string
email: string email: string
stationary_mode: boolean
limit_group?: number limit_group?: number
count_groups: number count_groups: number
} }

View File

@ -1,8 +1,45 @@
import { useState } from 'react'
import { useQuery } from 'react-query'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import Select from 'react-select'
import { getYearGroups } from '../api/yearGroups'
import useLocalStorageState from 'use-local-storage-state'
import { getStudents } from '../api/students'
type SelectValue = {
value: string | number
label: string
}
const TopBar = ({ routes, color }: { routes: { name: string; path: string }[]; color: string}, ) => { const TopBar = ({ routes, color }: { routes: { name: string; path: string }[]; color: string}, ) => {
const linkClass = ({ isActive }: { isActive: boolean }) => const linkClass = ({ isActive }: { isActive: boolean }) => isActive ? 'underline font-bold' : ''
isActive ? 'underline font-bold' : ''
const [yearGroupId, setYearGroupId] = useLocalStorageState('yearGroupId', {
defaultValue: -1,
})
const [userType, setUserType] = useLocalStorageState('userType', {
defaultValue: 'coordinator',
})
const [yearGroupOptions, setYearGroupOptions] = useState<SelectValue[]>()
const [name, setName] = useState("")
const onYearChange = (v: any) => {
setYearGroupId(v?.value)
}
useQuery('year_groups', () => getYearGroups({ per_page: 100 }), {
onSuccess: (data) => {
setYearGroupOptions(
data?.data.year_groups.map(({ name, id }) => {
return {
value: id,
label: name,
}
}),
)
},
})
return ( return (
<div className={"flex items-center py-6 px-10 shadow " + color}> <div className={"flex items-center py-6 px-10 shadow " + color}>
<h1 className="text-xl font-bold">System PRI</h1> <h1 className="text-xl font-bold">System PRI</h1>
@ -13,6 +50,21 @@ const TopBar = ({ routes, color }: { routes: { name: string; path: string }[]; c
</NavLink> </NavLink>
))} ))}
</div> </div>
<div className="m-auto flex-col">
{userType == 'coordinator' ? <Select
closeMenuOnSelect={true}
options={yearGroupOptions}
placeholder="Wybierz rok"
onChange={onYearChange}
styles={{
control: (styles: any) => ({
...styles,
padding: '0.01rem',
borderRadius: '0.5rem',
}),
}}
/> : null}
</div>
<NavLink className="ml-auto" to="/"> <NavLink className="ml-auto" to="/">
Wyloguj Wyloguj
</NavLink> </NavLink>

View File

@ -6,6 +6,7 @@ import Select from 'react-select'
import useLocalStorageState from 'use-local-storage-state' import useLocalStorageState from 'use-local-storage-state'
import { getStudents } from '../api/students' import { getStudents } from '../api/students'
import { getYearGroups } from '../api/yearGroups' import { getYearGroups } from '../api/yearGroups'
import { getLeaders } from '../api/leaders'
type SelectValue = { type SelectValue = {
value: string | number value: string | number
@ -16,16 +17,31 @@ const Login = () => {
const navigate = useNavigate() const navigate = useNavigate()
const [yearGroupId, setYearGroupId] = useLocalStorageState('yearGroupId', { const [yearGroupId, setYearGroupId] = useLocalStorageState('yearGroupId', {
defaultValue: 1, defaultValue: -1,
}) })
const [studentId, setStudentId] = useLocalStorageState('studentId') const [userId, setUserId] = useLocalStorageState('userId', {
const [supervisorId, setSupervisorId] = useLocalStorageState('supervisorId', { defaultValue: -1,
defaultValue: 1, })
const [userType, setUserType] = useLocalStorageState('userType', {
defaultValue: 'coordinator',
}) })
const [studentOptions, setStudentOptions] = useState<SelectValue[]>([])
const [yearGroupOptions, setYearGroupOptions] = useState<SelectValue[]>([]) const [yearGroupOptions, setYearGroupOptions] = useState<SelectValue[]>([])
const [studentOptions, setStudentOptions] = useState<SelectValue[]>([])
const [leaderOptions, setLeaderOptions] = useState<SelectValue[]>([])
const [selectedYear, setSelectedYear] = useState<any>() const [selectedYear, setSelectedYear] = useState<any>()
const [selectedRole, setSelectedRole] = useState<any>()
useQuery('year_groups', () => getYearGroups({ per_page: 100 }), {
onSuccess: (data) => {
setYearGroupOptions(
data?.data.year_groups.map(({ name, id }) => {
return {
value: id,
label: name,
}
}),
)
},
})
useQuery( useQuery(
'students', 'students',
@ -44,22 +60,31 @@ const Login = () => {
}, },
) )
useQuery('year_groups', () => getYearGroups({ per_page: 100 }), { useQuery(
onSuccess: (data) => { 'project_supervisors',
setYearGroupOptions( () => getLeaders({ year_group_id: yearGroupId, per_page: 1000 }),
data?.data.year_groups.map(({ name, id }) => { {
return { onSuccess: (data) => {
value: id, setLeaderOptions(
label: name, data?.data.project_supervisors.map(({ first_name, last_name, id }) => {
} return {
}), value: id,
) label: `${first_name} ${last_name}`,
}
}),
)
},
}, },
}) )
const onStudentChange = (v: any) => { const onStudentChange = (v: any) => {
setSelectedRole(v?.value) setUserId(v.value)
setStudentId(v.value) setUserType('student')
}
const onLeaderChange = (v: any) => {
setUserId(v.value)
setUserType('supervisor')
} }
const onYearChange = (v: any) => { const onYearChange = (v: any) => {
@ -102,6 +127,21 @@ const Login = () => {
}} }}
/> />
<label className="label">Opiekun</label>
<Select
closeMenuOnSelect={true}
options={leaderOptions}
placeholder="Wybierz studenta"
onChange={onLeaderChange}
styles={{
control: (styles: any) => ({
...styles,
padding: '0.3rem',
borderRadius: '0.5rem',
}),
}}
/>
{/* <div className="form-control"> {/* <div className="form-control">
<label className="label" htmlFor="login"> <label className="label" htmlFor="login">
Login Login
@ -116,15 +156,18 @@ const Login = () => {
</div> */} </div> */}
<button <button
className="btn mt-5 text-lg" className="btn mt-5 text-lg"
disabled={!selectedRole || !selectedYear} disabled={userId < 0 || selectedYear < 0}
onClick={() => navigate('/student')} onClick={() => navigate('/' + userType)}
> >
Zaloguj Zaloguj
</button> </button>
<div className="flex flex-col mt-3"> <div className="flex flex-col mt-3">
<NavLink to="/coordinator">Koordynator</NavLink> <span onClick={() => {
setUserType('coordinator')
navigate("/coordinator")
}} className="cursor-pointer">Koordynator</span>
{/* <NavLink to="/student">Student</NavLink> */} {/* <NavLink to="/student">Student</NavLink> */}
<NavLink to="/supervisor">Opiekun</NavLink> {/* <NavLink to="/supervisor">Opiekun</NavLink> */}
</div> </div>
</div> </div>
</> </>

View File

@ -7,7 +7,6 @@ import InputError from '../../components/InputError'
const AddLeader = () => { const AddLeader = () => {
const [isAlertVisible, setIsAlertVisible] = useState(false) const [isAlertVisible, setIsAlertVisible] = useState(false)
const [stationaryMode, setStationaryMode] = useState(false)
const { const {
register, register,
handleSubmit, handleSubmit,
@ -21,8 +20,6 @@ const AddLeader = () => {
'createLeader', 'createLeader',
(payload: Leader) => { (payload: Leader) => {
delete payload.limit_group delete payload.limit_group
payload.stationary_mode = stationaryMode
console.log(payload)
return createLeader(payload) return createLeader(payload)
}, },
{ {
@ -104,16 +101,6 @@ const AddLeader = () => {
<InputError>Email jest wymagany</InputError> <InputError>Email jest wymagany</InputError>
)} )}
</div> </div>
<div className="flex">
<label className="label">
<input
type="checkbox"
className="checkbox checkbox-xs md:checkbox-md"
onChange={() => setStationaryMode(!stationaryMode)}
/>
<span className="ml-2 text-xs md:text-base">Tryb stacjonarny</span>
</label>
</div>
{/* <div className="form-control"> {/* <div className="form-control">
<label className="label" htmlFor="limit_group"> <label className="label" htmlFor="limit_group">
Limit grup Limit grup

View File

@ -82,7 +82,7 @@ const Home = () => {
{yearGroups && {yearGroups &&
yearGroups?.data?.year_groups.map((yearGroup) => ( yearGroups?.data?.year_groups.map((yearGroup) => (
<h3 className="text-xl " key={yearGroup.name}> <h3 className="text-xl " key={yearGroup.name}>
- {yearGroup.name} - {yearGroup.name} {yearGroup.mode == 's' ? 'Stacjonarne' : 'Niestacjonarne'}
</h3> </h3>
))} ))}
</div> </div>

View File

@ -35,7 +35,7 @@ const SupervisorSchedule = () => {
const { id } = useParams<{ id: string }>() const { id } = useParams<{ id: string }>()
const [yearGroupId] = useLocalStorageState('yearGroupId') const [yearGroupId] = useLocalStorageState('yearGroupId')
const [supervisorId] = useLocalStorageState('supervisorId') const [supervisorId] = useLocalStorageState('userId')
const [events, setEvents] = useState< const [events, setEvents] = useState<
{ {
id: number id: number