Saving inputs to browser storage
This commit is contained in:
15
README.md
15
README.md
@@ -1,7 +1,11 @@
|
||||
# `Daily Time Recording`
|
||||
# Daily Time Recording
|
||||
|
||||
Simple utility to calculate how much time you have left to record today.
|
||||
|
||||
The start time & duration are kept in browser storage. The recorded duration is also kept but cleared every day.
|
||||
|
||||
# Operation
|
||||
|
||||
Inputs:
|
||||
|
||||
- Start Time
|
||||
@@ -9,6 +13,9 @@ Inputs:
|
||||
- Break Duration
|
||||
- Break Taken Yes/No
|
||||
- Recorded Duration
|
||||
|
||||
Output:
|
||||
|
||||
- Remaining Duration
|
||||
|
||||
Calculation:
|
||||
@@ -21,8 +28,4 @@ Remaining = Now - Start - Break (if taken) - Recorded
|
||||
|
||||
- `npm run build` - Builds for production, emitting to `dist/`
|
||||
|
||||
- `npm run preview` - Starts a server at http://localhost:4173/ to test production build locally
|
||||
|
||||
# Todo
|
||||
|
||||
- Save start, target & break duration in browser storage
|
||||
- `npm run preview` - Starts a server at http://localhost:4173/ to test production build locally
|
||||
@@ -10,6 +10,7 @@ import './style.css';
|
||||
import {durationRe} from "./duration.js";
|
||||
import Duration from "./Duration.jsx";
|
||||
import calculateRemaining from "./calc.js";
|
||||
import {getStoredRecordedTime, getStoredDefaults, setStoredRecordedTime, setStoredDefaults} from "./store.js";
|
||||
|
||||
const schema = yup.object({
|
||||
startTime: yup.string().matches(timeRe, {message: '12 or 24 hr time format required'}).required(),
|
||||
@@ -30,7 +31,8 @@ export function App() {
|
||||
startTime: '09:00',
|
||||
target: '7.5h',
|
||||
break: '1h',
|
||||
recorded: ''
|
||||
recorded: getStoredRecordedTime(),
|
||||
...getStoredDefaults()
|
||||
},
|
||||
resolver: yupResolver(schema)
|
||||
});
|
||||
@@ -49,6 +51,10 @@ export function App() {
|
||||
}
|
||||
setRemaining(calculateRemaining(currentData));
|
||||
|
||||
// save new values to storage
|
||||
setStoredDefaults({ startTime: currentData.startTime, target: currentData.target });
|
||||
setStoredRecordedTime(currentData.recorded);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
setRemaining(calculateRemaining(currentData));
|
||||
}, 60000);
|
||||
@@ -68,6 +74,10 @@ export function App() {
|
||||
Daily Time Tracking
|
||||
</div>
|
||||
<div class="title-bar-controls">
|
||||
<button type="button"
|
||||
aria-label="Help"
|
||||
title="Open in GitHub - https://github.com/sam159/daily-time-recording"
|
||||
onClick={() => window.open("https://github.com/sam159/daily-time-recording", "_blank")} />
|
||||
<button type="button" aria-label="Close" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
65
src/store.js
Normal file
65
src/store.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import * as yup from "yup";
|
||||
|
||||
const DEFAULTS_KEY = 'defaults';
|
||||
const RECORDED_KEY = 'recorded';
|
||||
|
||||
const defaultsSchema = yup.object({
|
||||
startTime: yup.string().required(),
|
||||
target: yup.string().required(),
|
||||
}).required();
|
||||
|
||||
const recordedSchema = yup.object({
|
||||
recorded: yup.string().required(),
|
||||
updated: yup.number().required().nullable()
|
||||
}).required();
|
||||
|
||||
function getJsonValue(key, defaultValue = {}) {
|
||||
const item = localStorage.getItem(key);
|
||||
if (item != null) {
|
||||
try {
|
||||
const data = JSON.parse(item);
|
||||
if (typeof data === 'object') {
|
||||
return data;
|
||||
}
|
||||
} catch (e) {
|
||||
localStorage.removeItem(key);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
export function getStoredDefaults() {
|
||||
const value = getJsonValue(DEFAULTS_KEY);
|
||||
try {
|
||||
return defaultsSchema.validateSync(value);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export function setStoredDefaults(data) {
|
||||
localStorage.setItem(DEFAULTS_KEY, JSON.stringify(data));
|
||||
}
|
||||
|
||||
export function getStoredRecordedTime() {
|
||||
const info = getJsonValue(RECORDED_KEY, { recorded: '', updated: null });
|
||||
try {
|
||||
const data = recordedSchema.validateSync(info);
|
||||
if (data.updated != null) {
|
||||
const startOfDay = new Date();
|
||||
startOfDay.setHours(0, 0, 0, 0);
|
||||
|
||||
if (data.updated < startOfDay.valueOf()) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return data.recorded;
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export function setStoredRecordedTime(recorded) {
|
||||
localStorage.setItem(RECORDED_KEY, JSON.stringify({ recorded, updated: new Date().valueOf() }));
|
||||
}
|
||||
@@ -40,10 +40,13 @@ export function minsToTime(totalMinutes) {
|
||||
let hours = Math.floor(absMinutes / 60);
|
||||
let minutes = absMinutes % 60;
|
||||
if (minutes > 0) {
|
||||
return `${prefix}${hours}h ${minutes}m`;
|
||||
if (hours > 0) {
|
||||
return `${prefix}${hours}h ${minutes}m`;
|
||||
}
|
||||
return `${prefix}${minutes}m`;
|
||||
}
|
||||
if (hours > 0) {
|
||||
return `${hours}h`;
|
||||
return `${prefix}${hours}h`;
|
||||
}
|
||||
return '0m';
|
||||
return `${prefix}0m`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user