allaw-ui 2.5.5 → 2.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -6,5 +6,5 @@ export type BillingCountProps = {
|
|
|
6
6
|
resetTimer?: boolean;
|
|
7
7
|
pauseTimer?: boolean;
|
|
8
8
|
};
|
|
9
|
-
declare const BillingCount: ({ onEnd, setIsStarted,
|
|
9
|
+
declare const BillingCount: ({ onEnd, setIsStarted, resetTimer, pauseTimer, }: BillingCountProps) => React.JSX.Element;
|
|
10
10
|
export default BillingCount;
|
|
@@ -2,145 +2,156 @@ import React, { useEffect, useState, useRef } from "react";
|
|
|
2
2
|
import "./BillingCount.css";
|
|
3
3
|
var LOCAL_STORAGE_KEYS = {
|
|
4
4
|
START_TIME: "startTimeBilling",
|
|
5
|
-
|
|
5
|
+
ACCUMULATED_TIME: "accumulatedTime",
|
|
6
6
|
IS_RUNNING: "isRunning",
|
|
7
|
+
HAS_STARTED_BEFORE: "hasStartedBefore",
|
|
7
8
|
};
|
|
8
9
|
var BillingCount = function (_a) {
|
|
9
|
-
var onEnd = _a.onEnd, setIsStarted = _a.setIsStarted,
|
|
10
|
-
var _b = useState(0),
|
|
11
|
-
var _c = useState(false),
|
|
12
|
-
var _d = useState(false), isRunning = _d[0], setIsRunning = _d[1];
|
|
13
|
-
var _e = useState(false), isInitialized = _e[0], setIsInitialized = _e[1];
|
|
10
|
+
var onEnd = _a.onEnd, setIsStarted = _a.setIsStarted, resetTimer = _a.resetTimer, pauseTimer = _a.pauseTimer;
|
|
11
|
+
var _b = useState(0), elapsedSeconds = _b[0], setElapsedSeconds = _b[1];
|
|
12
|
+
var _c = useState(false), isRunning = _c[0], setIsRunning = _c[1];
|
|
14
13
|
var intervalRef = useRef(null);
|
|
14
|
+
// --- Au premier render, on relit le localStorage
|
|
15
15
|
useEffect(function () {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (!isInitialized)
|
|
23
|
-
return;
|
|
24
|
-
if (resetTimer)
|
|
25
|
-
setTime(0);
|
|
26
|
-
setIsPaused(false);
|
|
27
|
-
setIsRunning(false);
|
|
28
|
-
clearTimerData();
|
|
29
|
-
if (intervalRef.current) {
|
|
30
|
-
clearInterval(intervalRef.current);
|
|
16
|
+
var savedAccumulated = getAccumulatedTime();
|
|
17
|
+
var savedIsRunning = localStorage.getItem(LOCAL_STORAGE_KEYS.IS_RUNNING) === "true";
|
|
18
|
+
var savedStartTime = getStartTime();
|
|
19
|
+
var hasStartedBefore = localStorage.getItem(LOCAL_STORAGE_KEYS.HAS_STARTED_BEFORE) === "true"; // ✅ Vérifier si un chrono a déjà été utilisé
|
|
20
|
+
if (savedAccumulated > 0) {
|
|
21
|
+
setElapsedSeconds(savedAccumulated);
|
|
31
22
|
}
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
if (hasStartedBefore && savedIsRunning && savedStartTime > 0) {
|
|
24
|
+
// ✅ Reprendre seulement si le chrono a déjà été lancé au moins une fois
|
|
25
|
+
setIsRunning(true);
|
|
26
|
+
setIsStarted && setIsStarted(true);
|
|
34
27
|
}
|
|
35
|
-
else
|
|
36
|
-
|
|
28
|
+
else {
|
|
29
|
+
// ✅ Ne pas démarrer automatiquement si aucun chrono n'a été lancé
|
|
30
|
+
setIsRunning(false);
|
|
31
|
+
setIsStarted && setIsStarted(false);
|
|
37
32
|
}
|
|
38
|
-
}, [
|
|
33
|
+
}, [setIsStarted]);
|
|
34
|
+
// --- Gère l'interval pour mettre à jour l'affichage
|
|
39
35
|
useEffect(function () {
|
|
40
|
-
if (isRunning
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return newElapsedTime;
|
|
46
|
-
});
|
|
36
|
+
if (isRunning) {
|
|
37
|
+
// Créé un interval toutes les 1000ms
|
|
38
|
+
intervalRef.current = window.setInterval(function () {
|
|
39
|
+
var newElapsed = computeElapsedTime(); // on recalcule via Date.now()
|
|
40
|
+
setElapsedSeconds(newElapsed);
|
|
47
41
|
}, 1000);
|
|
48
42
|
}
|
|
49
43
|
else if (intervalRef.current) {
|
|
44
|
+
// On stoppe l'interval
|
|
50
45
|
clearInterval(intervalRef.current);
|
|
51
46
|
intervalRef.current = null;
|
|
52
47
|
}
|
|
48
|
+
// Cleanup si le composant se démonte
|
|
53
49
|
return function () {
|
|
54
50
|
if (intervalRef.current)
|
|
55
51
|
clearInterval(intervalRef.current);
|
|
56
52
|
};
|
|
57
|
-
}, [isRunning
|
|
53
|
+
}, [isRunning]);
|
|
54
|
+
// --- Sur changement de resetTimer/pauseTimer
|
|
55
|
+
// on applique la logique de reset, de pause ou de start
|
|
58
56
|
useEffect(function () {
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
var hasStartedBefore = localStorage.getItem(LOCAL_STORAGE_KEYS.HAS_STARTED_BEFORE) === "true";
|
|
58
|
+
var savedAccumulated = getAccumulatedTime();
|
|
61
59
|
if (resetTimer) {
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
else if (!pauseTimer && !resetTimer) {
|
|
65
|
-
startTimerHandler();
|
|
60
|
+
resetTimerHandler();
|
|
66
61
|
}
|
|
67
62
|
else if (pauseTimer) {
|
|
68
63
|
pauseTimerHandler();
|
|
69
64
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
setTime(savedElapsedTime);
|
|
76
|
-
if (savedIsRunning && savedElapsedTime > 0) {
|
|
77
|
-
setIsRunning(true);
|
|
78
|
-
setIsStarted && setIsStarted(true);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
setIsRunning(false);
|
|
82
|
-
setIsStarted && setIsStarted(false);
|
|
83
|
-
}
|
|
84
|
-
}, [setIsStarted]);
|
|
85
|
-
// Mise a jour du temps de session
|
|
86
|
-
var updateElapsedTime = function (elapsedTime) {
|
|
87
|
-
localStorage.setItem(LOCAL_STORAGE_KEYS.ELAPSED_TIME, elapsedTime.toString());
|
|
88
|
-
};
|
|
89
|
-
// Cleanup du localStorage après un reset de session de travail
|
|
90
|
-
var clearTimerData = function () {
|
|
91
|
-
localStorage.removeItem(LOCAL_STORAGE_KEYS.START_TIME);
|
|
92
|
-
localStorage.removeItem(LOCAL_STORAGE_KEYS.ELAPSED_TIME);
|
|
93
|
-
localStorage.removeItem(LOCAL_STORAGE_KEYS.IS_RUNNING);
|
|
94
|
-
};
|
|
95
|
-
var getSavedElapsedTime = function () {
|
|
96
|
-
return parseInt(localStorage.getItem(LOCAL_STORAGE_KEYS.ELAPSED_TIME) || "0", 10);
|
|
97
|
-
};
|
|
98
|
-
var getCurrentElapsedTime = function () {
|
|
99
|
-
var savedStartTime = localStorage.getItem(LOCAL_STORAGE_KEYS.START_TIME);
|
|
100
|
-
if (savedStartTime) {
|
|
101
|
-
return getSavedElapsedTime();
|
|
65
|
+
else if (!pauseTimer && !resetTimer) {
|
|
66
|
+
// ⚠️ Ne lance le chrono que s'il est déjà en cours ou s'il y a du temps accumulé
|
|
67
|
+
if (hasStartedBefore && savedAccumulated > 0) {
|
|
68
|
+
startTimerHandler();
|
|
69
|
+
}
|
|
102
70
|
}
|
|
103
|
-
|
|
71
|
+
}, [resetTimer, pauseTimer]);
|
|
72
|
+
// --- Fonctions utilitaires ---
|
|
73
|
+
// Calcule la différence en s'appuyant sur:
|
|
74
|
+
// accumulatedTime (secondes) + (Date.now() - startTime) / 1000
|
|
75
|
+
var computeElapsedTime = function () {
|
|
76
|
+
var savedStartTime = getStartTime();
|
|
77
|
+
var savedAccumulated = getAccumulatedTime();
|
|
78
|
+
if (!savedStartTime)
|
|
79
|
+
return savedAccumulated;
|
|
80
|
+
var now = Date.now();
|
|
81
|
+
var diffSeconds = Math.floor((now - savedStartTime) / 1000);
|
|
82
|
+
return savedAccumulated + diffSeconds;
|
|
104
83
|
};
|
|
84
|
+
// On lance ou relance le chrono
|
|
105
85
|
var startTimerHandler = function () {
|
|
106
|
-
|
|
107
|
-
|
|
86
|
+
var isRunningFlag = localStorage.getItem(LOCAL_STORAGE_KEYS.IS_RUNNING) === "true";
|
|
87
|
+
if (!isRunningFlag) {
|
|
88
|
+
// ✅ Indiquer que le chrono a été démarré au moins une fois
|
|
89
|
+
localStorage.setItem(LOCAL_STORAGE_KEYS.HAS_STARTED_BEFORE, "true");
|
|
90
|
+
localStorage.setItem(LOCAL_STORAGE_KEYS.START_TIME, Date.now().toString());
|
|
108
91
|
localStorage.setItem(LOCAL_STORAGE_KEYS.IS_RUNNING, "true");
|
|
109
|
-
setTime(getSavedElapsedTime());
|
|
110
92
|
setIsRunning(true);
|
|
111
93
|
setIsStarted && setIsStarted(true);
|
|
112
94
|
}
|
|
113
95
|
};
|
|
96
|
+
// On met le chrono en pause
|
|
114
97
|
var pauseTimerHandler = function () {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
98
|
+
var currentlyRunning = localStorage.getItem(LOCAL_STORAGE_KEYS.IS_RUNNING) === "true";
|
|
99
|
+
if (currentlyRunning) {
|
|
100
|
+
// On calcule le temps total vraiment écoulé
|
|
101
|
+
var newElapsed = computeElapsedTime();
|
|
102
|
+
// On met à jour l'accumulatedTime en localStorage
|
|
103
|
+
localStorage.setItem(LOCAL_STORAGE_KEYS.ACCUMULATED_TIME, newElapsed.toString());
|
|
104
|
+
// On arrête
|
|
118
105
|
localStorage.setItem(LOCAL_STORAGE_KEYS.IS_RUNNING, "false");
|
|
119
|
-
|
|
106
|
+
localStorage.removeItem(LOCAL_STORAGE_KEYS.START_TIME);
|
|
107
|
+
setElapsedSeconds(newElapsed);
|
|
120
108
|
setIsRunning(false);
|
|
121
109
|
setIsStarted && setIsStarted(false);
|
|
110
|
+
onEnd(newElapsed); // si on veut déclencher l'événement "onEnd"
|
|
122
111
|
}
|
|
123
112
|
};
|
|
113
|
+
// On remet tout à zéro
|
|
114
|
+
var resetTimerHandler = function () {
|
|
115
|
+
clearTimerData();
|
|
116
|
+
localStorage.setItem(LOCAL_STORAGE_KEYS.HAS_STARTED_BEFORE, "false");
|
|
117
|
+
setElapsedSeconds(0);
|
|
118
|
+
setIsRunning(false);
|
|
119
|
+
setIsStarted && setIsStarted(false);
|
|
120
|
+
};
|
|
124
121
|
var handleButtonClick = function () {
|
|
125
|
-
if (
|
|
126
|
-
|
|
122
|
+
if (isRunning) {
|
|
123
|
+
pauseTimerHandler();
|
|
127
124
|
}
|
|
128
125
|
else {
|
|
129
|
-
|
|
130
|
-
onEnd(getCurrentElapsedTime());
|
|
126
|
+
startTimerHandler();
|
|
131
127
|
}
|
|
132
128
|
};
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
var
|
|
136
|
-
|
|
129
|
+
// --- Lecture / écriture localStorage ---
|
|
130
|
+
var getStartTime = function () {
|
|
131
|
+
var val = localStorage.getItem(LOCAL_STORAGE_KEYS.START_TIME);
|
|
132
|
+
return val ? parseInt(val, 10) : 0;
|
|
133
|
+
};
|
|
134
|
+
var getAccumulatedTime = function () {
|
|
135
|
+
var val = localStorage.getItem(LOCAL_STORAGE_KEYS.ACCUMULATED_TIME);
|
|
136
|
+
return val ? parseInt(val, 10) : 0;
|
|
137
|
+
};
|
|
138
|
+
var clearTimerData = function () {
|
|
139
|
+
localStorage.removeItem(LOCAL_STORAGE_KEYS.START_TIME);
|
|
140
|
+
localStorage.removeItem(LOCAL_STORAGE_KEYS.ACCUMULATED_TIME);
|
|
141
|
+
localStorage.removeItem(LOCAL_STORAGE_KEYS.IS_RUNNING);
|
|
142
|
+
};
|
|
143
|
+
// --- Format d'affichage
|
|
144
|
+
var formatTime = function (totalSeconds) {
|
|
145
|
+
var hrs = Math.floor(totalSeconds / 3600);
|
|
146
|
+
var mins = Math.floor((totalSeconds % 3600) / 60);
|
|
147
|
+
var secs = totalSeconds % 60;
|
|
137
148
|
return "".concat(hrs.toString().padStart(2, "0"), ":").concat(mins
|
|
138
149
|
.toString()
|
|
139
150
|
.padStart(2, "0"), ":").concat(secs.toString().padStart(2, "0"));
|
|
140
151
|
};
|
|
141
152
|
return (React.createElement("button", { onClick: handleButtonClick, className: "billing-button-wrapper ".concat(isRunning ? "isRunning" : "") },
|
|
142
153
|
React.createElement("i", { className: "allaw-icon-clock" }),
|
|
143
|
-
React.createElement("span", { className: "billing-time" }, formatTime(
|
|
154
|
+
React.createElement("span", { className: "billing-time" }, formatTime(elapsedSeconds)),
|
|
144
155
|
React.createElement("i", { className: isRunning ? "allaw-icon-pause" : "allaw-icon-play", style: { fontSize: "12px", color: "#25BEEB", fontWeight: 800 } })));
|
|
145
156
|
};
|
|
146
157
|
export default BillingCount;
|
|
@@ -19,10 +19,11 @@
|
|
|
19
19
|
.stepper-content {
|
|
20
20
|
width: 100%;
|
|
21
21
|
flex: 1;
|
|
22
|
+
margin: 20px 0;
|
|
22
23
|
overflow-y: auto;
|
|
23
24
|
display: flex;
|
|
24
25
|
flex-direction: column;
|
|
25
|
-
align-items:
|
|
26
|
+
align-items: center;
|
|
26
27
|
font-family: "Open Sans", sans-serif;
|
|
27
28
|
font-size: 16px;
|
|
28
29
|
font-weight: 400;
|