diff --git a/backend/package-lock.json b/backend/package-lock.json index 293a724..ccfd1dc 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -13,6 +13,7 @@ "cors": "^2.8.5", "dotenv": "^10.0.0", "express": "^4.17.1", + "formidable": "^2.0.1", "socket.io": "^4.5.3", "uuid": "^8.3.2" }, @@ -21,6 +22,7 @@ "@types/cors": "^2.8.12", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.13", + "@types/formidable": "^2.0.5", "@types/node": "^17.0.0", "@types/uuid": "^8.3.3", "nodemon": "^2.0.15", @@ -166,6 +168,15 @@ "@types/range-parser": "*" } }, + "node_modules/@types/formidable": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.5.tgz", + "integrity": "sha512-uvMcdn/KK3maPOaVUAc3HEYbCEhjaGFwww4EsX6IJfWIJ1tzHtDHczuImH3GKdusPnAAmzB07St90uabZeCKPA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", @@ -268,6 +279,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -472,6 +488,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -642,6 +667,31 @@ "node": ">= 0.8" } }, + "node_modules/formidable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.0.1.tgz", + "integrity": "sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==", + "dependencies": { + "dezalgo": "1.0.3", + "hexoid": "1.0.0", + "once": "1.4.0", + "qs": "6.9.3" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/formidable/node_modules/qs": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz", + "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -733,6 +783,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "engines": { + "node": ">=8" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -996,6 +1054,14 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1440,6 +1506,11 @@ "node": ">= 0.8" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, "node_modules/ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", @@ -1601,6 +1672,15 @@ "@types/range-parser": "*" } }, + "@types/formidable": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.5.tgz", + "integrity": "sha512-uvMcdn/KK3maPOaVUAc3HEYbCEhjaGFwww4EsX6IJfWIJ1tzHtDHczuImH3GKdusPnAAmzB07St90uabZeCKPA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", @@ -1688,6 +1768,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1840,6 +1925,15 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==", + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -1974,6 +2068,24 @@ "unpipe": "~1.0.0" } }, + "formidable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.0.1.tgz", + "integrity": "sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==", + "requires": { + "dezalgo": "1.0.3", + "hexoid": "1.0.0", + "once": "1.4.0", + "qs": "6.9.3" + }, + "dependencies": { + "qs": { + "version": "6.9.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz", + "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==" + } + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2034,6 +2146,11 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, + "hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==" + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -2226,6 +2343,14 @@ "ee-first": "1.1.1" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -2538,6 +2663,11 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, "ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", diff --git a/backend/package.json b/backend/package.json index 2cfe805..8c4a51a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -15,6 +15,7 @@ "cors": "^2.8.5", "dotenv": "^10.0.0", "express": "^4.17.1", + "formidable": "^2.0.1", "socket.io": "^4.5.3", "uuid": "^8.3.2" }, @@ -23,6 +24,7 @@ "@types/cors": "^2.8.12", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.13", + "@types/formidable": "^2.0.5", "@types/node": "^17.0.0", "@types/uuid": "^8.3.3", "nodemon": "^2.0.15", diff --git a/backend/src/index.ts b/backend/src/index.ts index 48458d0..b1a885f 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,6 +1,8 @@ import cors from 'cors'; import dotenv from 'dotenv'; import express from 'express'; +import formidable from 'formidable'; +import { mkdir, rename } from 'fs/promises'; const app = express(); dotenv.config(); @@ -15,8 +17,33 @@ app.listen(+process.env.API_PORT, () => console.log(`Server running on: ${proces app.use(express.json()); app.use(cors({ origin: process.env.CORS_HOST })); -// Register post route -// app.post('/api/register', () => { }); +// File upload post route +app.post('/api/upload', (req, res) => { + const form = new formidable.IncomingForm(); + form.parse(req, (err, fields, files) => { + if (!('filepath' in files.filetoupload) || !files.filetoupload?.filepath) { + res.write('Ups! Missing property "filetoupload" file'); + res.end(); + return; + } + const filename = files.filetoupload.originalFilename + const oldpath = files.filetoupload.filepath + const newdir = process.cwd() + '/upload/' + const newpath = newdir + filename + mkdir(newdir, { recursive: true }) + .then(() => { + return rename(oldpath, newpath) + }) + .then(() => { + console.log('New Upload: ' + filename) + res.write('File uploaded and moved!'); + res.end(); + }) + .catch((err) => { + if (err) throw err; + }) + }); +}); // - - - - - @@ -49,6 +76,6 @@ io.on("connection", (socket) => { console.log("Got test:", payload) // ... }); - + socket.emit('test2', 'lol') }); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a1f6835..bd8f462 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,7 +1,8 @@ // import Gamefield from './components/Gamefield'; // import Homepage from './components/Homepage'; // import Homepage2 from './components/Homepage2'; -import SocketIO from './components/SocketIO'; +// import SocketIO from './components/SocketIO'; +import Upload from './components/Upload'; import './styles/App.scss'; function App() { @@ -13,7 +14,8 @@ function App() { {/* */} {/* */} {/* */} - + {/* */} + ); diff --git a/frontend/src/components/Upload.tsx b/frontend/src/components/Upload.tsx new file mode 100644 index 0000000..1a85fea --- /dev/null +++ b/frontend/src/components/Upload.tsx @@ -0,0 +1,44 @@ +import { useState } from 'react'; + +function Upload() { + const [file, setFile] = useState(''); + const [filename, setFilename] = useState(''); + + // function handleChange + function handleChange(e: React.ChangeEvent) { + console.log(e.target.files); + if (!e.target.files?.length) + return + const file = e.target.files[0] + console.log(URL.createObjectURL(e.target.files[0])) + setFile(URL.createObjectURL(e.target.files[0])); + setFilename(e.target.files[0].name); + + + const url = 'http://localhost:5000/api/upload'; + const formData = new FormData(); + formData.append('filetoupload', file); + + console.log(file) + + const config = { + method: 'POST', + body: formData + }; + + fetch(url, config) + .then((response) => { + console.log(response.body) + }) + .catch(error => console.log(error)) + } + return ( +
+

Add Image:

+ + {filename +
+ ) +} + +export default Upload \ No newline at end of file diff --git a/frontend/src/styles/App.scss b/frontend/src/styles/App.scss index 9bbbcfa..0906523 100644 --- a/frontend/src/styles/App.scss +++ b/frontend/src/styles/App.scss @@ -186,4 +186,11 @@ grid-area: 4 / 4 / -4 / -4; } } +} + +.inputt { + background-color: #61dafb; + &:hover { + background-color: red; + } } \ No newline at end of file