Skip to content

Commit

Permalink
date and currency localization fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ádám Kleizer committed Nov 22, 2024
1 parent 1de13d2 commit 6aaa8d9
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 27 deletions.
20 changes: 18 additions & 2 deletions frontend/components/Form/DatePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,27 @@
<label class="label">
<span class="label-text"> {{ label }} </span>
</label>
<VueDatePicker v-model="selected" :enable-time-picker="false" clearable :dark="isDark" :teleport="true" />
<VueDatePicker
v-model="selected"
:enable-time-picker="false"
clearable
:dark="isDark"
:teleport="true"
:format="formatDate"
/>
</div>
<div v-else class="sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
<label class="label">
<span class="label-text"> {{ label }} </span>
</label>
<VueDatePicker v-model="selected" :enable-time-picker="false" clearable :dark="isDark" :teleport="true" />
<VueDatePicker
v-model="selected"
:enable-time-picker="false"
clearable
:dark="isDark"
:teleport="true"
:format="formatDate"
/>
</div>
</template>

Expand Down Expand Up @@ -38,6 +52,8 @@
const isDark = useIsDark();
const formatDate = (date: Date | string | number) => fmtDate(date, "human", "date");
const selected = computed<Date | null>({
get() {
// String
Expand Down
33 changes: 19 additions & 14 deletions frontend/composables/use-formatters.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useI18n } from "vue-i18n";
import { format, formatDistance } from "date-fns";
/* eslint import/namespace: ['error', { allowComputed: true }] */
import * as Locales from "date-fns/locale";
Expand All @@ -22,37 +21,43 @@ export async function useFormatCurrency() {
}
}

return (value: number | string) => fmtCurrency(value, cache.currency);
return (value: number | string) => fmtCurrency(value, cache.currency, getLocaleCode());
}

export type DateTimeFormat = "relative" | "long" | "short" | "human";
export type DateTimeType = "date" | "time" | "datetime";

function getLocale() {
const t = useI18n();
const localeCode = (t?.locale?.value as string) ?? "en-US";
export function getLocaleCode() {
const { $i18nGlobal } = useNuxtApp();
return ($i18nGlobal?.locale?.value as string) ?? "en-US";
}

function getLocaleForDate() {
const localeCode = getLocaleCode();
const lang = localeCode.length > 1 ? localeCode.substring(0, 2) : localeCode;
const region = localeCode.length > 2 ? localeCode.substring(3) : "";
return Locales[(lang + region) as keyof typeof Locales] ?? Locales[lang as keyof typeof Locales] ?? Locales.enUS;
}

export function useLocaleTimeAgo(date: Date) {
return formatDistance(date, new Date(), { locale: getLocale() });
}

export function fmtDate(value: string | Date, fmt: DateTimeFormat = "human", type: DateTimeType = "date"): string {
const dt = typeof value === "string" ? new Date(value) : value;
export function fmtDate(
value: string | Date | number,
fmt: DateTimeFormat = "human",
type: DateTimeType = "date"
): string {
const dt = typeof value === "string" || typeof value === "number" ? new Date(value) : value;

if (!dt || !validDate(dt)) {
return "";
}

const localeOptions = { locale: getLocaleForDate() };

if (fmt === "relative") {
return useLocaleTimeAgo(dt);
return `${formatDistance(dt, new Date(), { ...localeOptions, addSuffix: true })} (${fmtDate(dt, "short", "date")})`;
}

if (type === "time") {
return format(dt, "p", { locale: getLocale() });
return format(dt, "p", localeOptions);
}

let formatStr = "";
Expand All @@ -74,5 +79,5 @@ export function fmtDate(value: string | Date, fmt: DateTimeFormat = "human", typ
formatStr += "p";
}

return format(dt, formatStr, { locale: getLocale() });
return format(dt, formatStr, localeOptions);
}
4 changes: 3 additions & 1 deletion frontend/lib/datelib/datelib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export function format(date: Date | string): string {
}

export function zeroTime(date: Date): Date {
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
return new Date(
new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - date.getTimezoneOffset() * 60000
);
}

export function factorRange(offset: number = 7): [Date, Date] {
Expand Down
6 changes: 1 addition & 5 deletions frontend/pages/item/[id]/index/edit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,12 @@
let purchasePrice = 0;
let soldPrice = 0;
let purchaseTime = null;
if (item.value.purchasePrice) {
purchasePrice = item.value.purchasePrice;
}
if (item.value.soldPrice) {
soldPrice = item.value.soldPrice;
}
if (item.value.purchaseTime && typeof item.value.purchaseTime !== "string") {
purchaseTime = new Date(item.value.purchaseTime.getTime() - item.value.purchaseTime.getTimezoneOffset() * 60000);
}
console.log((item.value.purchasePrice ??= 0));
console.log((item.value.soldPrice ??= 0));
Expand All @@ -121,7 +117,7 @@
assetId: item.value.assetId,
purchasePrice,
soldPrice,
purchaseTime: purchaseTime as Date,
purchaseTime: item.value.purchaseTime as Date,
};
const { error } = await api.items.update(itemId.value, payload);
Expand Down
11 changes: 6 additions & 5 deletions frontend/pages/profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import MdiFill from "~icons/mdi/fill";
import MdiPencil from "~icons/mdi/pencil";
import MdiAccountMultiple from "~icons/mdi/account-multiple";
import { getLocaleCode } from "~/composables/use-formatters";
definePageMeta({
middleware: ["auth"],
Expand Down Expand Up @@ -52,12 +53,11 @@
});
const currencyExample = computed(() => {
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: currency.value ? currency.value.code : "USD",
});
return fmtCurrency(1000, currency.value?.code ?? "USD", getLocaleCode());
});
return formatter.format(1000);
const dateExample = computed(() => {
return fmtDate(new Date(Date.now() - 15 * 60000), "relative");
});
const { data: group } = useAsyncData(async () => {
Expand Down Expand Up @@ -389,6 +389,7 @@
{{ $t(`languages.${lang}`) }} ({{ $t(`languages.${lang}`, 1, { locale: lang }) }})
</option>
</select>
<p class="m-2 text-sm">{{ $t("profile.example") }}: {{ $t("global.created") }} {{ dateExample }}</p>
</div>
</BaseCard>

Expand Down
6 changes: 6 additions & 0 deletions frontend/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export default defineNuxtPlugin(({ vueApp }) => {
messages: messages(),
});
vueApp.use(i18n);

return {
provide: {
i18nGlobal: i18n.global,
},
};
});

export const messages = () => {
Expand Down

0 comments on commit 6aaa8d9

Please sign in to comment.