Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0356721279 | |||
| 7ba9b27019 | |||
| d7babf7230 | |||
| 24d3df7f2d | |||
| 224e12294a | |||
| 281b4db9fc | |||
| 1fcb525211 | |||
| e2b406946f | |||
| 74d95f08f5 |
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
||||
dist
|
||||
node_modules
|
||||
.git
|
||||
.idea
|
||||
26
Dockerfile
Normal file
26
Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
||||
FROM node:20-alpine AS build
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
# install packages first
|
||||
COPY package* .
|
||||
RUN npm ci
|
||||
|
||||
# copy everything else and run the build
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM busybox:1.37 AS httpd
|
||||
|
||||
# add user to run web server as
|
||||
RUN adduser -D static
|
||||
USER static
|
||||
WORKDIR /home/static
|
||||
|
||||
# copy build files from the node worker
|
||||
COPY --from=build /build/dist /home/static
|
||||
|
||||
EXPOSE 3000
|
||||
# run httpd in foreground, verbose, on port 3000
|
||||
CMD ["busybox", "httpd", "-f", "-v", "-p", "3000"]
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="light" />
|
||||
<title>Daily Time Tracking</title>
|
||||
<script defer src="https://umami.knier.uk/script.js" data-website-id="8776a11a-9f28-49f4-9b95-87cf1317a9a1"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -16,7 +16,7 @@ const schema = yup.object({
|
||||
startTime: yup.string().matches(timeRe, {message: '12 or 24 hr time format required'}).required(),
|
||||
target: yup.string().matches(durationRe, {message: 'duration in hh:mm or hrs and mins required'}).required(),
|
||||
break: yup.string().matches(durationRe, {message: 'duration in hh:mm or hrs and mins required'}).required(),
|
||||
breakTaken: yup.bool().required(),
|
||||
breakTaken: yup.boolean().required(),
|
||||
recorded: yup.string().matches(durationRe, {message: 'duration in hh:mm or hrs and mins required'}).required()
|
||||
}).required();
|
||||
|
||||
@@ -31,7 +31,9 @@ export function App() {
|
||||
startTime: '09:00',
|
||||
target: '7.5h',
|
||||
break: '1h',
|
||||
recorded: getStoredRecordedTime(),
|
||||
breakTaken: false,
|
||||
recorded: '0',
|
||||
...getStoredRecordedTime(),
|
||||
...getStoredDefaults()
|
||||
},
|
||||
resolver: yupResolver(schema)
|
||||
@@ -52,8 +54,8 @@ export function App() {
|
||||
setRemaining(calculateRemaining(currentData));
|
||||
|
||||
// save new values to storage
|
||||
setStoredDefaults({ startTime: currentData.startTime, target: currentData.target });
|
||||
setStoredRecordedTime(currentData.recorded);
|
||||
setStoredDefaults(currentData);
|
||||
setStoredRecordedTime(currentData.recorded, currentData.breakTaken);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
setRemaining(calculateRemaining(currentData));
|
||||
|
||||
23
src/store.js
23
src/store.js
@@ -6,10 +6,12 @@ const RECORDED_KEY = 'recorded';
|
||||
const defaultsSchema = yup.object({
|
||||
startTime: yup.string().required(),
|
||||
target: yup.string().required(),
|
||||
break: yup.string().required(),
|
||||
}).required();
|
||||
|
||||
const recordedSchema = yup.object({
|
||||
recorded: yup.string().required(),
|
||||
breakTaken: yup.boolean().required(),
|
||||
updated: yup.number().required().nullable()
|
||||
}).required();
|
||||
|
||||
@@ -39,11 +41,15 @@ export function getStoredDefaults() {
|
||||
}
|
||||
|
||||
export function setStoredDefaults(data) {
|
||||
localStorage.setItem(DEFAULTS_KEY, JSON.stringify(data));
|
||||
try {
|
||||
localStorage.setItem(DEFAULTS_KEY, JSON.stringify(defaultsSchema.cast(data, {stripUnknown: true})));
|
||||
} catch (e) {
|
||||
console.error(`Error setting stored defaults: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function getStoredRecordedTime() {
|
||||
const info = getJsonValue(RECORDED_KEY, { recorded: '', updated: null });
|
||||
const info = getJsonValue(RECORDED_KEY, { recorded: '', breakTaken: false, updated: null });
|
||||
try {
|
||||
const data = recordedSchema.validateSync(info);
|
||||
if (data.updated != null) {
|
||||
@@ -51,15 +57,18 @@ export function getStoredRecordedTime() {
|
||||
startOfDay.setHours(0, 0, 0, 0);
|
||||
|
||||
if (data.updated < startOfDay.valueOf()) {
|
||||
return '';
|
||||
return { recorded: '0', breakTaken: false };
|
||||
}
|
||||
}
|
||||
return data.recorded;
|
||||
return {
|
||||
recorded: data.recorded,
|
||||
breakTaken: data.breakTaken,
|
||||
};
|
||||
} catch (e) {
|
||||
return '';
|
||||
return { recorded: '0', breakTaken: false };
|
||||
}
|
||||
}
|
||||
|
||||
export function setStoredRecordedTime(recorded) {
|
||||
localStorage.setItem(RECORDED_KEY, JSON.stringify({ recorded, updated: new Date().valueOf() }));
|
||||
export function setStoredRecordedTime(recorded, breakTaken) {
|
||||
localStorage.setItem(RECORDED_KEY, JSON.stringify({ recorded, breakTaken, updated: new Date().valueOf() }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user