Browse Source

added image upload functionality

master
Danilo Di Cuia 3 years ago
parent
commit
2b562e3495
  1. 12
      public/index.html
  2. 52
      src/Admin.js
  3. 38
      src/App.css
  4. 74
      src/ImageUpload.js
  5. 65
      src/MyForm.js
  6. 53
      src/Proiezione.js
  7. 119
      src/index.js

12
public/index.html

@ -26,18 +26,8 @@
-->
<title>React App</title>
</head>
<body>
<body style="margin: 0">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

52
src/Admin.js

@ -0,0 +1,52 @@
import React, { useEffect, useState } from "react";
import firebase from "firebase/app";
import { Stack } from "@mui/system";
import { CheckboxListSecondary } from "./index";
export const Admin = () => {
const [messaggi, cambiaMessaggi] = useState([]);
useEffect(() => {
// Get a reference to the messages node in the Realtime Database
var messagesRef = firebase.database().ref("/messaggi");
console.log(messagesRef);
messagesRef.on("value", function (snapshot) {
var messaggi = snapshot.val();
console.log(messaggi);
messaggi = Object.keys(messaggi).map((d) => messaggi[d]);
cambiaMessaggi(messaggi);
});
messagesRef.on("child_changed", function (snapshot) {
var messaggio = snapshot.val();
const i = messaggi.findIndex((m) => messaggio.timestamp === m.timestamp);
});
}, []);
let element;
if (!messaggi.length) {
element = <div>nessun messaggio</div>;
} else {
element = (
<CheckboxListSecondary
messaggi={messaggi}
onChecked={(m) => {
firebase
.database()
.ref("messaggi/" + m.id)
.update({
approvato: !m.approvato,
});
}}
/>
);
}
return (
<Stack>
<h2>Admin</h2>
{element}
</Stack>
);
};

38
src/App.css

@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

74
src/ImageUpload.js

