Header, Footer, FileUpload

This commit is contained in:
Peter Hoppe
2022-12-28 15:08:29 +01:00
parent fd65306aaf
commit 4da1c85fe9
18 changed files with 256 additions and 26 deletions

Binary file not shown.

BIN
docs/Bonny2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

29
package-lock.json generated
View File

@ -16,6 +16,7 @@
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"axios": "^1.2.1",
"bootstrap": "^5.2.3",
"env-cmd": "^10.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -3074,6 +3075,16 @@
}
}
},
"node_modules/@popperjs/core": {
"version": "2.11.6",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
"integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@remix-run/router": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.5.tgz",
@ -5174,6 +5185,24 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"node_modules/bootstrap": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz",
"integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"peerDependencies": {
"@popperjs/core": "^2.11.6"
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",

View File

@ -11,6 +11,7 @@
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"axios": "^1.2.1",
"bootstrap": "^5.2.3",
"env-cmd": "^10.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -44,7 +45,7 @@
"last 1 safari version"
]
},
"xxxhomepage____": "http://localhost:3000/dog",
"xxxhomepage": "http://localhost:3000/dog",
"homepage": "https://hope-fly.de/dog",
"xxxxhomepage": "http://localhost/dog"
}

View File

@ -79,7 +79,7 @@ try
$result = new CMsg(
0,
507,
'Too many users registered on the server, try it again later');
'Too many registered users on the server, try it again later');
}
else
{

View File

@ -1,16 +1,21 @@
import React from 'react';
import {useContext} from 'react'
import './App.css';
import { BrowserRouter, Routes, Route, Navigate} from 'react-router-dom';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Login from './components/Login';
import Register from './components/Register';
import Home from './components/Home';
import Dog from './components/Dog';
import {UserCtx, UserCtxT} from './context/UserContext';
import Qr from './components/Qr';
import Header from './components/Header';
import Footer from './components/Footer';
import Impressum from './components/Impressum';
import "bootstrap/dist/css/bootstrap.min.css";
import FileUpload from './components/FileUpload';
function App()
const App: React.FC = () =>
{
const {user} = useContext<UserCtxT | null>(UserCtx) as UserCtxT;
@ -18,17 +23,22 @@ function App()
<div className="App">
<div className="col middle">
<BrowserRouter basename='/dog'>
{user && <Header />}
<Routes>
{user && <Route path="/" element={<Home/>} />}
{!user && <Route path="/" element={<Login/>} />}
{user && <Route index path="/" element={<Home/>} />}
{!user && <Route index path="/" element={<Login/>} />}
{user && <Route path="/qr" element={<Qr/>} />}
{user && <Route path="/d" element={<Dog/>} />}
<Route path="/:qr_id" element={<Dog/>} />
<Route path="/login" element={<Login/>} />
<Route path="/reg" element={<Register/>} />
<Route path="/impressum" element={<Impressum/>} />
<Route path="/upload" element={<FileUpload/>} />
</Routes>
<Footer/>
</BrowserRouter>
</div>
</div>
);
}

View File

