Add import button

This commit is contained in:
adam-skowronek 2022-05-30 21:38:45 +02:00
parent a607964114
commit 859885a520
4 changed files with 81 additions and 29 deletions

View File

@ -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

View File

@ -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,
)

View File

@ -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

View File

@ -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>