feat: uptime and expire time component

This commit is contained in:
Zack Spear
2023-05-30 18:40:03 -07:00
parent 4b27d54302
commit 9404bdb580
8 changed files with 205 additions and 2 deletions

View File

@@ -0,0 +1,56 @@
<script setup lang="ts">
import dateDiff from '~/helpers/time/dateDiff';
import dateFormat from '~/helpers/time/dateFormat';
import buildStringFromValues from '~/helpers/time/buildTimeString';
export interface Props {
time: string;
state: string;
}
const props = defineProps<Props>();
const parsedTime = ref<string>('');
const formattedTime = computed<string>(() => {
return dateFormat(props.time);
});
const countUp = computed<boolean>(() => {
return props.state !== 'TRIAL' && props.state === 'EEXPIRED';
})
const output = computed(() => {
if (!countUp.value) {
return {
title: props.state === 'EEXPIRED'
? `Trial Key Expired at ${formattedTime.value}`
: `Trial Key Expires at ${formattedTime.value}`,
text: props.state === 'EEXPIRED'
? `Trial Key Expired ${parsedTime.value}`
: `Trial Key Expires in ${parsedTime.value}`,
};
}
return {
title: `Server Up Since ${formattedTime.value}`,
text: `Uptime ${parsedTime.value}`,
};
});
const runDiff = () => parsedTime.value = buildStringFromValues(dateDiff(props.time, countUp.value));
let interval: string | number | NodeJS.Timeout | undefined = undefined;
onBeforeMount(() => {
runDiff();
interval = setInterval(() => {
runDiff();
}, 1000);
});
onBeforeUnmount(() => {
clearInterval(interval);
});
</script>
<template>
<p :title="output.title">{{ output.text }}</p>
</template>

View File

@@ -0,0 +1,42 @@
import { TimeStringsObject } from '~/types/time';
const buildStringFromValues = ({
years, months, days, hours, minutes, seconds, firstDateWasLater, displaySeconds,
}: TimeStringsObject) => {
const result = [];
type DateStrings = {
[key: string]: string;
};
const dateStrings: DateStrings = {
year: 'year',
years: 'years',
month: 'month',
months: 'months',
day: 'day',
days: 'days',
hour: 'hour',
hours: 'hours',
minute: 'minute',
minutes: 'minutes',
second: 'second',
seconds: 'seconds',
firstDateWasLater: 'ago',
delimiter: ' ',
};
const pluralize = (num: number, word: string) => {
const index = word + (num === 1 ? '' : 's');
return `${num} ${dateStrings[index]}`;
};
if (years) result.push(pluralize(years, 'year'));
if (months) result.push(pluralize(months, 'month'));
if (days) result.push(pluralize(days, 'day'));
if (hours) result.push(pluralize(hours, 'hour'));
if (minutes) result.push(pluralize(minutes, 'minute'));
if (seconds && ((!years && !months && !days && !hours && !minutes) || displaySeconds)) result.push(pluralize(seconds, 'second'));
if (firstDateWasLater) result.push(dateStrings.firstDateWasLater);
return result.join(dateStrings.delimiter);
}
export default buildStringFromValues;

11
helpers/time/dateDiff.ts Normal file
View File

@@ -0,0 +1,11 @@
import dayjs from 'dayjs';
import preciseDateDiff from './preciseDateDiff';
const readbleDifference = (a = '', b = '') => {
const x = a ? dayjs(parseInt(a, 10)) : dayjs();
const y = b ? dayjs(parseInt(b, 10)) : dayjs();
return preciseDateDiff(x, y);
};
const dateDiff = (time: string, countUp: boolean) => countUp ? readbleDifference(time, '') : readbleDifference('', time);
export default dateDiff;

View File

@@ -0,0 +1,5 @@
import dayjs from 'dayjs';
const formatDate = (date: string): string => dayjs(parseInt(date, 10)).format('llll');
export default formatDate;

View File

@@ -0,0 +1,72 @@
import dayjs from 'dayjs';
import { TimeStringsObject } from '~/types/time';
/**
* Original meat and potatos from:
* @version: 1.0.1
* @author: huangjinlin
* @repo: https://github.com/huangjinlin/dayjs-precise-range
*/
const buildValueObject = (yDiff: number, mDiff: number, dDiff: number, hourDiff: number, minDiff: number, secDiff: number, firstDateWasLater: boolean): TimeStringsObject => ({
years: yDiff,
months: mDiff,
days: dDiff,
hours: hourDiff,
minutes: minDiff,
seconds: secDiff,
firstDateWasLater,
});
const preciseDateDiff = (d1: dayjs.Dayjs, d2: dayjs.Dayjs): TimeStringsObject => {
let m1 = dayjs(d1);
let m2 = dayjs(d2);
let firstDateWasLater;
if (m1.isSame(m2)) {
return buildValueObject(0, 0, 0, 0, 0, 0, false);
}
if (m1.isAfter(m2)) {
const tmp = m1;
m1 = m2;
m2 = tmp;
firstDateWasLater = true;
} else {
firstDateWasLater = false;
}
let yDiff = m2.year() - m1.year();
let mDiff = m2.month() - m1.month();
let dDiff = m2.date() - m1.date();
let hourDiff = m2.hour() - m1.hour();
let minDiff = m2.minute() - m1.minute();
let secDiff = m2.second() - m1.second();
if (secDiff < 0) {
secDiff = 60 + secDiff;
minDiff -= 1;
}
if (minDiff < 0) {
minDiff = 60 + minDiff;
hourDiff -= 1;
}
if (hourDiff < 0) {
hourDiff = 24 + hourDiff;
dDiff -= 1;
}
if (dDiff < 0) {
const daysInLastFullMonth = dayjs(`${m2.year()}-${m2.month() + 1}`).subtract(1, 'M').daysInMonth();
if (daysInLastFullMonth < m1.date()) { // 31/01 -> 2/03
dDiff = daysInLastFullMonth + dDiff + (m1.date() - daysInLastFullMonth);
} else {
dDiff = daysInLastFullMonth + dDiff;
}
mDiff -= 1;
}
if (mDiff < 0) {
mDiff = 12 + mDiff;
yDiff -= 1;
}
return buildValueObject(yDiff, mDiff, dDiff, hourDiff, minDiff, secDiff, firstDateWasLater);
};
export default preciseDateDiff;

8
package-lock.json generated
View File

@@ -8,7 +8,8 @@
"hasInstallScript": true,
"dependencies": {
"@pinia/nuxt": "^0.4.11",
"crypto-js": "^4.1.1"
"crypto-js": "^4.1.1",
"dayjs": "^1.11.7"
},
"devDependencies": {
"@nuxtjs/tailwindcss": "^6.7.0",
@@ -3703,6 +3704,11 @@
"node": ">= 12"
}
},
"node_modules/dayjs": {
"version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",

View File

@@ -20,7 +20,8 @@
},
"dependencies": {
"@pinia/nuxt": "^0.4.11",
"crypto-js": "^4.1.1"
"crypto-js": "^4.1.1",
"dayjs": "^1.11.7"
},
"overrides": {
"vue": "latest"

10
types/time.ts Normal file
View File

@@ -0,0 +1,10 @@
export interface TimeStringsObject {
years: number;
months: number;
days: number;
hours: number;
minutes: number;
seconds: number;
firstDateWasLater: boolean;
displaySeconds?: boolean;
};