Browse Source

ciao bellezza

master
Matteo Benedetto 3 years ago
parent
commit
8e3213bdbd
  1. 2243
      package-lock.json
  2. 9
      package.json
  3. 25
      src/App.js
  4. 48
      src/Countdown.js
  5. 243
      src/index.js

2243
package-lock.json generated

File diff suppressed because it is too large Load Diff

9
package.json

@ -3,12 +3,21 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mui/material": "^5.11.1",
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"firebase": "^8.10.1",
"localforage": "^1.10.0",
"match-sorter": "^6.3.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hook-form": "^7.41.0",
"react-router-dom": "^6.6.1",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"sort-by": "^1.2.0",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {

25
src/App.js

@ -1,25 +0,0 @@
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;

48
src/Countdown.js

@ -0,0 +1,48 @@
import { useEffect, useRef, useState } from "react";
function useInterval(callback, delay) {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
function Countdown({ duration, onComplete }) {
// Initialize the countdown timer with the duration prop
const [timeLeft, setTimeLeft] = useState(duration);
// Decrement the timer by 1 second every 1000ms
useInterval(() => {
if(timeLeft === 1) {
onComplete()
} else{
setTimeLeft(timeLeft - 1);
}
}, 1000);
// Return the time left formatted as minutes and seconds
let minutes = Math.floor(timeLeft / 60);
let seconds = timeLeft % 60;
return (
<div>{seconds}
</div>
);
}
export default Countdown

243
src/index.js

@ -1,17 +1,226 @@
import React from 'react'; import React, { useEffect, useState } from "react";
import ReactDOM from 'react-dom/client'; import ReactDOM from "react-dom/client";
import './index.css'; import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import App from './App'; import firebase from "firebase/app";
import reportWebVitals from './reportWebVitals'; import "firebase/database";
import TextField from "@mui/material/TextField";
const root = ReactDOM.createRoot(document.getElementById('root')); import { Stack } from "@mui/system";
root.render( import { Button } from "@mui/material";
<React.StrictMode> import { useForm } from "react-hook-form";
<App /> import Countdown from "./Countdown";
</React.StrictMode>
); import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
// If you want to start measuring performance in your app, pass a function import ListItemButton from "@mui/material/ListItemButton";
// to log results (for example: reportWebVitals(console.log)) import ListItemText from "@mui/material/ListItemText";
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals import Checkbox from "@mui/material/Checkbox";
reportWebVitals();
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>
);
};
const firebaseConfig = {
apiKey: "AIzaSyASAEVOTQ38EmRoelz9qGiF6QsqpBOuU_k",
authDomain: "messaggi-letsswing.firebaseapp.com",
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",
};
firebase.initializeApp(firebaseConfig);
function CheckboxListSecondary({ messaggi, onChecked }) {
return (
<List
dense
sx={{ width: "100%", maxWidth: 360, bgcolor: "background.paper" }}
>
{messaggi.map((m) => {
const labelId = `checkbox-list-secondary-label-${m.timestamp}`;
return (
<ListItem
key={m.timestamp}
secondaryAction={
<Checkbox
edge="end"
onChange={() => onChecked(m)}
checked={m.approvato}
inputProps={{ "aria-labelledby": labelId }}
/>
}
disablePadding
>
<ListItemButton>
<ListItemText
id={labelId}
primary={`"${m.testo}" da ${m.autore}`}
/>
</ListItemButton>
</ListItem>
);
})}
</List>
);
}
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 Proiezione = () => {
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("child_added", function (snapshot) {
var messaggio = snapshot.val();
cambiaMessaggi((oldArray) =>
[...oldArray, messaggio].sort((a, b) => b.timestamp - a.timestamp)
);
});
messagesRef.on("child_changed", function (snapshot) {
var messaggio = snapshot.val();
cambiaMessaggi((oldArray) => {
var nuoviMessaggi = [...oldArray];
var nuovoIndice = oldArray.findIndex((d) => d.id === messaggio.id);
if (nuovoIndice != -1) {
nuoviMessaggi[nuovoIndice] = messaggio;
}
return nuoviMessaggi;
});
});
}, []);
const nextMessage = (i) => {
if(i === indiceCorrente) return
let nuovoIndice = (i + 1) % messaggi.length;
if (!messaggi[nuovoIndice].approvato) {
nextMessage(nuovoIndice);
} else {
cambiaindiceCorrente(nuovoIndice)
}
};
const messaggioCorrente = messaggi[indiceCorrente];
return (
<div>
<MyForm />
{!messaggi.filter((m) => m.approvato).length && (
<div>nessun messaggio</div>
)}
{messaggi.filter((m) => m.approvato).length && (
<div>
<h1>{messaggioCorrente.testo}</h1>
<p>da {messaggioCorrente.autore}</p>
</div>
)}
<Button onClick={()=>nextMessage(indiceCorrente)}>next</Button>
<Admin />
</div>
);
};
const Input = () => {
return <div> Input </div>;
};
ReactDOM.createRoot(document.getElementById("root")).render(
<Router>
<Routes>
<Route path="/" element={<Input />} />
<Route path="proiezione" element={<Proiezione />} />
<Route path="admin" element={<Admin />} />
</Routes>
</Router>
);

Loading…
Cancel
Save