diff --git a/docs/Bestellung # 000001860.pdf b/docs/Bestellung # 000001860.pdf deleted file mode 100644 index da08de4..0000000 Binary files a/docs/Bestellung # 000001860.pdf and /dev/null differ diff --git a/docs/Bonny2.png b/docs/Bonny2.png new file mode 100644 index 0000000..f8f9ae3 Binary files /dev/null and b/docs/Bonny2.png differ diff --git a/docs/bc535769f3f10994c63fdb68ba2ec650.ico.zip b/docs/bc535769f3f10994c63fdb68ba2ec650.ico.zip new file mode 100644 index 0000000..8a1b1fe Binary files /dev/null and b/docs/bc535769f3f10994c63fdb68ba2ec650.ico.zip differ diff --git a/package-lock.json b/package-lock.json index b91677f..e45212f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 50a30e0..e682a70 100644 --- a/package.json +++ b/package.json @@ -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" } diff --git a/php/php-dog/register.php b/php/php-dog/register.php index 2f69b4a..7fcc4d6 100644 --- a/php/php-dog/register.php +++ b/php/php-dog/register.php @@ -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 { diff --git a/php/php-dog/upload.php b/php/php-dog/upload.php index be635bb..5b4f5b6 100644 --- a/php/php-dog/upload.php +++ b/php/php-dog/upload.php @@ -58,7 +58,7 @@ if(isset($_POST["submit"]) && !empty($_FILES["file"]["name"])) if(move_uploaded_file($_FILES["file"]["tmp_name"], $targetFilePath)) { // Insert image file name into database - $update = $db->query("UPDATE dogs SET qr_codefile_name, uploaded_on) VALUES ('".$fileName."', NOW())"); + $update = $db->query("UPDATE dogs SET picture = '".$fileName."' WHERE qr_id = ".$user->qr_id); if($update) { $result = new CMsg(1,200,"The file ".$fileName. " has been uploaded successfully."); diff --git a/src/App.tsx b/src/App.tsx index 684777d..28c681a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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(UserCtx) as UserCtxT; @@ -18,17 +23,22 @@ function App()
+ {user &&
} - {user && } />} - {!user && } />} + {user && } />} + {!user && } />} {user && } />} {user && } />} } /> } /> } /> + } /> + } /> +
+
); } diff --git a/src/components/Dog.tsx b/src/components/Dog.tsx index bf81727..2d2c5ae 100644 --- a/src/components/Dog.tsx +++ b/src/components/Dog.tsx @@ -1,5 +1,5 @@ -import { ResponseT, UserCtx, UserCtxT } from '../context/UserContext'; -import React, { useContext, useState } 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'; @@ -12,37 +12,39 @@ 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; } - return ( -
-

Hast Du mich gefunden?

- {/*

name: {name}

-

email: {email}

-

phone: {phone}

-

pic: {picPath}

-

qr: {qrPath}

*/} - - -
- ) + const content: ReactNode = dog.success === 1 ? +
+

Hast Du mich gefunden?

