Add file upload functionality
This commit is contained in:
parent
5e4554710c
commit
f3c3f15f3a
6 changed files with 217 additions and 5 deletions
130
backend/package-lock.json
generated
130
backend/package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// - - - - -
|
||||
|
|
|
@ -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() {
|
|||
{/* <Gamefield/> */}
|
||||
{/* <Homepage/> */}
|
||||
{/* <Homepage2/> */}
|
||||
<SocketIO/>
|
||||
{/* <SocketIO/> */}
|
||||
<Upload />
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
|
|
44
frontend/src/components/Upload.tsx
Normal file
44
frontend/src/components/Upload.tsx
Normal file
|
@ -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<HTMLInputElement>) {
|
||||
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 (
|
||||
<div>
|
||||
<h2>Add Image:</h2>
|
||||
<input type="file" className='inputt' onChange={handleChange} />
|
||||
<img src={file} alt={filename || 'No selection'} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Upload
|
|
@ -187,3 +187,10 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.inputt {
|
||||
background-color: #61dafb;
|
||||
&:hover {
|
||||
background-color: red;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue