149 lines
5 KiB
TypeScript
149 lines
5 KiB
TypeScript
import chalk from 'chalk';
|
|
import { Duration } from 'dayjs/plugin/duration';
|
|
import { parseDuration, parseTimestamp } from './parse';
|
|
import * as readline from 'readline/promises';
|
|
import { formatDuration, formatTime } from './format';
|
|
import dayjs, { Dayjs } from 'dayjs';
|
|
import { WtcPromptResult } from './types/WtcPromptResult';
|
|
import duration from 'dayjs/plugin/duration.js';
|
|
import WtcConfig from './types/WtcConfig';
|
|
import { MessageKey, message } from './i18n';
|
|
|
|
dayjs.extend(duration);
|
|
|
|
const { error } = console;
|
|
|
|
const input = async (config: WtcConfig): Promise<WtcPromptResult> => {
|
|
const msg = message(config.language);
|
|
const fmtDuration = formatDuration(config.language);
|
|
const { defaults, askInput, unpaidLunchBreakDuration: lunchBreakDuration } = config;
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
});
|
|
|
|
let startedAt: Dayjs | undefined = undefined;
|
|
let stoppedAt: Dayjs | undefined = undefined;
|
|
let stoppedWorking = false;
|
|
|
|
try {
|
|
// Get work day duration
|
|
let workDayDuration: Duration | undefined = undefined;
|
|
|
|
if (askInput.workDayLength) {
|
|
const durationAnswer = await rl.question(
|
|
msg(
|
|
MessageKey.promptWorkDayDuration,
|
|
config.unpaidLunchBreakDuration ? msg(MessageKey.excludingLunch) : '',
|
|
fmtDuration(defaults.workDayDuration, true),
|
|
),
|
|
);
|
|
if (durationAnswer !== '') {
|
|
workDayDuration = parseDuration(durationAnswer);
|
|
if (workDayDuration.asMinutes() <= 0) {
|
|
error(
|
|
chalk.red(
|
|
msg(MessageKey.parseTimeFailed, durationAnswer, fmtDuration(defaults.workDayDuration)),
|
|
),
|
|
);
|
|
workDayDuration = undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!workDayDuration) {
|
|
workDayDuration = defaults.workDayDuration;
|
|
}
|
|
|
|
if (askInput.startTime) {
|
|
const startTimeAnswer = await rl.question(msg(MessageKey.promptStartTime, formatTime(defaults.startTime)));
|
|
if (startTimeAnswer !== '') {
|
|
startedAt = parseTimestamp(startTimeAnswer);
|
|
if (!startedAt.isValid()) {
|
|
error(chalk.red(msg(MessageKey.parseTimeFailed, startTimeAnswer, formatTime(defaults.startTime))));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!startedAt?.isValid()) {
|
|
startedAt = defaults.startTime;
|
|
}
|
|
|
|
if (askInput.stopTime) {
|
|
const stoppedAnswer = await rl.question(msg(MessageKey.promptStopTime, formatTime(defaults.stopTime)));
|
|
|
|
if (stoppedAnswer !== '') {
|
|
stoppedWorking = true;
|
|
stoppedAt = parseTimestamp(stoppedAnswer);
|
|
if (!stoppedAt.isValid()) {
|
|
error(chalk.red(msg(MessageKey.parseTimeFailed, stoppedAnswer, formatTime(defaults.stopTime))));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!stoppedAt) {
|
|
stoppedAt = defaults.stopTime;
|
|
}
|
|
|
|
if (stoppedAt.isSame(startedAt) || stoppedAt.isBefore(startedAt)) {
|
|
error(
|
|
chalk.red(msg(MessageKey.startTimeBeforeStopTimeError, formatTime(startedAt), formatTime(stoppedAt))),
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
let worked = dayjs.duration(stoppedAt.diff(startedAt));
|
|
|
|
let hadLunch = false;
|
|
if (lunchBreakDuration) {
|
|
const lunchAnswer = (
|
|
await rl.question(
|
|
msg(
|
|
MessageKey.promptLunchBreak,
|
|
msg(config.defaults.hadLunch ? MessageKey.promptYesNoYes : MessageKey.promptYesNoNo),
|
|
),
|
|
)
|
|
).toLowerCase();
|
|
|
|
if (
|
|
lunchAnswer === 'y' ||
|
|
lunchAnswer === 'k' ||
|
|
(config.defaults.hadLunch && lunchAnswer !== 'n' && lunchAnswer !== 'e')
|
|
) {
|
|
hadLunch = true;
|
|
worked = worked.subtract(lunchBreakDuration);
|
|
}
|
|
}
|
|
|
|
// Calculate unlogged time
|
|
let loggedAnswer = await rl.question(msg(MessageKey.promptLogged));
|
|
if (loggedAnswer === '') {
|
|
loggedAnswer = '00:00';
|
|
}
|
|
const logged = parseDuration(loggedAnswer);
|
|
const unLogged = worked.subtract(logged);
|
|
const workLeft = workDayDuration.subtract(worked);
|
|
let workLeftMinutes = workLeft.asMinutes();
|
|
let workedOvertime: Duration | undefined;
|
|
|
|
if (workLeftMinutes < 0) {
|
|
workedOvertime = dayjs.duration(Math.round(workLeftMinutes * -1), 'minutes');
|
|
}
|
|
|
|
return {
|
|
logged,
|
|
unLogged,
|
|
startedAt,
|
|
stoppedAt,
|
|
stoppedWorking,
|
|
hadLunch,
|
|
worked,
|
|
workLeft,
|
|
workedOvertime,
|
|
};
|
|
} finally {
|
|
rl.close();
|
|
}
|
|
};
|
|
|
|
export default input;
|