add colors to different modes and stationaryMode to supervisors
This commit is contained in:
parent
817095cc3f
commit
6ae0854fb9
@ -7,7 +7,8 @@ import AddGroup from './views/coordinator/AddGroup'
|
|||||||
import AddStudent from './views/coordinator/AddStudent'
|
import AddStudent from './views/coordinator/AddStudent'
|
||||||
import AddLeader from './views/coordinator/AddLeader'
|
import AddLeader from './views/coordinator/AddLeader'
|
||||||
import Coordinator from './views/coordinator/Coordinator'
|
import Coordinator from './views/coordinator/Coordinator'
|
||||||
import Groups from './views/coordinator/Groups'
|
import CoordinatorGroups from './views/coordinator/CoordinatorGroups'
|
||||||
|
import SupervisorGroups from './views/supervisor/SupervisorGroups'
|
||||||
import Leaders from './views/coordinator/Leaders'
|
import Leaders from './views/coordinator/Leaders'
|
||||||
import Students from './views/coordinator/Students'
|
import Students from './views/coordinator/Students'
|
||||||
import Login from './views/Login'
|
import Login from './views/Login'
|
||||||
@ -42,7 +43,7 @@ function App() {
|
|||||||
<Route index element={<Login />} />
|
<Route index element={<Login />} />
|
||||||
<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={<CoordinatorGroups />} />
|
||||||
<Route path="groups/:id" element={<Group />} />
|
<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 />} />
|
||||||
@ -69,7 +70,7 @@ function App() {
|
|||||||
</Route>
|
</Route>
|
||||||
<Route path="supervisor" element={<Supervisor />}>
|
<Route path="supervisor" element={<Supervisor />}>
|
||||||
<Route index element={<Navigate to="groups" />} />
|
<Route index element={<Navigate to="groups" />} />
|
||||||
<Route path="groups" element={<Groups />} />
|
<Route path="groups" element={<SupervisorGroups />} />
|
||||||
<Route path="schedule" element={<SupervisorSchedules />} />
|
<Route path="schedule" element={<SupervisorSchedules />} />
|
||||||
<Route path="schedule/:id" element={<SupervisorSchedule />} />
|
<Route path="schedule/:id" element={<SupervisorSchedule />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
|
|
||||||
const TopBar = ({ routes }: { routes: { name: string; path: 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' : ''
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center bg-gray-300 py-6 px-10 shadow">
|
<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>
|
||||||
<div className="flex ml-10 gap-3">
|
<div className="flex ml-10 gap-3">
|
||||||
{routes.map(({ path, name }) => (
|
{routes.map(({ path, name }) => (
|
||||||
|
@ -83,7 +83,23 @@ const AddLeader = () => {
|
|||||||
<InputError>Email jest wymagany</InputError>
|
<InputError>Email jest wymagany</InputError>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="form-control">
|
<div className="form-control">
|
||||||
|
<label className="label" htmlFor="stationary_mode">
|
||||||
|
Tryb stacjonarny
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="input input-bordered"
|
||||||
|
id="stationary_mode"
|
||||||
|
type="checkbox"
|
||||||
|
{...register('stationary_mode', {
|
||||||
|
required: true,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
{errors.email?.type === 'required' && (
|
||||||
|
<InputError>Email jest wymagany</InputError>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="form-control">
|
||||||
<label className="label" htmlFor="limit_group">
|
<label className="label" htmlFor="limit_group">
|
||||||
Limit grup
|
Limit grup
|
||||||
</label>
|
</label>
|
||||||
@ -99,7 +115,7 @@ const AddLeader = () => {
|
|||||||
{errors.limit_group?.type === 'pattern' && (
|
{errors.limit_group?.type === 'pattern' && (
|
||||||
<InputError>Limit grup musi być liczbą dodatnią</InputError>
|
<InputError>Limit grup musi być liczbą dodatnią</InputError>
|
||||||
)}
|
)}
|
||||||
</div> */}
|
</div>
|
||||||
<button className="btn btn-success mt-4">Dodaj opiekuna</button>
|
<button className="btn btn-success mt-4">Dodaj opiekuna</button>
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
|
@ -13,6 +13,7 @@ const Coordinator = () => {
|
|||||||
{ name: 'Harmonogram', path: '/coordinator/schedule' },
|
{ name: 'Harmonogram', path: '/coordinator/schedule' },
|
||||||
{ name: 'Dostępność', path: '/coordinator/supervisors_availability' },
|
{ name: 'Dostępność', path: '/coordinator/supervisors_availability' },
|
||||||
]}
|
]}
|
||||||
|
color="bg-violet-400"
|
||||||
/>
|
/>
|
||||||
<div className="m-10">
|
<div className="m-10">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
@ -9,6 +9,7 @@ const Student = () => {
|
|||||||
{ name: 'Zapisy', path: '/student/enrollment' },
|
{ name: 'Zapisy', path: '/student/enrollment' },
|
||||||
{ name: 'Harmonogram', path: '/student/schedule' },
|
{ name: 'Harmonogram', path: '/student/schedule' },
|
||||||
]}
|
]}
|
||||||
|
color="bg-gray-300"
|
||||||
/>
|
/>
|
||||||
<div className="m-10">
|
<div className="m-10">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
@ -9,6 +9,7 @@ const Supervisor = () => {
|
|||||||
{ name: 'Grupy', path: '/supervisor/groups' },
|
{ name: 'Grupy', path: '/supervisor/groups' },
|
||||||
{ name: 'Harmonogram', path: '/supervisor/schedule' },
|
{ name: 'Harmonogram', path: '/supervisor/schedule' },
|
||||||
]}
|
]}
|
||||||
|
color="bg-amber-300"
|
||||||
/>
|
/>
|
||||||
<div className="m-10">
|
<div className="m-10">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
161
frontend/src/views/supervisor/SupervisorGroups.tsx
Normal file
161
frontend/src/views/supervisor/SupervisorGroups.tsx
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import classNames from 'classnames'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useMutation, useQuery } from 'react-query'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import useLocalStorageState from 'use-local-storage-state'
|
||||||
|
import { deleteGroup, getGroups } from '../../api/groups'
|
||||||
|
import { ReactComponent as IconRemove } from '../../assets/svg/icon-remove.svg'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
const SupervisorGroups = () => {
|
||||||
|
let navigate = useNavigate()
|
||||||
|
const [page, setPage] = useState(1)
|
||||||
|
const [perPage, setPerPage] = useState(10)
|
||||||
|
const [yearGroupId] = useLocalStorageState('yearGroupId')
|
||||||
|
|
||||||
|
const perPageOptions = [
|
||||||
|
{
|
||||||
|
value: 10,
|
||||||
|
label: '10 rekordów',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 20,
|
||||||
|
label: '20 rekordów',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 50,
|
||||||
|
label: '50 rekordów',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1000,
|
||||||
|
label: 'Pokaż wszystkie',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const {
|
||||||
|
isLoading: areGroupsLoading,
|
||||||
|
data: groups,
|
||||||
|
refetch: refetchGroups,
|
||||||
|
} = useQuery(['groups', page, perPage], () =>
|
||||||
|
getGroups({ year_group_id: Number(yearGroupId), page, per_page: perPage }),
|
||||||
|
)
|
||||||
|
|
||||||
|
const { mutate: mutateDelete } = useMutation(
|
||||||
|
'deleteGroup',
|
||||||
|
(index: number) => deleteGroup(index),
|
||||||
|
{
|
||||||
|
onSuccess: () => refetchGroups(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPage(1)
|
||||||
|
}, [perPage])
|
||||||
|
|
||||||
|
if (areGroupsLoading) {
|
||||||
|
return <div>Ładowanie</div>
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center justify-between flex-col gap-3 md:flex-row md:gap-0">
|
||||||
|
<button
|
||||||
|
className="btn btn-success"
|
||||||
|
onClick={() => navigate('/coordinator/add-group')}
|
||||||
|
>
|
||||||
|
Dodaj nową grupę
|
||||||
|
</button>
|
||||||
|
<div className="flex">
|
||||||
|
<select className="select select-xs md:select-md select-bordered mr-3">
|
||||||
|
{perPageOptions.map(({ value, label }) => (
|
||||||
|
<option key={value} onClick={() => setPerPage(value)}>
|
||||||
|
{label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex mx-auto mt-5 overflow-hidden overflow-x-auto border border-gray-100 rounded">
|
||||||
|
<table className="min-w-full table table-compact">
|
||||||
|
<thead>
|
||||||
|
<tr className="bg-gray-50">
|
||||||
|
<th>Nazwa</th>
|
||||||
|
<th>Opiekun</th>
|
||||||
|
<th>Semestr 1</th>
|
||||||
|
<th>Semestr 2</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="divide-y divide-gray-100">
|
||||||
|
{groups?.data?.groups?.map(
|
||||||
|
({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
project_supervisor,
|
||||||
|
points_for_first_term,
|
||||||
|
points_for_second_term,
|
||||||
|
}) => (
|
||||||
|
<tr key={id}>
|
||||||
|
<td>
|
||||||
|
<Link
|
||||||
|
to={`/coordinator/groups/${id}`}
|
||||||
|
className="underline font-bold"
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{`${project_supervisor.first_name} ${project_supervisor.last_name}`}
|
||||||
|
</td>
|
||||||
|
<td>{points_for_first_term}</td>
|
||||||
|
<td>{points_for_second_term}</td>
|
||||||
|
<td>
|
||||||
|
<button onClick={() => mutateDelete(id)}>
|
||||||
|
<IconRemove />
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className="w-full flex items-center justify-center mt-2">
|
||||||
|
<div className="btn-group">
|
||||||
|
<button
|
||||||
|
className="btn btn-outline"
|
||||||
|
onClick={() => setPage(page - 1)}
|
||||||
|
disabled={page === 1}
|
||||||
|
>
|
||||||
|
«
|
||||||
|
</button>
|
||||||
|
{[
|
||||||
|
...Array(
|
||||||
|
groups?.data?.max_pages && groups?.data?.max_pages + 1,
|
||||||
|
).keys(),
|
||||||
|
]
|
||||||
|
.slice(1)
|
||||||
|
.map((p) => (
|
||||||
|
<button
|
||||||
|
key={p}
|
||||||
|
className={classNames('btn btn-outline', {
|
||||||
|
'bg-success': p === page,
|
||||||
|
})}
|
||||||
|
onClick={() => setPage(p)}
|
||||||
|
>
|
||||||
|
{p}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
className="btn btn-outline"
|
||||||
|
onClick={() => setPage(page + 1)}
|
||||||
|
disabled={page === groups?.data?.max_pages}
|
||||||
|
>
|
||||||
|
»
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SupervisorGroups
|
Loading…
Reference in New Issue
Block a user