📦 NEW: Ajout de chronometerTimer

This commit is contained in:
Divlo 2020-04-29 18:51:30 +02:00
parent b21d410a88
commit 075d455fbd
7 changed files with 176 additions and 3 deletions

3
.github/backup.sql vendored
View File

@ -20,4 +20,5 @@ INSERT INTO `functions` (`id`, `title`, `slug`, `description`, `image`, `type`,
(11, 'Heap\'s algorithm', 'heapAlgorithm', 'Génère toutes les permutations uniques possibles d\'une chaîne de caractère.', '/images/functions/heapAlgorithm.png', 'form', NULL, '[{\"name\": \"string\", \"type\": \"text\", \"label\": \"Entrez un mot :\", \"placeholder\": \"(e.g : Mot)\"}]', 1, '2019-10-11 00:01:00', '2020-04-22 23:06:15', 2), (11, 'Heap\'s algorithm', 'heapAlgorithm', 'Génère toutes les permutations uniques possibles d\'une chaîne de caractère.', '/images/functions/heapAlgorithm.png', 'form', NULL, '[{\"name\": \"string\", \"type\": \"text\", \"label\": \"Entrez un mot :\", \"placeholder\": \"(e.g : Mot)\"}]', 1, '2019-10-11 00:01:00', '2020-04-22 23:06:15', 2),
(12, 'Raccourcisseurs de liens', 'linkShortener', 'Une URL trop longue ? Raccourcissez-là !', '/images/functions/linkShortener.png', 'form', NULL, '[{\"name\": \"url\", \"type\": \"text\", \"label\": \"Entrez le lien à raccourcir :\", \"placeholder\": \"(e.g : https://divlo.fr)\"}, {\"name\": \"shortcutName\", \"type\": \"text\", \"label\": \"Entrez le nom du raccourci :\", \"placeholder\": \"(e.g : divlo)\"}]', 1, '2019-12-11 00:00:00', '2020-04-27 16:31:38', 1), (12, 'Raccourcisseurs de liens', 'linkShortener', 'Une URL trop longue ? Raccourcissez-là !', '/images/functions/linkShortener.png', 'form', NULL, '[{\"name\": \"url\", \"type\": \"text\", \"label\": \"Entrez le lien à raccourcir :\", \"placeholder\": \"(e.g : https://divlo.fr)\"}, {\"name\": \"shortcutName\", \"type\": \"text\", \"label\": \"Entrez le nom du raccourci :\", \"placeholder\": \"(e.g : divlo)\"}]', 1, '2019-12-11 00:00:00', '2020-04-27 16:31:38', 1),
(13, 'Liste de choses à faire', 'toDoList', 'Prévoyez la liste de choses que vous devez faire.', '/images/functions/toDoList.png', 'page', NULL, NULL, 1, '2019-12-26 00:00:00', '2020-04-27 16:34:34', 1), (13, 'Liste de choses à faire', 'toDoList', 'Prévoyez la liste de choses que vous devez faire.', '/images/functions/toDoList.png', 'page', NULL, NULL, 1, '2019-12-26 00:00:00', '2020-04-27 16:34:34', 1),
(14, 'Juste Prix', 'rightPrice', 'Arriverez-vous à deviner le prix d\'un objet ?', '/images/functions/rightPrice.png', 'page', NULL, NULL, 1, '2020-04-27 20:17:05', '2020-04-27 21:59:22', 3); (14, 'Juste Prix', 'rightPrice', 'Arriverez-vous à deviner le prix d\'un objet ?', '/images/functions/rightPrice.png', 'page', NULL, NULL, 1, '2020-04-27 20:17:05', '2020-04-27 21:59:22', 3),
(15, 'Chronomètre', 'chronometerTimer', 'Gérer votre temps facilement (et adopter la technique Pomodoro).', '/images/functions/chronometerTimer.png', 'page', NULL, NULL, 1, '2020-04-29 09:28:08', '2020-04-29 09:45:29', 1);

View File

@ -8594,6 +8594,14 @@
"prop-types": "^15.6.2" "prop-types": "^15.6.2"
} }
}, },
"react-codepen-embed": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/react-codepen-embed/-/react-codepen-embed-1.0.1.tgz",
"integrity": "sha512-Lqi9uNimI4s8pGpCNU/NuP/UFscFSdgeYXfLLJym8NmzzyUt5Gbwwbkvzfp5UYj24S31eW1eClewhe5W+STULA==",
"requires": {
"prop-types": "^15.5.0"
}
},
"react-color": { "react-color": {
"version": "2.18.0", "version": "2.18.0",
"resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.0.tgz", "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.0.tgz",

View File

@ -23,6 +23,7 @@
"notyf": "^3.6.0", "notyf": "^3.6.0",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"react": "16.13.0", "react": "16.13.0",
"react-codepen-embed": "^1.0.1",
"react-color": "^2.18.0", "react-color": "^2.18.0",
"react-datepicker": "^2.14.1", "react-datepicker": "^2.14.1",
"react-dom": "16.13.0", "react-dom": "16.13.0",

View File

@ -0,0 +1,126 @@
import { useState } from 'react';
import Codepen from "react-codepen-embed";
import redirect from '../../utils/redirect';
import FunctionPage from '../../components/FunctionPage/FunctionPage';
import FunctionTabs from '../../components/FunctionPage/FunctionTabs';
import FunctionArticle from '../../components/FunctionPage/FunctionArticle';
import FunctionComments from '../../components/FunctionPage/FunctionComments/FunctionComments';
import Loader from '../../components/Loader';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlay, faPause, faSync } from '@fortawesome/free-solid-svg-icons';
import api from '../../utils/api';
import '../../public/css/pages/FunctionComponent.css';
import '../../components/FunctionCard/FunctionCard.css';
import '../../public/css/pages/functions/chronometerTimer.css';
let interval;
function convertSeconds(seconds) {
return {
minutes: Math.floor(seconds / 60),
seconds: seconds % 60
}
}
const Chronometer = () => {
const [timeLength, setTimeLength] = useState(0); // seconds
const [isPlaying, setIsPlaying] = useState(false);
const handlePlayPause = () => {
if (isPlaying) {
clearInterval(interval);
} else {
if (interval) clearInterval(interval);
interval = setInterval(() => {
setTimeLength((time) => time + 1);
}, 1000);
}
setIsPlaying(!isPlaying);
}
const handleReset = () => {
if (interval) clearInterval(interval);
setIsPlaying(false);
setTimeLength(0);
}
const getFormattedValue = () => {
const minutesAndSeconds = convertSeconds(timeLength);
const minutes = (minutesAndSeconds.minutes < 100) ? (('0'+minutesAndSeconds.minutes).slice(-2)) : minutesAndSeconds.minutes;
const seconds = ('0'+minutesAndSeconds.seconds).slice(-2);
return `${minutes}:${seconds}`;
}
return(
<div className="container-fluid">
<div className="row justify-content-center">
<div className="col-sm-24 col-md-12">
<div className="Chronometer__container">
<div className="Chronometer__item">
<div className="Chronomter__row">
<div className="Chronometer__time-left">
{/* 25:00 */}
{getFormattedValue()}
</div>
</div>
</div>
<div className="Chronometer__item Chronometer__buttons">
<div className="Chronomter__row Chronometer__row-button">
<button onClick={handlePlayPause} className="Chronometer-btn">
<FontAwesomeIcon { ...(isPlaying) ? { icon: faPause } : { icon: faPlay } } />
</button>
<button onClick={handleReset} className="Chronometer-btn" title="Remettre à zéro ?">
<FontAwesomeIcon icon={faSync} />
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
const Pomodoro = () => {
return (
<div style={{ marginBottom: '50px' }} className="container-fluid">
<Codepen hash="vYEbPoB" user="Divlo" height={800} defaultTab="result" preview={false} loader={() => <Loader />} />
</div>
);
}
const FunctionTabManager = (props) => {
return (
<FunctionTabs setSlideIndex={props.setSlideIndex} slideIndex={props.slideIndex}>
<div className="FunctionComponent__slide">
<Chronometer />
</div>
<div className="FunctionComponent__slide">
<Pomodoro />
</div>
<div className="FunctionComponent__slide">
<FunctionArticle article={props.article} />
</div>
<div className="FunctionComponent__slide">
<FunctionComments functionId={props.id} />
</div>
</FunctionTabs>
);
}
const chronometerTimer = (props) => (
<FunctionPage
FunctionTabManager={FunctionTabManager}
{ ...props }
tabNames={["⏰ Chronomètre", "⌛ Pomodoro", "📝 Article", "📬 Commentaires"]}
/>
);
export async function getServerSideProps(context) {
return api.get(`/functions/chronometerTimer`)
.then((response) => ({ props: response.data }))
.catch(() => redirect(context, '/404'));
}
export default chronometerTimer;

View File

@ -7,7 +7,6 @@ import FunctionComments from '../../components/FunctionPage/FunctionComments/Fun
import Loader from '../../components/Loader'; import Loader from '../../components/Loader';
import api from '../../utils/api'; import api from '../../utils/api';
import '../../public/css/pages/FunctionComponent.css'; import '../../public/css/pages/FunctionComponent.css';
import '../../public/css/pages/functions/toDoList.css';
import '../../components/FunctionCard/FunctionCard.css'; import '../../components/FunctionCard/FunctionCard.css';
import '../../public/css/pages/functions/rightPrice.css'; import '../../public/css/pages/functions/rightPrice.css';

View File

@ -10,8 +10,8 @@ import FunctionArticle from '../../components/FunctionPage/FunctionArticle';
import FunctionComments from '../../components/FunctionPage/FunctionComments/FunctionComments'; import FunctionComments from '../../components/FunctionPage/FunctionComments/FunctionComments';
import api from '../../utils/api'; import api from '../../utils/api';
import '../../public/css/pages/FunctionComponent.css'; import '../../public/css/pages/FunctionComponent.css';
import '../../public/css/pages/functions/toDoList.css';
import '../../components/FunctionCard/FunctionCard.css'; import '../../components/FunctionCard/FunctionCard.css';
import '../../public/css/pages/functions/toDoList.css';
const ManageToDo = () => { const ManageToDo = () => {

View File

@ -0,0 +1,38 @@
.Chronometer__container {
display: flex;
flex-flow: row wrap;
box-shadow: 0px 0px 6px 6px rgba(0, 0, 0, .25);
border: 1px solid black;
border-radius: 1rem;
padding: 20px;
margin-bottom: 40px;
}
.Chronometer__item {
width: 100%;
}
.Chronomter__row {
margin: 8px 0 16px 0;
text-align: center;
}
.Chronometer__time-left {
font-size: 3rem;
font-weight: 700;
}
.Chronometer__buttons {
border-top: solid 3px var(--important);
padding-top: 12px;
}
.Chronometer__row-button {
display: flex;
justify-content: center;
}
.Chronometer-btn {
color: var(--text-color);
cursor: pointer;
background-color: transparent;
border: none;
outline: none;
margin-left: 14px;
margin-right: 14px;
width: 2em;
}