@ -1,10 +1,9 @@
import { ResponseT, UserCtx, UserCtxT } from '../context/UserContext';
import React, { useContext, useState, ReactNode } from 'react'
import { UserCtx, UserCtxT } from '../context/UserContext';
import { useContext, ReactNode } from 'react'
import { useParams } from "react-router-dom";
import Img from './Img';
import DogNameTxt from './DogNameTxt';
import './Dog.css';
import { JSXElement, JSXFragment } from '@babel/types';
const Dog = () =>
{
@ -13,21 +12,20 @@ const Dog = () =>
// m7MdMK
const params = useParams();
const qr_id = Object.values(params)[0];
var data;
var needData = dog.success === undefined;
if(needData)
{
data = getDog(qr_id); // await not allowed?! => workaraound
getDog(qr_id); // await not allowed?! => workaraound
}
var email = "nicht definiert;"
var phone = "nicht definiert;"
var picPath = "nicht definiert;"
var qrPath = "nicht definiert;"
//var qrPath = "nicht definiert;"
var name = "nicht definiert;"
if(dog.success === 1)
{
name = dog.data.name;
qrPath = dog.data.qr_code;
//qrPath = dog.data.qr_code;
picPath = dog.data.picture;
email = dog.data.email;
phone = dog.data.phone;

View File

@ -0,0 +1,123 @@
import { useState, useEffect } from "react";
import UploadService from "../services/FileUploadService";
import IFile from "../types/File";
const FileUpload: React.FC = () =>
{
const [currentFile, setCurrentFile] = useState<File>();
const [progress, setProgress] = useState(0);
const [message, setMessage] = useState("");
const [fileInfos, setFileInfos] = useState([]);
const selectFile = (event: React.ChangeEvent<HTMLInputElement>) =>
{
const { files } = event.target;
const selectedFiles = files as FileList;
setCurrentFile(selectedFiles?.[0]);
setProgress(0);
};
const upload = () =>
{
setProgress(0);
if (!currentFile) return;
UploadService.upload(currentFile, (event: any) =>
{
setProgress(Math.round((100 * event.loaded) / event.total));
})
.then((response) =>
{
setMessage(response.data.message);
return UploadService.getFiles();
})
.then((files) =>
{
setFileInfos(files.data);
})
.catch((err) =>
{
setProgress(0);
if (err.response && err.response.data && err.response.data.message)
{
setMessage(err.response.data.message);
}
else
{
setMessage("Could not upload the File!");
}
setCurrentFile(undefined);
});
};
useEffect(() =>
{
UploadService.getFiles().then((response) =>
{
setFileInfos(response.data);
});
}, []);
return (
<div>
<div className="row">
<div className="col-8">
<label className="btn btn-default p-0">
<input type="file" onChange={selectFile} />
</label>
</div>
<div className="col-4">
<button
className="btn btn-success btn-sm"
disabled={!currentFile}
onClick={upload}
>
Upload
</button>
</div>
</div>
{currentFile && (
<div className="progress my-3">
<div
className="progress-bar progress-bar-info"
role="progressbar"
aria-valuenow={progress}
aria-valuemin={0}
aria-valuemax={100}
style={{ width: progress + "%" }}
>
{progress}%
</div>
</div>
)}
{message && (
<div className="alert alert-secondary mt-3" role="alert">
{message}
</div>
)}
<div className="card mt-3">
<div className="card-header">List of Files</div>
<ul className="list-group list-group-flush">
{fileInfos &&
fileInfos.map((file: IFile, index: number) => (
<li className="list-group-item" key={index}>
<a href={file.url}>{file.name}</a>
</li>
))}
</ul>
</div>
</div>
);
}
export default FileUpload;

View File

10
src/components/Footer.tsx Normal file
View File

@ -0,0 +1,10 @@
import { Link } from 'react-router-dom';
import './Footer.css';
function Footer() {
return (
<div><Link to={'./Impressum'}>Impressum</Link></div>
);
}
export default Footer;

View File

@ -0,0 +1,6 @@
.logout
{
display: flex;
flex-direction: row;
justify-content: flex-end;
}

28
src/components/Header.tsx Normal file
View File

@ -0,0 +1,28 @@
import React, { useContext } from 'react'
import './Header.css';
import {Axios, UserCtx, UserCtxT} from '../context/UserContext';
function Header() {
const {setUser} = useContext<UserCtxT | null>(UserCtx) as UserCtxT;
const logOut = () =>
{
Axios.post('logout.php')
.then((res) =>
{
console.log(res);
})
.catch((err) => console.error(err));
setUser(null);
}
return (
<div className='logout'>
<div>Header</div>
<button onClick={logOut}>Logout</button>
</div>
);
}
export default Header;

View File

@ -9,7 +9,7 @@ export default function Qr()
const { user } = useContext<UserCtxT | null>(UserCtx) as UserCtxT;
const [dog, setDog] = useState<DogT | any>({}); // local dog not the dog in UserContext
if(user)
if(user && dog.success === undefined)
{
Axios.post<ResponseT>('getDog.php',
{

View File

@ -1,11 +0,0 @@
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
session_start();
session_destroy();
session_abort();
?>

View File

@ -41,6 +41,8 @@ export type UserCtxT =
{
user: TUser | null,
setUser: React.Dispatch<React.SetStateAction<TUser | null>>,
registerUser: ({ email, password }: {
email: string;
password: string;
@ -153,7 +155,7 @@ export const UserCtxProvider = ({children}:TUserContextProviderProps) => {
setUser(data.user);
return;
}
setUser(null);
//setUser(null);
}
else
{
@ -165,6 +167,7 @@ export const UserCtxProvider = ({children}:TUserContextProviderProps) => {
return;
}
}
setUser(null);
}
useEffect(() =>
@ -212,6 +215,7 @@ export const UserCtxProvider = ({children}:TUserContextProviderProps) => {
loginUser,
wait,
user,
setUser,
getUser,
logout,
getDog,

View File

@ -0,0 +1,27 @@
//import http from "../http-common";
import { Axios } from '../context/UserContext';
const upload = (file: File, onUploadProgress: any): Promise<any> => {
let formData = new FormData();
formData.append("file", file);
return Axios.post("/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
onUploadProgress,
});
};
const getFiles = () : Promise<any> => {
return Axios.get("/files");
};
const FileUploadService = {
upload,
getFiles,
};
export default FileUploadService;

5
src/types/File.ts Normal file
View File

@ -0,0 +1,5 @@
export default interface IFile
{
url: string,
name: string,
}