Add import button
This commit is contained in:
parent
a607964114
commit
859885a520
@ -1,13 +1,19 @@
|
||||
import React from "react";
|
||||
import { QueryClient, QueryClientProvider } from "react-query";
|
||||
import { Route, Routes } from "react-router-dom";
|
||||
import "./App.css";
|
||||
import Coordinator from "./views/coordinator/Coordinator";
|
||||
import Groups from "./views/coordinator/Groups";
|
||||
import Leaders from "./views/coordinator/Leaders";
|
||||
import Students from "./views/coordinator/Students";
|
||||
import React from 'react'
|
||||
import { QueryClient, QueryClientProvider } from 'react-query'
|
||||
import { Route, Routes } from 'react-router-dom'
|
||||
import './App.css'
|
||||
import Coordinator from './views/coordinator/Coordinator'
|
||||
import Groups from './views/coordinator/Groups'
|
||||
import Leaders from './views/coordinator/Leaders'
|
||||
import Students from './views/coordinator/Students'
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
function App() {
|
||||
return (
|
||||
@ -23,7 +29,7 @@ function App() {
|
||||
</Routes>
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
@ -1,10 +1,23 @@
|
||||
import axiosInstance from "./axiosInstance";
|
||||
import axiosInstance from './axiosInstance'
|
||||
|
||||
interface StudentResponse {
|
||||
max_pages: number,
|
||||
students: {first_name: string, last_name: string, index: number, mode: boolean; group: any}[]
|
||||
max_pages: number
|
||||
students: {
|
||||
first_name: string
|
||||
last_name: string
|
||||
index: number
|
||||
mode: boolean
|
||||
group: any
|
||||
}[]
|
||||
}
|
||||
|
||||
export const getStudents = () => axiosInstance.get<StudentResponse>(
|
||||
"http://127.0.0.1:5000/api/coordinator/students"
|
||||
)
|
||||
export const getStudents = () =>
|
||||
axiosInstance.get<StudentResponse>(
|
||||
'http://127.0.0.1:5000/api/coordinator/students',
|
||||
)
|
||||
|
||||
export const uploadStudents = (payload: FormData) =>
|
||||
axiosInstance.post(
|
||||
'http://127.0.0.1:5000/api/coordinator/students/upload/',
|
||||
payload,
|
||||
)
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { NavLink } from 'react-router-dom'
|
||||
|
||||
const TopBar = () => {
|
||||
const linkClass = ({ isActive }: { isActive: boolean }) =>
|
||||
isActive ? "underline font-bold" : "";
|
||||
isActive ? 'underline font-bold' : ''
|
||||
return (
|
||||
<div className="flex items-center bg-gray-300 p-6">
|
||||
<h1 className="text-xl font-bold">System PRI</h1>
|
||||
@ -18,7 +18,7 @@ const TopBar = () => {
|
||||
</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default TopBar;
|
||||
export default TopBar
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { useQuery } from 'react-query'
|
||||
import { getStudents } from '../../api/students'
|
||||
import { useMutation, useQuery } from 'react-query'
|
||||
import { getStudents, uploadStudents } from '../../api/students'
|
||||
|
||||
const TableHeader = (props: { children: React.ReactNode }) => (
|
||||
<th className="px-4 py-2 font-medium text-left text-gray-900 whitespace-nowrap">
|
||||
@ -9,17 +9,50 @@ const TableHeader = (props: { children: React.ReactNode }) => (
|
||||
)
|
||||
|
||||
const Students = () => {
|
||||
const { isLoading, data: students } = useQuery('students', () =>
|
||||
getStudents(),
|
||||
const {
|
||||
isLoading: isStudentsLoading,
|
||||
data: students,
|
||||
refetch: refetchStudents,
|
||||
} = useQuery('students', () => getStudents())
|
||||
|
||||
const { mutate: mutateUpload } = useMutation(
|
||||
'uploadStudents',
|
||||
(payload: FormData) => uploadStudents(payload),
|
||||
{
|
||||
onSuccess: () => refetchStudents(),
|
||||
},
|
||||
)
|
||||
if (isLoading) {
|
||||
|
||||
const handleOnChange = (event: any) => {
|
||||
const file = event.target.files[0]
|
||||
const payload = new FormData()
|
||||
payload.append('file', file, file.name)
|
||||
mutateUpload(payload)
|
||||
}
|
||||
|
||||
if (isStudentsLoading) {
|
||||
return <div>Ładowanie</div>
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<button className="bg-green-400 p-3 rounded-lg text-white font-bold hover:bg-green-300">
|
||||
<button className="bg-green-400 p-3 rounded-lg text-white font-extrabold hover:bg-green-300">
|
||||
Dodaj nowego studenta
|
||||
</button>
|
||||
<label
|
||||
className="ml-4 text-green-400 font-extrabold rounded-lg border-2 p-3 border-green-400 hover:border-green-300 cursor-pointer"
|
||||
htmlFor="file"
|
||||
>
|
||||
Importuj
|
||||
</label>
|
||||
<input
|
||||
type="file"
|
||||
id="file"
|
||||
name="avatar"
|
||||
accept=".csv"
|
||||
className="hidden"
|
||||
onChange={handleOnChange}
|
||||
/>
|
||||
|
||||
<div className="flex mx-auto mt-5 overflow-hidden overflow-x-auto border border-gray-100 rounded">
|
||||
<table className="min-w-full text-sm divide-y divide-gray-200">
|
||||
<thead>
|
||||
@ -34,7 +67,7 @@ const Students = () => {
|
||||
<tbody className="divide-y divide-gray-100">
|
||||
{students?.data?.students?.map(
|
||||
({ first_name, last_name, index, group, mode }) => (
|
||||
<tr>
|
||||
<tr key={index}>
|
||||
<td className="px-4 py-2 font-medium text-gray-900 whitespace-nowrap">
|
||||
{first_name}
|
||||
</td>
|
||||
|
Loading…
Reference in New Issue
Block a user