| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- <script>
- import CurrentPositionChart from '../../components/CurrentPositionChart.svelte';
- import { onMount } from 'svelte';
- import { authentication } from '../store.js';
- import { fade } from 'svelte/transition';
- import { goto } from '$app/navigation';
- import { getRequest } from '../../utils/api.js';
- import MarketDistributionChart from '../../components/MarketDistributionChart.svelte';
- let authToken;
- let data = {};
- let isLoading = true;
- let currency;
- let total = 0;
- let chartView = 'positions';
- onMount(() => {
- return authentication.subscribe(async (auth) => {
- if (new Date(auth?.expirationDate) < new Date()) {
- await goto('/logout');
- }
- if (!auth || !auth.token) {
- await goto('/logout');
- } else {
- const defaultCurrency = localStorage.getItem('defaultCurrency');
- currency = defaultCurrency || 'USD';
- authToken = auth.token;
- await fetchPortfolio(currency);
- }
- });
- });
- async function fetchPortfolio(currency) {
- try {
- const response = await getRequest(
- `${import.meta.env.VITE_STOCKS_HOST}/api/portfolios?currency=${currency}`,
- {},
- authToken
- );
- if (response.ok) {
- const portfolio = await response.json();
- if (portfolio?.length) {
- data = {
- ...portfolio[0],
- stocks: [...portfolio[0].stocks].sort((a, b) => a.total - b.total)
- };
- total = portfolio[0].totalValue;
- } else {
- data = {};
- total = 0;
- }
- } else {
- const error = await response.json();
- console.error('Failed to find portfolio info:', error);
- data = {};
- total = 0;
- }
- } catch (error) {
- console.error('Failed to fetch insights:', error);
- await goto('/logout');
- } finally {
- isLoading = false;
- }
- }
- function updateCurrency(event) {
- currency = event.target.value;
- isLoading = true;
- fetchPortfolio(currency);
- }
- </script>
- <svelte:head>
- <title>Insights</title>
- <meta name="description" content="Insights" />
- </svelte:head>
- {#if isLoading}
- <div in:fade class="text-center py-6 text-gray-500 dark:text-gray-300">Loading...</div>
- {:else}
- <div in:fade class="space-y-6">
- <div class="flex justify-end mb-4">
- <select
- class="w-52 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-400"
- on:change={updateCurrency}
- bind:value={currency}
- >
- <option value="BRL">BRL</option>
- <option value="EUR">EUR</option>
- <option value="USD">USD</option>
- </select>
- </div>
- <!-- Chart View Selector -->
- <div class="flex justify-center gap-4 mb-4">
- <button
- class="px-4 py-2 rounded-md text-sm font-medium transition
- {chartView === 'positions'
- ? 'bg-blue-500 text-white'
- : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-100'}"
- on:click={() => chartView = 'positions'}
- >
- By Position
- </button>
- <button
- class="px-4 py-2 rounded-md text-sm font-medium transition
- {chartView === 'markets'
- ? 'bg-blue-500 text-white'
- : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-100'}"
- on:click={() => chartView = 'markets'}
- >
- By Market
- </button>
- </div>
- <!-- Chart Display -->
- {#if chartView === 'positions'}
- <CurrentPositionChart {data} {currency} {total} />
- {:else if chartView === 'markets'}
- <MarketDistributionChart {data} {currency} {total} />
- {/if}
- </div>
- {/if}
|