Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/TextField.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<template>
<div>
<span><small>{{ title }}</small></span>
<p>{{ content }}</p>
<p v-b-tooltip.hover :title="tooltip">{{ content }}</p>
</div>
</template>
<script>
export default {
name: 'TextField',
props: ['title', 'content'],
props: ['title', 'content', 'tooltip'],

}
</script>
5 changes: 5 additions & 0 deletions src/lib/dates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import moment from "moment/moment";

export function formatDate(value) {
return moment(String(value)).format('YYYY-MM-DD');
}
5 changes: 2 additions & 3 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'vue-tour/dist/vue-tour.css'
import './assets/css/main.css'
import QrcodeVue from "qrcode.vue";
import moment from "moment/moment";
import { formatDate } from "./lib/dates";

Vue.use(BootstrapVue)
Vue.use(BootstrapVueIcons)
Expand All @@ -28,9 +29,7 @@ Vue.filter('uppercase', function (value) {
return value.toUpperCase();
});

Vue.filter('formatDate', function (value) {
return moment(String(value)).format('YYYY-MM-DD hh:mm');
})
Vue.filter('formatDate', formatDate)

Vue.filter('formatDateHumanize', function (value) {
const now = new moment();
Expand Down
26 changes: 17 additions & 9 deletions src/views/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
</b-alert>
<b-card-text v-if="$store.state.profile.delete_after">
Your shard will be deleted
{{ $store.state.profile.delete_after | formatDateHumanize }}.
<span v-b-tooltip.hover :title="$store.state.profile.delete_after | formatDate">{{
$store.state.profile.delete_after | formatDateHumanize }}</span>.
That happens on its own if you do nothing:
you are not charged, and there is nothing to cancel.
</b-card-text>
Expand Down Expand Up @@ -89,7 +90,7 @@
incl. 19% VAT ({{ formatPrice(vatAmountEur($store.state.profile.subscription.price_cents)) }})
</b-card-text>
<b-card-text v-if="$store.state.profile.subscription.next_billing_date">
Next charge {{ $store.state.profile.subscription.next_billing_date | formatDateHumanize }}.
Next charge: {{ $store.state.profile.subscription.next_billing_date | formatDate }}.
</b-card-text>
<b-card-text v-if="$store.state.profile.subscription.payer_email" class="text-muted small">
Billed to {{ $store.state.profile.subscription.payer_email }}.
Expand Down Expand Up @@ -120,18 +121,21 @@
<template v-else-if="subscriptionState === 'grace'">
<b-card-text v-if="$store.state.profile.subscription.last_payment_failed_at">
Payment failed
{{ $store.state.profile.subscription.last_payment_failed_at | formatDateHumanize }}.
<span v-b-tooltip.hover :title="$store.state.profile.subscription.last_payment_failed_at | formatDate">{{
$store.state.profile.subscription.last_payment_failed_at | formatDateHumanize }}</span>.
</b-card-text>
<b-card-text v-else-if="$store.state.profile.subscription.ended">
Subscription ended
{{ $store.state.profile.subscription.ended | formatDateHumanize }}.
<span v-b-tooltip.hover :title="$store.state.profile.subscription.ended | formatDate">{{
$store.state.profile.subscription.ended | formatDateHumanize }}</span>.
</b-card-text>
<b-card-text v-else>
Subscription is no longer active.
</b-card-text>
<b-card-text v-if="$store.state.profile.delete_after">
Your shard will stop
{{ $store.state.profile.delete_after | formatDateHumanize }}.
<span v-b-tooltip.hover :title="$store.state.profile.delete_after | formatDate">{{
$store.state.profile.delete_after | formatDateHumanize }}</span>.
</b-card-text>
<div ref="paypalButton"></div>
</template>
Expand Down Expand Up @@ -235,7 +239,8 @@
</b-alert>
<p v-if="backupInfo.last_passphrase_access_info" class="text-muted small">
Your passphrase was last revealed
{{ backupInfo.last_passphrase_access_info.time | formatDateHumanize }}
<span v-b-tooltip.hover :title="backupInfo.last_passphrase_access_info.time | formatDate">{{
backupInfo.last_passphrase_access_info.time | formatDateHumanize }}</span>
from device <i>{{ backupInfo.last_passphrase_access_info.terminal_name }}</i> (with ID:
{{ backupInfo.last_passphrase_access_info.terminal_id }}).
</p>
Expand Down Expand Up @@ -341,12 +346,15 @@
<TextField v-if="$store.state.profile" title="Owner Email"
:content="$store.state.profile.owner_email || 'unknown'"/>
<TextField v-if="$store.state.profile" title="Created"
:content="$store.state.profile.time_created | formatDateHumanize"/>
:content="$store.state.profile.time_created | formatDateHumanize"
:tooltip="$store.state.profile.time_created | formatDate"/>
<TextField v-if="$store.state.profile" title="Assigned"
:content="$store.state.profile.time_assigned | formatDateHumanize"/>
:content="$store.state.profile.time_assigned | formatDateHumanize"
:tooltip="$store.state.profile.time_assigned | formatDate"/>
<div v-if="$store.state.profile">
<TextField v-if="$store.state.profile.delete_after" title="Scheduled to delete"
:content="$store.state.profile.delete_after | formatDateHumanize"/>
:content="$store.state.profile.delete_after | formatDateHumanize"
:tooltip="$store.state.profile.delete_after | formatDate"/>
<TextField v-else title="Scheduled to delete" content="never"/>
</div>
<TextField title="UI Version" :content="uiVersion"/>
Expand Down
12 changes: 12 additions & 0 deletions tests/unit/dates.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { formatDate } from '@/lib/dates';

describe('formatDate', () => {
test('renders the calendar day the charge falls on', () => {
expect(formatDate('2026-07-01T13:30:00')).toBe('2026-07-01');
});

test('carries no clock time, which the billing line does not need', () => {
expect(formatDate('2026-07-01T13:30:00'))
.toBe(formatDate('2026-07-01T01:30:00'));
});
});
Loading