Skip to content

Commit

Permalink
Improve portfolio UI view (#163)
Browse files Browse the repository at this point in the history
* Improve portfolio UI view

* Properly rendering dates
* Adding performance gain/loss on portfolio card

* Added ui label for labeler
  • Loading branch information
oxisto authored Oct 6, 2023
1 parent b6b706a commit cb342c5
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@

"repl":
- "repl/**/*"

"ui":
- "ui/**/*"
2 changes: 1 addition & 1 deletion repl/commands/portfolio.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import (
portfoliov1 "github.com/oxisto/money-gopher/gen"
"github.com/oxisto/money-gopher/gen/portfoliov1connect"
"github.com/oxisto/money-gopher/repl"
"google.golang.org/protobuf/types/known/timestamppb"

"github.com/bufbuild/connect-go"
"google.golang.org/protobuf/types/known/timestamppb"
)

type portfolioSnapshot struct{}
Expand Down
1 change: 1 addition & 0 deletions service/portfolio/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func marketPrice(secmap map[string]*portfoliov1.Security, name string, netPrice
}
}

// TODO(oxisto): remove once maps.Keys is in the stdlib in Go 1.22
func keys[M ~map[K]V, K comparable, V any](m M) (keys []K) {
keys = make([]K, 0, len(m))

Expand Down
16 changes: 16 additions & 0 deletions ui/src/lib/components/Date.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script lang="ts">
export let date: Date | undefined;
</script>

{#if date}
<time datetime={date.toISOString()}>
{Intl.DateTimeFormat(navigator.language, {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
}).format(date)}
</time>
{:else}
-
{/if}
31 changes: 31 additions & 0 deletions ui/src/lib/components/Performance.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script lang="ts">
import type { PortfolioSnapshot } from '$lib/gen/mgo_pb';
import { currency } from '$lib/intl';
import { ArrowTrendingUp, ArrowTrendingDown } from '@steeze-ui/heroicons';
import { Icon } from '@steeze-ui/svelte-icon';
export let snapshot: PortfolioSnapshot;
export let icon: boolean = true;
$: perf =
((snapshot.totalMarketValue - snapshot.totalPurchaseValue) / snapshot.totalPurchaseValue) * 100;
$: perfAbs = snapshot.totalMarketValue - snapshot.totalPurchaseValue;
</script>

<div
class="{perf < 0 ? 'text-red-400' : 'text-green-400'}
flex items-center"
>
{#if icon}
<Icon
src={perf > 0 ? ArrowTrendingUp : ArrowTrendingDown}
class="{perf < 0 ? 'text-red-400' : 'text-green-400'}
mr-1.5 h-5 w-5 flex-shrink-0"
aria-hidden="true"
/>
{/if}
{Intl.NumberFormat(navigator.language, { maximumFractionDigits: 2 }).format(perf)} % ({currency(
perfAbs,
'EUR'
)})
</div>
28 changes: 6 additions & 22 deletions ui/src/lib/components/PortfolioBreadcrumb.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import Date from '$lib/components/Date.svelte';
import Performance from '$lib/components/Performance.svelte';
import type { Portfolio, PortfolioSnapshot } from '$lib/gen/mgo_pb';
import { currency } from '$lib/intl';
import { Menu, MenuButton, MenuItems, MenuItem } from '@rgossiaux/svelte-headlessui';
import { Menu, MenuButton, MenuItem, MenuItems } from '@rgossiaux/svelte-headlessui';
import {
ArrowTrendingDown,
ArrowTrendingUp,
Calendar,
Check,
ChevronDown,
Expand All @@ -18,10 +18,6 @@
export let portfolio: Portfolio;
export let snapshot: PortfolioSnapshot;
$: perf =
((snapshot.totalMarketValue - snapshot.totalPurchaseValue) / snapshot.totalPurchaseValue) * 100;
$: perfAbs = snapshot.totalMarketValue - snapshot.totalPurchaseValue;
</script>

<div class="lg:flex lg:items-center lg:justify-between">
Expand Down Expand Up @@ -55,20 +51,8 @@
{portfolio.displayName}
</h2>
<div class="mt-1 flex flex-col sm:mt-0 sm:flex-row sm:flex-wrap sm:space-x-6">
<div
class="{perf < 0 ? 'text-red-400' : 'text-green-400'}
mt-2 flex items-center text-sm"
>
<Icon
src={perf > 0 ? ArrowTrendingUp : ArrowTrendingDown}
class="{perf < 0 ? 'text-red-400' : 'text-green-400'}
mr-1.5 h-5 w-5 flex-shrink-0"
aria-hidden="true"
/>
{Intl.NumberFormat('de', { maximumFractionDigits: 2 }).format(perf)} % ({currency(
perfAbs,
'EUR'
)})
<div class="mt-2 flex items-center text-sm">
<Performance {snapshot} />
</div>
<div class="mt-2 flex items-center text-sm text-gray-500">
<Icon
Expand All @@ -92,7 +76,7 @@
class="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
aria-hidden="true"
/>
First transaction on {snapshot.firstTransactionTime}
First transaction on&nbsp;<Date date={snapshot.firstTransactionTime?.toDate()} />
</div>
</div>
</div>
Expand Down
19 changes: 16 additions & 3 deletions ui/src/lib/components/PortfolioCard.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<script lang="ts">
import type { Portfolio, PortfolioSnapshot } from '$lib/gen/mgo_pb';
import { currency } from '$lib/intl';
import { CalendarDays, CreditCard, UserCircle } from '@steeze-ui/heroicons';
import { ArrowTrendingUp, CalendarDays, CreditCard, UserCircle } from '@steeze-ui/heroicons';
import { Icon } from '@steeze-ui/svelte-icon';
import Performance from '$lib/components/Performance.svelte';
import Date from '$lib/components/Date.svelte';
export let portfolio: Portfolio;
export let snapshot: PortfolioSnapshot;
Expand All @@ -13,7 +15,9 @@
<div class="rounded-lg bg-gray-50 shadow-sm ring-1 ring-gray-900/5">
<dl class="flex flex-wrap">
<div class="flex-auto pl-6 pt-6">
<dt class="text-sm font-semibold leading-6 text-gray-900">{portfolio.displayName}</dt>
<dt class="text-sm font-semibold leading-6 text-gray-900">
<a href="/portfolios/{portfolio.name}">{portfolio.displayName}</a>
</dt>
<dd class="mt-1 text-base font-semibold leading-6 text-gray-900">
{currency(snapshot?.totalMarketValue, 'EUR')}
</dd>
Expand All @@ -31,6 +35,15 @@
</dd>
</div>
<div class="mt-6 flex w-full flex-none gap-x-4 border-t border-gray-900/5 px-6 pt-6">
<dt class="flex-none">
<span class="sr-only">Performance</span>
<Icon src={ArrowTrendingUp} class="h-6 w-5 text-gray-400" aria-hidden="true" />
</dt>
<dd class="text-sm font-medium leading-6 text-gray-900">
<Performance {snapshot} icon={false} />
</dd>
</div>
<div class="mt-4 flex w-full flex-none gap-x-4 px-6">
<dt class="flex-none">
<span class="sr-only">Client</span>
<Icon src={UserCircle} class="h-6 w-5 text-gray-400" aria-hidden="true" />
Expand All @@ -43,7 +56,7 @@
<Icon src={CalendarDays} class="h-6 w-5 text-gray-400" aria-hidden="true" />
</dt>
<dd class="text-sm leading-6 text-gray-500">
<time datetime="2023-01-31">{snapshot?.firstTransactionTime}</time>
<Date date={snapshot?.firstTransactionTime?.toDate()} />
</dd>
</div>
<div class="mt-4 flex w-full flex-none gap-x-4 px-6">
Expand Down
4 changes: 2 additions & 2 deletions ui/src/lib/components/PortfolioPositionRow.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</div>
</td>
<td class="hidden whitespace-nowrap px-3 py-2 text-right text-sm text-gray-500 md:table-cell">
{Intl.NumberFormat('de', {
{Intl.NumberFormat(navigator.language, {
maximumFractionDigits: 2
}).format(position.amount)}
</td>
Expand Down Expand Up @@ -58,7 +58,7 @@
: 'text-green-500'} whitespace-nowrap px-3 py-2 text-right text-sm"
>
<div>
{Intl.NumberFormat('de', {
{Intl.NumberFormat(navigator.language, {
maximumFractionDigits: 2
}).format(perf)} %
<Icon
Expand Down
2 changes: 1 addition & 1 deletion ui/src/lib/components/PortfolioPositionsTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
: 'text-green-500'} px-3 py-3.5 text-right text-sm font-semibold"
>
<div>
{Intl.NumberFormat('de', {
{Intl.NumberFormat(navigator.language, {
maximumFractionDigits: 2
}).format(perf)} %
<Icon
Expand Down
2 changes: 1 addition & 1 deletion ui/src/lib/intl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export function currency(value: number, currency: string): string {
const formatter = Intl.NumberFormat('de', {
const formatter = Intl.NumberFormat(navigator.language, {
style: 'currency',
currency: currency
});
Expand Down
1 change: 0 additions & 1 deletion ui/src/routes/portfolios/[...name]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
export let data: PageData;
</script>

Hey from there
<PortfolioBreadcrumb portfolio={data.portfolio} snapshot={data.snapshot} />
<PortfolioPositionsTable snapshot={data.snapshot} />

0 comments on commit cb342c5

Please sign in to comment.