@ -1,9 +1,15 @@
import React, { useState } from "react";
import { storage, firestore } from "firebase/app";
import firebase from "firebase/app";
import "firebase/storage";
import "firebase/firestore";
import { Stack } from "@mui/system";
function ImageUpload() {
const IDLE = 0;
const IMAGE_SET = 1;
const UPLOADING = 2;
const DONE = 3;
function ImageUpload({ onImageURLSet }) {
const [state, setState] = useState();
const [image, setImage] = useState(null);
const [imageUrl, setImageUrl] = useState("");
const [progress, setProgress] = useState(0);
@ -11,11 +17,17 @@ function ImageUpload() {
const handleChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
setState(1);
}
};
const handleUpload = () => {
const uploadTask = storage.ref(`images/${image.name}`).put(image);
const uploadTask = firebase
.storage()
.ref(`images/${image.name}`)
.put(image);
setState(2);
uploadTask.on(
"state_changed",
@ -29,34 +41,64 @@ function ImageUpload() {
console.log(error);
},
() => {
storage
firebase
.storage()
.ref("images")
.child(image.name)
.getDownloadURL()
.then((url) => {
setImageUrl(url);
firestore()
.collection("images")
.add({
imageUrl,
createdAt: new Date(),
})
.then(() => {
setProgress(0);
setImage(null);
});
onImageURLSet(url);
setState(3);
});
}
);
};
return (
let componente;
switch (state) {
default:
case IDLE:
componente = <input type="file" onChange={handleChange} />;
break;
case IMAGE_SET:
componente = (
<Stack>
<img style={{ width: 200 }} src={URL.createObjectURL(image)} />
<Stack spacing={2} direction="row">
<button
onClick={() => {
setState(IDLE);
}}
>
annulla
</button>
<button onClick={handleUpload}>carica</button>
</Stack>
</Stack>
);
break;
case UPLOADING:
componente = (
<div>
<input type="file" onChange={handleChange} />
<button onClick={handleUpload}>Upload</button>
<img style={{ width: 200 }} src={image.src} />
<progress value={progress} max="100" />
</div>
);
break;
case DONE:
componente = (
<div>
<img style={{ width: 200 }} src={imageUrl} />
</div>
);
}
return <Stack>{componente}</Stack>;
}
export default ImageUpload;

65
src/MyForm.js

@ -0,0 +1,65 @@
import React, { useState } from "react";
import firebase from "firebase/app";
import TextField from "@mui/material/TextField";
import { Container, Stack } from "@mui/system";
import { Button } from "@mui/material";
import { useForm } from "react-hook-form";
import Countdown from "./Countdown";
import ImageUpload from "./ImageUpload";
export const MyForm = () => {
const [mandato, cambiaMandato] = useState(false);
const [immagineURL, cambiaimmagineURL] = useState(null);
const { register, handleSubmit } = useForm();
const onSubmit = ({ testo, autore }) => {
cambiaMandato(true);
var postListRef = firebase.database().ref("messaggi");
var newPostRef = postListRef.push();
const update = {
id: newPostRef.key,
autore,
testo,
timestamp: firebase.database.ServerValue.TIMESTAMP,
approvato: true,
};
if (immagineURL) update.immagineURL = immagineURL;
newPostRef.set(update);
};
const onImageURLSet = (url) => {
cambiaimmagineURL(url);
};
if (mandato) {
return (
<Stack>
<div>mandato e mo aspetti</div>
<Countdown onComplete={() => cambiaMandato(false)} duration={5} />
</Stack>
);
}
return (
<Container maxWidth="sm" style={{ marginTop: 100 }}>
<form onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={2}>
<ImageUpload onImageURLSet={onImageURLSet} />
<TextField
{...register("testo", { required: true, maxLength: 20 })}
id="outlined-basic"
label="messaggio"
variant="outlined"
/>
<TextField
{...register("autore", { pattern: /^[A-Za-z]+$/i })}
id="outlined-basic"
label="da"
variant="outlined"
/>
<Button type="submit" variant="contained">
manda
</Button>
</Stack>
</form>
</Container>
);
};

53
src/Proiezione.js

@ -1,9 +1,12 @@
import React, { useEffect, useState } from "react";
import firebase from "firebase/app";
import { Button } from "@mui/material";
import { MyForm, Admin } from "./index";
import { Button, Grid } from "@mui/material";
import { Admin } from "./Admin";
import { MyForm } from "./MyForm";
import { useInterval } from "./Countdown";
window.debug = false;
export const Proiezione = () => {
const [messaggi, cambiaMessaggi] = useState([]);
const [messaggiApprovati, cambiaMessaggiApprovati] = useState([]);
@ -14,6 +17,7 @@ export const Proiezione = () => {
messagesRef.on("child_added", function (snapshot) {
var messaggio = snapshot.val();
console.log(messaggio);
cambiaMessaggi((oldArray) => {
const newArray = [...oldArray, messaggio].sort(
(a, b) => b.timestamp - a.timestamp
@ -44,7 +48,7 @@ export const Proiezione = () => {
const ContainerMessaggio = () => {
if (!messaggiApprovati.length) {
<div>nessun messaggio</div>;
return <div>nessun messaggio</div>;
} else {
const messaggioCorrente = messaggiApprovati[indiceCorrente];
@ -59,17 +63,43 @@ export const Proiezione = () => {
return (
<div>
<MyForm />
<Grid
style={{
width: "100%",
height: "100vh",
background: "black",
fontFamily: "sans-serif",
fontWeight: "bold",
color: "white",
display: "flex",
justifyContent: "space-around",
alignContent: "center",
alignItems: "center",
textAlign: "center",
}}
>
<ContainerMessaggio />
<Admin />
</Grid>
</div>
);
};
const Immagine = ({ url }) => {
return (
<div
style={{
height: 400,
width: 400,
borderRadius: "50%",
backgroundSize: "cover",
backgroundImage: `url("${url}")`,
backgroundPositionX: "center",
}}
></div>
);
};
const Messaggio = ({ nextMessage, messaggioCorrente }) => {
const [timeLeft, setTimeLeft] = useState(5);
// Decrement the timer by 1 second every 1000ms
useInterval(() => {
if (timeLeft === 1) {
nextMessage();
@ -78,13 +108,20 @@ const Messaggio = ({ nextMessage, messaggioCorrente }) => {
}
}, 1000);
console.log("asdf");
return (
<div>
{messaggioCorrente.immagineURL && (
<Immagine url={messaggioCorrente.immagineURL} />
)}
<h1>{messaggioCorrente.testo}</h1>
<p>da {messaggioCorrente.autore}</p>
{debug && (
<div>
<Button onClick={() => nextMessage()}>next</Button>
{timeLeft}
</div>
)}
</div>
);
};

119
src/index.js

@ -1,13 +1,8 @@
import React, { useEffect, useState } from "react";
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import firebase from "firebase/app";
import "firebase/database";
import TextField from "@mui/material/TextField";
import { Stack } from "@mui/system";
import { Button } from "@mui/material";
import { useForm } from "react-hook-form";
import Countdown from "./Countdown";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
@ -15,69 +10,23 @@ import ListItemButton from "@mui/material/ListItemButton";
import ListItemText from "@mui/material/ListItemText";
import Checkbox from "@mui/material/Checkbox";
import { Proiezione } from "./Proiezione";
export const MyForm = () => {
const [mandato, cambiaMandato] = useState(false);
const { register, handleSubmit } = useForm();
const onSubmit = ({ testo, autore }) => {
var postListRef = firebase.database().ref("messaggi");
var newPostRef = postListRef.push();
console.log(newPostRef.key);
newPostRef.set({
id: newPostRef.key,
autore,
testo,
timestamp: firebase.database.ServerValue.TIMESTAMP,
approvato: true,
});
cambiaMandato(true);
};
if (mandato) {
return (
<Stack>
<div>mandato e mo aspetti</div>
<Countdown onComplete={() => cambiaMandato(false)} duration={5} />
</Stack>
);
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={2}>
<TextField
{...register("testo", { required: true, maxLength: 20 })}
id="outlined-basic"
label="messaggio"
variant="outlined"
/>
<TextField
{...register("autore", { pattern: /^[A-Za-z]+$/i })}
id="outlined-basic"
label="da"
variant="outlined"
/>
<Button type="submit" variant="contained">
manda
</Button>
</Stack>
</form>
);
};
import { MyForm } from "./MyForm";
import { Admin } from "./Admin";
const firebaseConfig = {
apiKey: "AIzaSyASAEVOTQ38EmRoelz9qGiF6QsqpBOuU_k",
authDomain: "messaggi-letsswing.firebaseapp.com",
apiKey: "AIzaSyBWE1l8WV_7eyKT-PMu0Kq2w_WiV0SUhJw",
authDomain: "messaggiswing.firebaseapp.com",
projectId: "messaggiswing",
storageBucket: "messaggiswing.appspot.com",
messagingSenderId: "983131964310",
appId: "1:983131964310:web:5ef430e42c42d2dfe253b7",
databaseURL:
"https://messaggi-letsswing-default-rtdb.europe-west1.firebasedatabase.app",
projectId: "messaggi-letsswing",
storageBucket: "messaggi-letsswing.appspot.com",
messagingSenderId: "154307951524",
appId: "1:154307951524:web:f320027fb89982a3f05f31",
"https://messaggiswing-default-rtdb.europe-west1.firebasedatabase.app",
};
firebase.initializeApp(firebaseConfig);
function CheckboxListSecondary({ messaggi, onChecked }) {
export function CheckboxListSecondary({ messaggi, onChecked }) {
return (
<List
dense
@ -111,54 +60,10 @@ function CheckboxListSecondary({ messaggi, onChecked }) {
);
}
export const Admin = () => {
const [messaggi, cambiaMessaggi] = useState([]);
const [indiceCorrente, cambiaindiceCorrente] = useState(0);
useEffect(() => {
// Get a reference to the messages node in the Realtime Database
var messagesRef = firebase.database().ref("/messaggi");
messagesRef.on("value", function (snapshot) {
var messaggi = snapshot.val();
messaggi = Object.keys(messaggi).map((d) => messaggi[d]);
cambiaMessaggi(messaggi);
});
messagesRef.on("child_changed", function (snapshot) {
var messaggio = snapshot.val();
const i = messaggi.findIndex((m) => messaggio.timestamp === m.timestamp);
});
}, []);
if (!messaggi.length) return <div>nessun messaggio</div>;
return (
<Stack>
<hr />
<CheckboxListSecondary
messaggi={messaggi}
onChecked={(m) => {
firebase
.database()
.ref("messaggi/" + m.id)
.update({
approvato: !m.approvato,
});
}}
/>
</Stack>
);
};
const Input = () => {
return <div> Input </div>;
};
ReactDOM.createRoot(document.getElementById("root")).render(
<Router>
<Routes>
<Route path="/" element={<Input />} />
<Route path="/" element={<MyForm />} />
<Route path="proiezione" element={<Proiezione />} />
<Route path="admin" element={<Admin />} />
</Routes>

Loading…
Cancel
Save