initial UI for currency selection

This commit is contained in:
Hayden 2022-10-14 14:50:14 -08:00
parent dea2dcfde8
commit 15dc75fce6
9 changed files with 232 additions and 158 deletions

View file

@ -27,6 +27,7 @@ tasks:
- "./scripts/process-types.py" - "./scripts/process-types.py"
generates: generates:
- "./frontend/lib/api/types/data-contracts.ts" - "./frontend/lib/api/types/data-contracts.ts"
- "./backend/ent/schema"
- "./backend/app/api/docs/swagger.json" - "./backend/app/api/docs/swagger.json"
- "./backend/app/api/docs/swagger.yaml" - "./backend/app/api/docs/swagger.yaml"

View file

@ -121,6 +121,9 @@ const DefaultCurrency = CurrencyUsd
// Currency values. // Currency values.
const ( const (
CurrencyUsd Currency = "usd" CurrencyUsd Currency = "usd"
CurrencyEur Currency = "eur"
CurrencyGbp Currency = "gbp"
CurrencyJpy Currency = "jpy"
) )
func (c Currency) String() string { func (c Currency) String() string {
@ -130,7 +133,7 @@ func (c Currency) String() string {
// CurrencyValidator is a validator for the "currency" field enum values. It is called by the builders before save. // CurrencyValidator is a validator for the "currency" field enum values. It is called by the builders before save.
func CurrencyValidator(c Currency) error { func CurrencyValidator(c Currency) error {
switch c { switch c {
case CurrencyUsd: case CurrencyUsd, CurrencyEur, CurrencyGbp, CurrencyJpy:
return nil return nil
default: default:
return fmt.Errorf("group: invalid enum value for currency field: %q", c) return fmt.Errorf("group: invalid enum value for currency field: %q", c)

View file

@ -127,7 +127,7 @@ var (
{Name: "created_at", Type: field.TypeTime}, {Name: "created_at", Type: field.TypeTime},
{Name: "updated_at", Type: field.TypeTime}, {Name: "updated_at", Type: field.TypeTime},
{Name: "name", Type: field.TypeString, Size: 255}, {Name: "name", Type: field.TypeString, Size: 255},
{Name: "currency", Type: field.TypeEnum, Enums: []string{"usd"}, Default: "usd"}, {Name: "currency", Type: field.TypeEnum, Enums: []string{"usd", "eur", "gbp", "jpy"}, Default: "usd"},
} }
// GroupsTable holds the schema information for the "groups" table. // GroupsTable holds the schema information for the "groups" table.
GroupsTable = &schema.Table{ GroupsTable = &schema.Table{

View file

@ -27,7 +27,7 @@ func (Group) Fields() []ent.Field {
NotEmpty(), NotEmpty(),
field.Enum("currency"). field.Enum("currency").
Default("usd"). Default("usd").
Values("usd"), // TODO: add more currencies Values("usd", "eur", "gbp", "jpy"), // TODO: add more currencies
} }
} }

View file

@ -25,7 +25,7 @@
}, },
modelValue: { modelValue: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
type: [Object, String, Boolean] as any, type: [Object, String] as any,
default: null, default: null,
}, },
items: { items: {
@ -53,10 +53,19 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function compare(a: any, b: any): boolean { function compare(a: any, b: any): boolean {
if (props.value != null) { if (props.value) {
return a[props.value] === b[props.value]; return a[props.value] === b[props.value];
} }
return a === b;
if (a === b) {
return true;
}
if (!a || !b) {
return false;
}
return JSON.stringify(a) === JSON.stringify(b);
} }
watch( watch(

View file

@ -1,35 +1,5 @@
import { Ref } from "vue"; import { Ref } from "vue";
import { DaisyTheme } from "~~/lib/data/themes";
export type DaisyTheme =
| "light"
| "dark"
| "cupcake"
| "bumblebee"
| "emerald"
| "corporate"
| "synthwave"
| "retro"
| "cyberpunk"
| "valentine"
| "halloween"
| "garden"
| "forest"
| "aqua"
| "lofi"
| "pastel"
| "fantasy"
| "wireframe"
| "black"
| "luxury"
| "dracula"
| "cmyk"
| "autumn"
| "business"
| "acid"
| "lemonade"
| "night"
| "coffee"
| "winter";
export type LocationViewPreferences = { export type LocationViewPreferences = {
showDetails: boolean; showDetails: boolean;

View file

@ -0,0 +1,33 @@
export type Currency = {
code: string;
local: string;
symbol: string;
name: string;
};
export const currencies: Currency[] = [
{
code: "USD",
local: "en-US",
symbol: "$",
name: "US Dollar",
},
{
code: "EUR",
local: "de-DE",
symbol: "€",
name: "Euro",
},
{
code: "GBP",
local: "en-GB",
symbol: "£",
name: "British Pound",
},
{
code: "JPY",
local: "ja-JP",
symbol: "¥",
name: "Japanese Yen",
},
];

150
frontend/lib/data/themes.ts Normal file
View file

@ -0,0 +1,150 @@
export type DaisyTheme =
| "light"
| "dark"
| "cupcake"
| "bumblebee"
| "emerald"
| "corporate"
| "synthwave"
| "retro"
| "cyberpunk"
| "valentine"
| "halloween"
| "garden"
| "forest"
| "aqua"
| "lofi"
| "pastel"
| "fantasy"
| "wireframe"
| "black"
| "luxury"
| "dracula"
| "cmyk"
| "autumn"
| "business"
| "acid"
| "lemonade"
| "night"
| "coffee"
| "winter";
export type ThemeOption = {
label: string;
value: DaisyTheme;
};
export const themes: ThemeOption[] = [
{
label: "Garden",
value: "garden",
},
{
label: "Light",
value: "light",
},
{
label: "Cupcake",
value: "cupcake",
},
{
label: "Bumblebee",
value: "bumblebee",
},
{
label: "Emerald",
value: "emerald",
},
{
label: "Corporate",
value: "corporate",
},
{
label: "Synthwave",
value: "synthwave",
},
{
label: "Retro",
value: "retro",
},
{
label: "Cyberpunk",
value: "cyberpunk",
},
{
label: "Valentine",
value: "valentine",
},
{
label: "Halloween",
value: "halloween",
},
{
label: "Forest",
value: "forest",
},
{
label: "Aqua",
value: "aqua",
},
{
label: "Lofi",
value: "lofi",
},
{
label: "Pastel",
value: "pastel",
},
{
label: "Fantasy",
value: "fantasy",
},
{
label: "Wireframe",
value: "wireframe",
},
{
label: "Black",
value: "black",
},
{
label: "Luxury",
value: "luxury",
},
{
label: "Dracula",
value: "dracula",
},
{
label: "Cmyk",
value: "cmyk",
},
{
label: "Autumn",
value: "autumn",
},
{
label: "Business",
value: "business",
},
{
label: "Acid",
value: "acid",
},
{
label: "Lemonade",
value: "lemonade",
},
{
label: "Night",
value: "night",
},
{
label: "Coffee",
value: "coffee",
},
{
label: "Winter",
value: "winter",
},
];

View file

@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { Detail } from "~~/components/global/DetailsSection/types"; import { Detail } from "~~/components/global/DetailsSection/types";
import { DaisyTheme } from "~~/composables/use-preferences";
import { useAuthStore } from "~~/stores/auth"; import { useAuthStore } from "~~/stores/auth";
import { themes } from "~~/lib/data/themes";
import { currencies, Currency } from "~~/lib/data/currency";
definePageMeta({ definePageMeta({
layout: "home", layout: "home",
@ -19,126 +20,6 @@
const { setTheme } = useTheme(); const { setTheme } = useTheme();
type ThemeOption = {
label: string;
value: DaisyTheme;
};
const themes: ThemeOption[] = [
{
label: "Garden",
value: "garden",
},
{
label: "Light",
value: "light",
},
{
label: "Cupcake",
value: "cupcake",
},
{
label: "Bumblebee",
value: "bumblebee",
},
{
label: "Emerald",
value: "emerald",
},
{
label: "Corporate",
value: "corporate",
},
{
label: "Synthwave",
value: "synthwave",
},
{
label: "Retro",
value: "retro",
},
{
label: "Cyberpunk",
value: "cyberpunk",
},
{
label: "Valentine",
value: "valentine",
},
{
label: "Halloween",
value: "halloween",
},
{
label: "Forest",
value: "forest",
},
{
label: "Aqua",
value: "aqua",
},
{
label: "Lofi",
value: "lofi",
},
{
label: "Pastel",
value: "pastel",
},
{
label: "Fantasy",
value: "fantasy",
},
{
label: "Wireframe",
value: "wireframe",
},
{
label: "Black",
value: "black",
},
{
label: "Luxury",
value: "luxury",
},
{
label: "Dracula",
value: "dracula",
},
{
label: "Cmyk",
value: "cmyk",
},
{
label: "Autumn",
value: "autumn",
},
{
label: "Business",
value: "business",
},
{
label: "Acid",
value: "acid",
},
{
label: "Lemonade",
value: "lemonade",
},
{
label: "Night",
value: "night",
},
{
label: "Coffee",
value: "coffee",
},
{
label: "Winter",
value: "winter",
},
];
const auth = useAuthStore(); const auth = useAuthStore();
const details = computed(() => { const details = computed(() => {
@ -232,6 +113,18 @@
passwordChange.current = ""; passwordChange.current = "";
passwordChange.loading = false; passwordChange.loading = false;
} }
// Currency Selection
const currency = ref<Currency>(currencies[1]);
const currencyExample = computed(() => {
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: currency.value ? currency.value.code : "USD",
});
return formatter.format(1000);
});
</script> </script>
<template> <template>
@ -283,6 +176,21 @@
</div> </div>
</BaseCard> </BaseCard>
<BaseCard>
<template #title>
<BaseSectionHeader class="pb-0">
<Icon name="mdi-accounts" class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Group Settings </span>
<template #description> Shared Group Settings </template>
</BaseSectionHeader>
</template>
<div class="p-5 pt-0 max-w-lg">
<FormSelect v-model="currency" label="Currency Format" :items="currencies" />
<p class="m-2 text-sm">Example: {{ currencyExample }}</p>
</div>
</BaseCard>
<BaseCard> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>