+ {/*

name: {name}

+

email: {email}

+

phone: {phone}

+

pic: {picPath}

+

qr: {qrPath}

*/} + + +
+: +<>; + + return ( content ); } export default Dog; \ No newline at end of file diff --git a/src/components/FileUpload.tsx b/src/components/FileUpload.tsx new file mode 100644 index 0000000..5f08c33 --- /dev/null +++ b/src/components/FileUpload.tsx @@ -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(); + const [progress, setProgress] = useState(0); + const [message, setMessage] = useState(""); + const [fileInfos, setFileInfos] = useState([]); + + + const selectFile = (event: React.ChangeEvent) => + { + 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 ( +
+
+
+ +
+ +
+ +
+
+ + {currentFile && ( +
+
+ {progress}% +
+
+ )} + + {message && ( +
+ {message} +
+ )} + +
+
List of Files
+
    + {fileInfos && + fileInfos.map((file: IFile, index: number) => ( +
  • + {file.name} +
  • + ))} +
+
+
+ + ); +} + +export default FileUpload; \ No newline at end of file diff --git a/src/components/Footer.css b/src/components/Footer.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx new file mode 100644 index 0000000..0baccd3 --- /dev/null +++ b/src/components/Footer.tsx @@ -0,0 +1,10 @@ +import { Link } from 'react-router-dom'; +import './Footer.css'; + +function Footer() { + return ( +
Impressum
+ ); +} + +export default Footer; \ No newline at end of file diff --git a/src/components/Header.css b/src/components/Header.css new file mode 100644 index 0000000..2229a2b --- /dev/null +++ b/src/components/Header.css @@ -0,0 +1,6 @@ +.logout +{ + display: flex; + flex-direction: row; + justify-content: flex-end; +} \ No newline at end of file diff --git a/src/components/Header.tsx b/src/components/Header.tsx new file mode 100644 index 0000000..3b195fa --- /dev/null +++ b/src/components/Header.tsx @@ -0,0 +1,28 @@ +import React, { useContext } from 'react' +import './Header.css'; +import {Axios, UserCtx, UserCtxT} from '../context/UserContext'; + + +function Header() { + const {setUser} = useContext(UserCtx) as UserCtxT; + const logOut = () => + { + Axios.post('logout.php') + .then((res) => + { + console.log(res); + }) + .catch((err) => console.error(err)); + + setUser(null); + } + + return ( +
+
Header
+ +
+ ); +} + +export default Header; \ No newline at end of file diff --git a/src/components/ImpressTxt.tsx b/src/components/ImpressTxt.tsx new file mode 100644 index 0000000..b9186bd --- /dev/null +++ b/src/components/ImpressTxt.tsx @@ -0,0 +1,70 @@ +import React from 'react'; + +const ImpressTxt = () => +{ + return ( +<> +

Angaben gem. § 5 TMG:

+

 

+

Dipl.-Ing. Peter Hoppe

+

Rachelstraße 12a

+

93059 Regensburg

+

 

+

Kontaktaufnahme:

+

 

+

E-Mail:

+

 

+

Haftungsausschluss - Disclaimer:

+

 

+

Haftung für Inhalte

+

 

+

Alle Inhalte unseres Internetauftritts wurden mit größter Sorgfalt und nach bestem Gewissen erstellt. Für die + Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir jedoch keine Gewähr übernehmen. Als + Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen + verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder + gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige + Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen + Gesetzen bleiben hiervon unberührt.

+

Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntniserlangung einer konkreten Rechtsverletzung + möglich. Bei Bekanntwerden von den o.g. Rechtsverletzungen werden wir diese Inhalte unverzüglich entfernen.

+

 

+

Haftungsbeschränkung für externe Links

+

 

+

Unsere Webseite enthält Links auf externe Webseiten Dritter. Auf die Inhalte dieser direkt oder indirekt verlinkten + Webseiten haben wir keinen Einfluss. Daher können wir für die „externen Links“ auch keine Gewähr auf Richtigkeit der + Inhalte übernehmen. Für die Inhalte der externen Links sind die jeweilige Anbieter oder Betreiber (Urheber) der + Seiten verantwortlich.

+

Die externen Links wurden zum Zeitpunkt der Linksetzung auf eventuelle Rechtsverstöße überprüft und waren im + Zeitpunkt der Linksetzung frei von rechtswidrigen Inhalten. Eine ständige inhaltliche Überprüfung der externen Links + ist ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht möglich. Bei direkten oder indirekten Verlinkungen auf + die Webseiten Dritter, die außerhalb unseres Verantwortungsbereichs liegen, würde eine Haftungsverpflichtung + ausschließlich in dem Fall nur bestehen, wenn wir von den Inhalten Kenntnis erlangen und es uns technisch möglich + und zumutbar wäre, die Nutzung im Falle rechtswidriger Inhalte zu verhindern.

+

Diese Haftungsausschlusserklärung gilt auch innerhalb des eigenen Internetauftrittes „Name Ihrer Domain“ + gesetzten Links und Verweise von Fragestellern, Blogeinträgern, Gästen des Diskussionsforums. Für illegale, + fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung + solcherart dargestellten Informationen entstehen, haftet allein der Diensteanbieter der Seite, auf welche verwiesen + wurde, nicht derjenige, der über Links auf die jeweilige Veröffentlichung lediglich verweist.

+

Werden uns Rechtsverletzungen bekannt, werden die externen Links durch uns unverzüglich entfernt.

+

 

+

Urheberrecht

+

 

+

Die auf unserer Webseite veröffentlichen Inhalte und Werke unterliegen dem deutschen Urheberrecht (http://www.gesetze-im-internet.de/bundesrecht/urhg/gesamt.pdf) + . Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung des geistigen Eigentums in ideeller und + materieller Sicht des Urhebers außerhalb der Grenzen des Urheberrechtes bedürfen der vorherigen schriftlichen + Zustimmung des jeweiligen Urhebers i.S.d. Urhebergesetzes (http://www.gesetze-im-internet.de/bundesrecht/urhg/gesamt.pdf + ). Downloads und Kopien dieser Seite sind nur für den privaten und nicht kommerziellen Gebrauch erlaubt. Sind die + Inhalte auf unserer Webseite nicht von uns erstellt wurden, sind die Urheberrechte Dritter zu beachten. Die Inhalte + Dritter werden als solche kenntlich gemacht. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam + werden, bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige + Inhalte unverzüglich entfernen.

+

Dieses Impressum wurde freundlicherweise von www.jurarat.de zur + Verfügung gestellt.

+ +); +} +export default ImpressTxt; + + diff --git a/src/components/Impressum.css b/src/components/Impressum.css new file mode 100644 index 0000000..d8196ba --- /dev/null +++ b/src/components/Impressum.css @@ -0,0 +1,4 @@ +.underline +{ + text-decoration: underline; +} \ No newline at end of file diff --git a/src/components/Impressum.tsx b/src/components/Impressum.tsx new file mode 100644 index 0000000..69fef34 --- /dev/null +++ b/src/components/Impressum.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import ImpressTxt from './ImpressTxt'; +import './Impressum.css' + +const Impressum = () => +{ + return ( + <> +

Impressum

+ + + ) + + ; +} +export default Impressum; \ No newline at end of file diff --git a/src/components/Login.tsx b/src/components/Login.tsx index 53d2ceb..927b441 100644 --- a/src/components/Login.tsx +++ b/src/components/Login.tsx @@ -38,7 +38,7 @@ const Login = () => { setRedirect('Redirecting...'); setErrMsg(data.message); await getUser(); - e.currentTarget.reset(); + e?.currentTarget?.reset(); return; } setErrMsg(data.message); diff --git a/src/components/Qr.css b/src/components/Qr.css index 31f217a..caa67ef 100644 --- a/src/components/Qr.css +++ b/src/components/Qr.css @@ -23,7 +23,7 @@ img .vertFont { - writing-mode: vertical-lr; + writing-mode: vertical-rl; } .qrCodeVert @@ -47,3 +47,16 @@ img flex-direction: row; flex-wrap: wrap; } + +.order1 +{ + order: 1; +} +.order2 +{ + order: 2; +} +.order3 +{ + order: 3; +} diff --git a/src/components/Qr.tsx b/src/components/Qr.tsx index 21e5e81..3d0bcef 100644 --- a/src/components/Qr.tsx +++ b/src/components/Qr.tsx @@ -1,20 +1,26 @@ -import React, { useContext } from 'react' -import { UserCtx, UserCtxT, DogT } from '../context/UserContext'; +import React, { useContext, useState } from 'react' +import { UserCtx, UserCtxT, DogT, Axios, ResponseT, TUser } from '../context/UserContext'; import Img from './Img'; import './Qr.css'; + export default function Qr() { - const {dog, getDog, user} = useContext(UserCtx) as UserCtxT; - var needData = dog.success === undefined; - if(needData) + const { user } = useContext(UserCtx) as UserCtxT; + const [dog, setDog] = useState({}); // local dog not the dog in UserContext + + if(user && dog.success === undefined) { - if(user) + Axios.post('getDog.php', { - getDog(user?.qr_id); // await not allowed?! => workaraound - } + qr_id: user.qr_id + }) + .then((resDog) => + { + setDog(resDog.data); + }) + .catch((err) => console.error(err)); } - return ( <> @@ -33,57 +39,9 @@ export default function Qr()
- {/*
{dog.data.phone}
-
{dog.data.email}
*/}
{dog.data.name}
-
- - - -
-
-
SCAN ME
- -
-
-
{dog.data.phone}
- {/*
{dog.data.email}
*/} -
{dog.data.name}
-
-
-
-
-
SCAN ME
- -
-
- {/*
{dog.data.phone}
*/} -
{dog.data.email}
-
{dog.data.name}
-
-
- - -
-
-
SCAN ME
- -
-
-
{dog.data.phone}
- {/*
{dog.data.email}
-
{dog.data.name}
*/} -
-
-
-
-
SCAN ME
- -
-
{dog.data.phone}
{dog.data.email}
- {/*
{dog.data.name}
*/}
@@ -94,9 +52,57 @@ export default function Qr()
+
{dog.data.name}
+
{dog.data.phone}
+
{dog.data.email}
+
+ +
+
+
SCAN ME
+ +
+
+
{dog.data.name}
{dog.data.phone}
{dog.data.email}
+
+
+ + +
+
+
SCAN ME
+ +
+
{dog.data.name}
+
{dog.data.phone}
+
{dog.data.email}
+
+
+
+
+
SCAN ME
+ +
+
+
{dog.data.name}
+
{dog.data.phone}
+
{dog.data.email}
+
+
+ + +
+
+
SCAN ME
+ +
+
+
{dog.data.name}
+
{dog.data.phone}
+
{dog.data.email}
diff --git a/src/components/logout.php b/src/components/logout.php deleted file mode 100644 index db82b7b..0000000 --- a/src/components/logout.php +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/src/context/UserContext.tsx b/src/context/UserContext.tsx index 9000912..9a0821b 100644 --- a/src/context/UserContext.tsx +++ b/src/context/UserContext.tsx @@ -41,6 +41,8 @@ export type UserCtxT = { user: TUser | null, + setUser: React.Dispatch>, + 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, diff --git a/src/services/FileUploadService.ts b/src/services/FileUploadService.ts new file mode 100644 index 0000000..7481093 --- /dev/null +++ b/src/services/FileUploadService.ts @@ -0,0 +1,27 @@ +//import http from "../http-common"; + +import { Axios } from '../context/UserContext'; + +const upload = (file: File, onUploadProgress: any): Promise => { + let formData = new FormData(); + + formData.append("file", file); + + return Axios.post("/upload", formData, { + headers: { + "Content-Type": "multipart/form-data", + }, + onUploadProgress, + }); +}; + +const getFiles = () : Promise => { + return Axios.get("/files"); + }; + + const FileUploadService = { + upload, + getFiles, + }; + + export default FileUploadService; \ No newline at end of file diff --git a/src/types/File.ts b/src/types/File.ts new file mode 100644 index 0000000..cd9b156 --- /dev/null +++ b/src/types/File.ts @@ -0,0 +1,5 @@ +export default interface IFile +{ + url: string, + name: string, +} \ No newline at end of file