Explorar o código

format classes

Daniel Bohry hai 9 meses
pai
achega
eec7b39b1c

+ 2 - 2
.github/workflows/build.yml

@@ -2,7 +2,7 @@ name: Build
 
 on:
   pull_request:
-    branches: [ main ]
+    branches: [main]
 
 jobs:
   build:
@@ -21,4 +21,4 @@ jobs:
         run: npm install
 
       - name: Build the application
-        run: npm run build
+        run: npm run build

+ 1 - 1
.github/workflows/buildAndRelease.yml

@@ -2,7 +2,7 @@ name: Build and Release
 
 on:
   push:
-    branches: [ main ]
+    branches: [main]
 
 jobs:
   build-and-release:

+ 2 - 2
postcss.config.js

@@ -1,5 +1,5 @@
 export default {
 	plugins: {
-		"@tailwindcss/postcss": {},
+		'@tailwindcss/postcss': {}
 	}
-}
+};

+ 5 - 5
src/app.css

@@ -1,12 +1,12 @@
-@import "tailwindcss";
+@import 'tailwindcss';
 @import '@fontsource/fira-mono';
 
 @custom-variant dark (&:where(.dark, .dark *));
 
-html[data-theme="loading"] {
-    display: none;
+html[data-theme='loading'] {
+	display: none;
 }
 
 body {
-    @apply bg-white text-gray-900 dark:bg-gray-900 dark:text-white;
-}
+	@apply bg-white text-gray-900 dark:bg-gray-900 dark:text-white;
+}

+ 25 - 25
src/app.html

@@ -1,28 +1,28 @@
 <!doctype html>
 <html lang="en" data-theme="loading">
-<head>
-	<script>
-		(() => {
-			const theme = localStorage.getItem('theme') || 'light';
-			if (theme === 'dark') {
-				document.documentElement.classList.add('dark');
-			} else {
-				document.documentElement.classList.remove('dark');
-			}
-			document.documentElement.dataset.theme = 'ready';
-		})();
-	</script>
+	<head>
+		<script>
+			(() => {
+				const theme = localStorage.getItem('theme') || 'light';
+				if (theme === 'dark') {
+					document.documentElement.classList.add('dark');
+				} else {
+					document.documentElement.classList.remove('dark');
+				}
+				document.documentElement.dataset.theme = 'ready';
+			})();
+		</script>
 
-	<meta charset="utf-8" />
-	<link rel="icon" href="%sveltekit.assets%/favicon.png" />
-	<link
-		href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
-		rel="stylesheet"
-	/>
-	<meta name="viewport" content="width=device-width, initial-scale=1" />
-	%sveltekit.head%
-</head>
-<body data-sveltekit-preload-data="hover">
-<div style="display: contents">%sveltekit.body%</div>
-</body>
-</html>
+		<meta charset="utf-8" />
+		<link rel="icon" href="%sveltekit.assets%/favicon.png" />
+		<link
+			href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
+			rel="stylesheet"
+		/>
+		<meta name="viewport" content="width=device-width, initial-scale=1" />
+		%sveltekit.head%
+	</head>
+	<body data-sveltekit-preload-data="hover">
+		<div style="display: contents">%sveltekit.body%</div>
+	</body>
+</html>

+ 6 - 2
src/components/AddStock.svelte

@@ -52,7 +52,9 @@
 
 			{#if searchResults.length > 0}
 				<div class="mt-4 space-y-2">
-					<ul class="divide-y divide-gray-200 dark:divide-gray-700 bg-white dark:bg-gray-800 rounded-lg shadow-sm overflow-hidden">
+					<ul
+						class="divide-y divide-gray-200 dark:divide-gray-700 bg-white dark:bg-gray-800 rounded-lg shadow-sm overflow-hidden"
+					>
 						{#each searchResults as result}
 							<li
 								class="flex items-center justify-between px-4 py-3 hover:bg-gray-100 dark:hover:bg-gray-700 cursor-pointer"
@@ -61,7 +63,9 @@
 								<span class="text-gray-800 dark:text-gray-100 text-sm">
 									({result.code}) {result.name}
 								</span>
-								<button class="bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 text-sm rounded-md transition">
+								<button
+									class="bg-blue-500 hover:bg-blue-600 text-white px-3 py-1 text-sm rounded-md transition"
+								>
 									+
 								</button>
 							</li>

+ 20 - 4
src/components/CurrentPositionChart.svelte

@@ -20,7 +20,11 @@
 		id: 'centerText',
 		beforeDraw(chart) {
 			const centerTextOptions = chart.options.plugins.centerText;
-			if (!centerTextOptions || centerTextOptions.displayTotal === undefined || !centerTextOptions.displayCurrency) {
+			if (
+				!centerTextOptions ||
+				centerTextOptions.displayTotal === undefined ||
+				!centerTextOptions.displayCurrency
+			) {
 				return;
 			}
 
@@ -73,9 +77,21 @@
 					label: 'Stock Distribution',
 					data: stockTotals,
 					backgroundColor: [
-						'#1abc9c', '#2ecc71', '#3498db', '#9b59b6', '#f1c40f',
-						'#e67e22', '#e74c3c', '#34495e', '#16a085', '#27ae60',
-						'#2980b9', '#8e44ad', '#f39c12', '#d35400', '#c0392b'
+						'#1abc9c',
+						'#2ecc71',
+						'#3498db',
+						'#9b59b6',
+						'#f1c40f',
+						'#e67e22',
+						'#e74c3c',
+						'#34495e',
+						'#16a085',
+						'#27ae60',
+						'#2980b9',
+						'#8e44ad',
+						'#f39c12',
+						'#d35400',
+						'#c0392b'
 					],
 					borderColor: '#fff',
 					borderWidth: 1

+ 15 - 11
src/components/Header.svelte

@@ -38,29 +38,31 @@
 		<nav>
 			<ul class="flex gap-6 text-sm font-medium text-gray-700 dark:text-gray-300">
 				{#if username}
-<!--					<li aria-current={$page.url.pathname === '/home' ? 'page' : undefined}>-->
-<!--						<a-->
-<!--							href="/home"-->
-<!--							class="hover:text-theme-light dark:hover:text-theme-dark transition-colors"-->
-<!--						>Home</a>-->
-<!--					</li>-->
+					<!--					<li aria-current={$page.url.pathname === '/home' ? 'page' : undefined}>-->
+					<!--						<a-->
+					<!--							href="/home"-->
+					<!--							class="hover:text-theme-light dark:hover:text-theme-dark transition-colors"-->
+					<!--						>Home</a>-->
+					<!--					</li>-->
 					<li aria-current={$page.url.pathname === '/stocks' ? 'page' : undefined}>
 						<a
 							href="/stocks"
-							class="hover:text-theme-light dark:hover:text-theme-dark transition-colors"
-						>Stocks</a>
+							class="hover:text-theme-light dark:hover:text-theme-dark transition-colors">Stocks</a
+						>
 					</li>
 					<li aria-current={$page.url.pathname === '/portfolio' ? 'page' : undefined}>
 						<a
 							href="/portfolio"
 							class="hover:text-theme-light dark:hover:text-theme-dark transition-colors"
-						>Portfolio</a>
+							>Portfolio</a
+						>
 					</li>
 					<li aria-current={$page.url.pathname === '/insights' ? 'page' : undefined}>
 						<a
 							href="/insights"
 							class="hover:text-theme-light dark:hover:text-theme-dark transition-colors"
-						>Insights</a>
+							>Insights</a
+						>
 					</li>
 				{/if}
 			</ul>
@@ -69,7 +71,9 @@
 		<!-- Right: user profile -->
 		<div class="flex items-center gap-3">
 			<a href="/profile" class="flex items-center gap-2 group">
-				<span class="text-sm text-gray-600 dark:text-gray-300 group-hover:text-theme-light dark:group-hover:text-theme-dark">
+				<span
+					class="text-sm text-gray-600 dark:text-gray-300 group-hover:text-theme-light dark:group-hover:text-theme-dark"
+				>
 					{username}
 				</span>
 				<img

+ 15 - 9
src/components/MarketDistributionChart.svelte

@@ -20,7 +20,11 @@
 		id: 'centerText',
 		beforeDraw(chart) {
 			const centerTextOptions = chart.options.plugins.centerText;
-			if (!centerTextOptions || centerTextOptions.displayTotal === undefined || !centerTextOptions.displayCurrency) {
+			if (
+				!centerTextOptions ||
+				centerTextOptions.displayTotal === undefined ||
+				!centerTextOptions.displayCurrency
+			) {
 				return;
 			}
 
@@ -56,7 +60,7 @@
 			Others: 0
 		};
 
-		stocks.forEach(stock => {
+		stocks.forEach((stock) => {
 			const code = stock.code;
 
 			if (code.startsWith('BVMF:')) {
@@ -89,12 +93,14 @@
 
 		const chartData = {
 			labels,
-			datasets: [{
-				data: values,
-				backgroundColor: ['#3498db', '#2ecc71', '#f39c12', '#9b59b6'],
-				borderColor: '#fff',
-				borderWidth: 1
-			}]
+			datasets: [
+				{
+					data: values,
+					backgroundColor: ['#3498db', '#2ecc71', '#f39c12', '#9b59b6'],
+					borderColor: '#fff',
+					borderWidth: 1
+				}
+			]
 		};
 
 		const chartOptions = {
@@ -106,7 +112,7 @@
 				},
 				tooltip: {
 					callbacks: {
-						label: function(tooltipItem) {
+						label: function (tooltipItem) {
 							const value = tooltipItem.raw;
 							const label = tooltipItem.label;
 							return `${label}: ${formatCurrency(value, currency)}`;

+ 2 - 2
src/components/StockPriceHistory.svelte

@@ -27,8 +27,8 @@
 	}
 
 	function renderChart(data) {
-		const labels = data.map(item => new Date(item.createdAt).toLocaleDateString());
-		const prices = data.map(item => item.price);
+		const labels = data.map((item) => new Date(item.createdAt).toLocaleDateString());
+		const prices = data.map((item) => item.price);
 
 		if (chartInstance) {
 			chartInstance.destroy();

+ 1 - 1
src/routes/+error.svelte

@@ -5,4 +5,4 @@
 	onMount(() => {
 		goto('/login');
 	});
-</script>
+</script>

+ 6 - 2
src/routes/+layout.svelte

@@ -5,14 +5,18 @@
 	let year = new Date().getFullYear();
 </script>
 
-<div class="flex flex-col min-h-screen bg-gray-100 dark:bg-gray-950 text-gray-900 dark:text-gray-100">
+<div
+	class="flex flex-col min-h-screen bg-gray-100 dark:bg-gray-950 text-gray-900 dark:text-gray-100"
+>
 	<Header />
 
 	<main class="flex-1 flex flex-col px-4 py-6 w-full max-w-4xl mx-auto box-border">
 		<slot />
 	</main>
 
-	<footer class="flex flex-col items-center justify-center py-3 text-sm text-gray-500 dark:text-gray-400">
+	<footer
+		class="flex flex-col items-center justify-center py-3 text-sm text-gray-500 dark:text-gray-400"
+	>
 		<p>© {year} Lhamacorp</p>
 	</footer>
 </div>

+ 1 - 1
src/routes/+page.svelte

@@ -2,4 +2,4 @@
 	import { goto } from '$app/navigation';
 
 	goto('/stocks');
-</script>
+</script>

+ 0 - 1
src/routes/home/+page.svelte

@@ -11,7 +11,6 @@
 			}
 		});
 	});
-
 </script>
 
 <svelte:head>

+ 1 - 1
src/routes/hooks.client.js

@@ -8,4 +8,4 @@ export async function handleFetch({ request, fetch }) {
 	}
 
 	return response;
-}
+}

+ 14 - 9
src/routes/insights/+page.svelte

@@ -23,7 +23,6 @@
 			if (!auth || !auth.token) {
 				await goto('/logout');
 			} else {
-
 				const defaultCurrency = localStorage.getItem('defaultCurrency');
 				currency = defaultCurrency || 'USD';
 
@@ -81,8 +80,14 @@
 
 {#if isLoading}
 	<div in:fade class="flex justify-center items-center py-10">
-		<svg class="animate-spin h-8 w-8 text-blue-500 dark:text-blue-300" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
-			<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
+		<svg
+			class="animate-spin h-8 w-8 text-blue-500 dark:text-blue-300"
+			xmlns="http://www.w3.org/2000/svg"
+			fill="none"
+			viewBox="0 0 24 24"
+		>
+			<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
+			></circle>
 			<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z"></path>
 		</svg>
 	</div>
@@ -105,9 +110,9 @@
 			<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'} cursor-pointer"
-				on:click={() => chartView = 'positions'}
+					? 'bg-blue-500 text-white'
+					: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-100'} cursor-pointer"
+				on:click={() => (chartView = 'positions')}
 			>
 				By Position
 			</button>
@@ -115,9 +120,9 @@
 			<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'} cursor-pointer"
-				on:click={() => chartView = 'markets'}
+					? 'bg-blue-500 text-white'
+					: 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-100'} cursor-pointer"
+				on:click={() => (chartView = 'markets')}
 			>
 				By Market
 			</button>

+ 59 - 6
src/routes/login/+page.svelte

@@ -18,7 +18,7 @@
 			const storedAuth = localStorage.getItem('authentication');
 			if (storedAuth) {
 				authentication.set(JSON.parse(storedAuth));
-				goto("/portfolio");
+				goto('/portfolio');
 			}
 		} catch (error) {
 			console.error('Error parsing stored auth:', error);
@@ -109,14 +109,55 @@
 						placeholder="Password"
 						class="w-full px-4 py-2 pr-10 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-500"
 					/>
+					<!-- Visibility toggle -->
 					<span
-						class="absolute inset-y-0 right-3 flex items-center cursor-pointer text-gray-500 dark:text-gray-400 text-lg"
 						on:click={togglePasswordVisibility}
+						class="absolute inset-y-0 right-3 flex items-center text-gray-500 dark:text-gray-400 cursor-pointer"
 					>
 						{#if showPassword}
-							👁️‍🗨️
+							<!-- Eye Off Icon -->
+							<svg
+								xmlns="http://www.w3.org/2000/svg"
+								class="h-5 w-5"
+								fill="none"
+								viewBox="0 0 24 24"
+								stroke="currentColor"
+							>
+								<path
+									stroke-linecap="round"
+									stroke-linejoin="round"
+									stroke-width="2"
+									d="M13.875 18.825A10.05 10.05 0 0112 19c-5.523 0-10-4.03-10-9s4.477-9 10-9a9.96 9.96 0 014.586 1.055M15 12a3 3 0 11-6 0 3 3 0 016 0z"
+								/>
+								<path
+									stroke-linecap="round"
+									stroke-linejoin="round"
+									stroke-width="2"
+									d="M2.458 12C3.732 15.943 7.46 19 12 19c1.5 0 2.91-.358 4.158-.99M19.742 16.018a9.97 9.97 0 002.258-4.018M15 12a3 3 0 00-3-3m0 0a3 3 0 01-3 3"
+								/>
+							</svg>
 						{:else}
-							👁️‍🗨️
+							<!-- Eye Icon -->
+							<svg
+								xmlns="http://www.w3.org/2000/svg"
+								class="h-5 w-5"
+								fill="none"
+								viewBox="0 0 24 24"
+								stroke="currentColor"
+							>
+								<path
+									stroke-linecap="round"
+									stroke-linejoin="round"
+									stroke-width="2"
+									d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
+								/>
+								<path
+									stroke-linecap="round"
+									stroke-linejoin="round"
+									stroke-width="2"
+									d="M2.458 12C3.732 15.943 7.46 19 12 19c4.54 0 8.268-3.057 9.542-7-1.274-3.943-5.002-7-9.542-7S3.732 8.057 2.458 12z"
+								/>
+							</svg>
 						{/if}
 					</span>
 				</div>
@@ -128,8 +169,20 @@
 					disabled={isDisabled}
 				>
 					{#if isDisabled}
-						<svg class="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
-							<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
+						<svg
+							class="animate-spin h-5 w-5 text-white"
+							xmlns="http://www.w3.org/2000/svg"
+							fill="none"
+							viewBox="0 0 24 24"
+						>
+							<circle
+								class="opacity-25"
+								cx="12"
+								cy="12"
+								r="10"
+								stroke="currentColor"
+								stroke-width="4"
+							></circle>
 							<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z"></path>
 						</svg>
 						<span>Logging in...</span>

+ 119 - 62
src/routes/portfolio/+page.svelte

@@ -44,7 +44,6 @@
 			if (!auth || !auth.token) {
 				await goto('/logout');
 			} else {
-
 				const defaultCurrency = localStorage.getItem('defaultCurrency');
 				currency = defaultCurrency || 'USD';
 
@@ -65,7 +64,11 @@
 
 	async function fetchPortfolio() {
 		try {
-			const response = await getRequest(`${import.meta.env.VITE_STOCKS_HOST}/api/portfolios?currency=${currency}`, {}, authToken);
+			const response = await getRequest(
+				`${import.meta.env.VITE_STOCKS_HOST}/api/portfolios?currency=${currency}`,
+				{},
+				authToken
+			);
 
 			if (response.ok) {
 				await update(response.json());
@@ -243,9 +246,7 @@
 	}
 
 	function formatCode(code) {
-		return code.includes(':')
-			? code.split(':')[1]
-			: code;
+		return code.includes(':') ? code.split(':')[1] : code;
 	}
 
 	function getFlag(code) {
@@ -299,8 +300,14 @@
 
 {#if isLoading}
 	<div in:fade class="flex justify-center items-center py-10">
-		<svg class="animate-spin h-8 w-8 text-blue-500 dark:text-blue-300" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
-			<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
+		<svg
+			class="animate-spin h-8 w-8 text-blue-500 dark:text-blue-300"
+			xmlns="http://www.w3.org/2000/svg"
+			fill="none"
+			viewBox="0 0 24 24"
+		>
+			<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
+			></circle>
 			<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z"></path>
 		</svg>
 	</div>
@@ -359,10 +366,18 @@
 	/>
 
 	{#if showDeleteConfirm}
-		<div class="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-white dark:bg-gray-800 p-6 rounded-xl shadow-lg z-50 text-center">
+		<div
+			class="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-white dark:bg-gray-800 p-6 rounded-xl shadow-lg z-50 text-center"
+		>
 			<div class="flex justify-center gap-4">
-				<button class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg" on:click={confirmDeleteAction}>Confirm deletion</button>
-				<button class="bg-gray-300 hover:bg-gray-400 text-gray-800 px-4 py-2 rounded-lg" on:click={cancelDelete}>Cancel</button>
+				<button
+					class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg"
+					on:click={confirmDeleteAction}>Confirm deletion</button
+				>
+				<button
+					class="bg-gray-300 hover:bg-gray-400 text-gray-800 px-4 py-2 rounded-lg"
+					on:click={cancelDelete}>Cancel</button
+				>
 			</div>
 		</div>
 	{/if}
@@ -370,16 +385,18 @@
 	<div in:fade class="overflow-x-auto mt-6 rounded-xl shadow">
 		<table class="min-w-full bg-white dark:bg-gray-900 text-sm">
 			<thead class="bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200">
-			<tr>
-				<th class="px-4 py-3 text-left font-semibold">Total Value</th>
-				<th class="px-4 py-3 text-left font-semibold">Total Assets</th>
-			</tr>
+				<tr>
+					<th class="px-4 py-3 text-left font-semibold">Total Value</th>
+					<th class="px-4 py-3 text-left font-semibold">Total Assets</th>
+				</tr>
 			</thead>
 			<tbody>
-			<tr class="border-t border-gray-200 dark:border-gray-700">
-				<td class="px-4 py-3 font-semibold text-gray-800 dark:text-gray-100">{formatCurrency(totalValue)}</td>
-				<td class="px-4 py-3 font-semibold text-gray-800 dark:text-gray-100">{totalAssets}</td>
-			</tr>
+				<tr class="border-t border-gray-200 dark:border-gray-700">
+					<td class="px-4 py-3 font-semibold text-gray-800 dark:text-gray-100"
+						>{formatCurrency(totalValue)}</td
+					>
+					<td class="px-4 py-3 font-semibold text-gray-800 dark:text-gray-100">{totalAssets}</td>
+				</tr>
 			</tbody>
 		</table>
 	</div>
@@ -387,60 +404,100 @@
 	<div in:fade class="overflow-x-auto mt-6 rounded-xl shadow">
 		<table class="min-w-full bg-white dark:bg-gray-900 text-sm">
 			<thead class="bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200">
-			<tr>
-				<th class="px-4 py-3">Code</th>
-				<th class="px-4 py-3">Name</th>
-				<th class="px-4 py-3">Qty</th>
-				<th class="px-4 py-3">Price</th>
-				<th class="px-4 py-3">Total</th>
-				<th class="px-4 py-3">% of Portfolio</th>
-				<th class="px-4 py-3"></th>
-			</tr>
+				<tr>
+					<th class="px-4 py-3">Code</th>
+					<th class="px-4 py-3">Name</th>
+					<th class="px-4 py-3">Qty</th>
+					<th class="px-4 py-3">Price</th>
+					<th class="px-4 py-3">Total</th>
+					<th class="px-4 py-3">% of Portfolio</th>
+					<th class="px-4 py-3"></th>
+				</tr>
 			</thead>
 			<tbody>
-			{#each result as stock}
-				<tr class="odd:bg-gray-50 even:bg-gray-100 dark:odd:bg-gray-800 dark:even:bg-gray-700 hover:bg-blue-50 dark:hover:bg-blue-900 transition">
-					<td class="px-4 py-2 font-mono font-semibold text-blue-700 dark:text-blue-300 cursor-pointer" title={stock.code} on:click={() => openStock(stock.code)}>
-						<div class="inline-flex items-center gap-2">
-							<img src={`https://flagcdn.com/w40/${getFlag(stock.code)}.png`} alt="{getFlag(stock.code)} flag" class="w-5 h-auto" />
-							{formatCode(stock.code)}
-						</div>
-					</td>
-					<td class="px-4 py-2 text-gray-700 dark:text-gray-300">{stock.name}</td>
-					<td class="px-4 py-2">
-						<form id="updateQuantity" on:submit|preventDefault={updateStockQuantity} class="flex items-center">
-							<input type="hidden" name="code" value={stock.code} />
-							<input type="number" name="quantity" min="0" value={stock.quantity}
-										 class="w-16 px-2 py-1 text-right border rounded-lg text-sm text-gray-800 dark:text-gray-100 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-300" on:input={handleInputChange} />
-						</form>
-					</td>
-					<td class="px-4 py-2 font-semibold text-green-600 dark:text-green-400">{formatCurrency(stock.price)}</td>
-					<td class="px-4 py-2 font-semibold text-gray-800 dark:text-gray-200">{formatCurrency(stock.total)}</td>
-					<td class="px-4 py-2 text-blue-600 dark:text-blue-400">{calculatePercentage(stock.total, totalValue)}%</td>
-					<td class="px-4 py-2 text-right">
-						<button on:click={() => confirmDelete(stock.code)} aria-label="Delete" title="remove"
-										class="bg-red-600 hover:bg-red-700 text-white rounded-full p-2 shadow focus:outline-none focus:ring-2 focus:ring-red-400">
-							<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4">
-								<polyline points="3 6 5 6 21 6"></polyline>
-								<path d="M19 6l-1 14H6L5 6"></path>
-								<path d="M10 11v6"></path>
-								<path d="M14 11v6"></path>
-								<path d="M9 6V4h6v2"></path>
-							</svg>
-						</button>
-					</td>
-				</tr>
-			{/each}
+				{#each result as stock}
+					<tr
+						class="odd:bg-gray-50 even:bg-gray-100 dark:odd:bg-gray-800 dark:even:bg-gray-700 hover:bg-blue-50 dark:hover:bg-blue-900 transition"
+					>
+						<td
+							class="px-4 py-2 font-mono font-semibold text-blue-700 dark:text-blue-300 cursor-pointer"
+							title={stock.code}
+							on:click={() => openStock(stock.code)}
+						>
+							<div class="inline-flex items-center gap-2">
+								<img
+									src={`https://flagcdn.com/w40/${getFlag(stock.code)}.png`}
+									alt="{getFlag(stock.code)} flag"
+									class="w-5 h-auto"
+								/>
+								{formatCode(stock.code)}
+							</div>
+						</td>
+						<td class="px-4 py-2 text-gray-700 dark:text-gray-300">{stock.name}</td>
+						<td class="px-4 py-2">
+							<form
+								id="updateQuantity"
+								on:submit|preventDefault={updateStockQuantity}
+								class="flex items-center"
+							>
+								<input type="hidden" name="code" value={stock.code} />
+								<input
+									type="number"
+									name="quantity"
+									min="0"
+									value={stock.quantity}
+									class="w-16 px-2 py-1 text-right border rounded-lg text-sm text-gray-800 dark:text-gray-100 bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-300"
+									on:input={handleInputChange}
+								/>
+							</form>
+						</td>
+						<td class="px-4 py-2 font-semibold text-green-600 dark:text-green-400"
+							>{formatCurrency(stock.price)}</td
+						>
+						<td class="px-4 py-2 font-semibold text-gray-800 dark:text-gray-200"
+							>{formatCurrency(stock.total)}</td
+						>
+						<td class="px-4 py-2 text-blue-600 dark:text-blue-400"
+							>{calculatePercentage(stock.total, totalValue)}%</td
+						>
+						<td class="px-4 py-2 text-right">
+							<button
+								on:click={() => confirmDelete(stock.code)}
+								aria-label="Delete"
+								title="remove"
+								class="bg-red-600 hover:bg-red-700 text-white rounded-full p-2 shadow focus:outline-none focus:ring-2 focus:ring-red-400"
+							>
+								<svg
+									viewBox="0 0 24 24"
+									fill="none"
+									stroke="currentColor"
+									stroke-width="2"
+									stroke-linecap="round"
+									stroke-linejoin="round"
+									class="w-4 h-4"
+								>
+									<polyline points="3 6 5 6 21 6"></polyline>
+									<path d="M19 6l-1 14H6L5 6"></path>
+									<path d="M10 11v6"></path>
+									<path d="M14 11v6"></path>
+									<path d="M9 6V4h6v2"></path>
+								</svg>
+							</button>
+						</td>
+					</tr>
+				{/each}
 			</tbody>
 		</table>
 	</div>
 
 	{#if hasChanges}
-		<button class="fixed bottom-5 right-5 bg-blue-500 hover:bg-blue-600 text-white px-6 py-3 rounded-lg shadow-lg z-50" on:click={applyChanges}>
+		<button
+			class="fixed bottom-5 right-5 bg-blue-500 hover:bg-blue-600 text-white px-6 py-3 rounded-lg shadow-lg z-50"
+			on:click={applyChanges}
+		>
 			Apply Changes
 		</button>
 	{/if}
 {:else}
 	<div class="text-gray-500 dark:text-gray-300 text-center py-6">No portfolio data available.</div>
 {/if}
-

+ 18 - 6
src/routes/profile/+page.svelte

@@ -92,7 +92,6 @@
 		theme = event.target.value;
 		savePreferenceDisabled = false;
 	}
-
 </script>
 
 <svelte:head>
@@ -114,7 +113,9 @@
 
 			<div class="space-y-4">
 				<div class="flex flex-col gap-1">
-					<label for="currency" class="text-sm font-medium text-gray-600 dark:text-gray-300">Currency</label>
+					<label for="currency" class="text-sm font-medium text-gray-600 dark:text-gray-300"
+						>Currency</label
+					>
 					<select
 						id="currency"
 						class="w-full 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-500"
@@ -128,7 +129,9 @@
 				</div>
 
 				<div class="flex flex-col gap-1">
-					<label for="orderBy" class="text-sm font-medium text-gray-600 dark:text-gray-300">Order By</label>
+					<label for="orderBy" class="text-sm font-medium text-gray-600 dark:text-gray-300"
+						>Order By</label
+					>
 					<select
 						id="orderBy"
 						class="w-full 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-500"
@@ -143,7 +146,9 @@
 				</div>
 
 				<div class="flex flex-col gap-1">
-					<label for="theme" class="text-sm font-medium text-gray-600 dark:text-gray-300">Theme</label>
+					<label for="theme" class="text-sm font-medium text-gray-600 dark:text-gray-300"
+						>Theme</label
+					>
 					<select
 						id="theme"
 						class="w-full 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-500"
@@ -169,7 +174,14 @@
 							viewBox="0 0 24 24"
 							class={`animate-spin h-5 w-5 text-white ${!isSaving ? 'hidden' : ''}`}
 						>
-							<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
+							<circle
+								class="opacity-25"
+								cx="12"
+								cy="12"
+								r="10"
+								stroke="currentColor"
+								stroke-width="4"
+							/>
 							<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z" />
 						</svg>
 						<span class={isSaving ? 'hidden' : ''}>Save preferences</span>
@@ -186,4 +198,4 @@
 			</div>
 		</div>
 	{/if}
-</div>
+</div>

+ 110 - 16
src/routes/register/+page.svelte

@@ -3,9 +3,11 @@
 	import { fade } from 'svelte/transition';
 
 	let showPassword = false;
+	let isSubmitting = false;
 
 	async function submit(event) {
 		event.preventDefault();
+		isSubmitting = true;
 
 		const formData = new FormData(event.target);
 		const username = formData.get('username');
@@ -14,25 +16,22 @@
 
 		if (!username || !password) {
 			alert('Please enter both username and password.');
+			isSubmitting = false;
 			return;
 		}
 
 		if (password !== passwordConfirm) {
 			alert('Passwords don\'t match');
+			isSubmitting = false;
 			return;
 		}
 
-		const data = {
-			username: username,
-			password: password
-		};
+		const data = { username, password };
 
 		try {
 			const response = await fetch(import.meta.env.VITE_AUTH_HOST + '/api/register', {
 				method: 'POST',
-				headers: {
-					'Content-Type': 'application/json'
-				},
+				headers: { 'Content-Type': 'application/json' },
 				body: JSON.stringify(data)
 			});
 
@@ -49,6 +48,8 @@
 		} catch (err) {
 			console.error('Error during registration:', err);
 			alert('An error occurred. Please try again.');
+		} finally {
+			isSubmitting = false;
 		}
 	}
 
@@ -59,7 +60,6 @@
 	function cancel() {
 		window.location.href = '/login';
 	}
-
 </script>
 
 <svelte:head>
@@ -78,6 +78,7 @@
 				class="w-full px-4 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-500"
 			/>
 
+			<!-- Password -->
 			<!-- Password -->
 			<div class="relative">
 				<input
@@ -87,13 +88,53 @@
 					class="w-full px-4 py-2 pr-10 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-500"
 				/>
 				<span
-					class="absolute inset-y-0 right-3 flex items-center cursor-pointer text-gray-500 dark:text-gray-400 text-lg"
+					class="absolute inset-y-0 right-3 flex items-center cursor-pointer text-gray-500 dark:text-gray-400"
 					on:click={togglePasswordVisibility}
 				>
 					{#if showPassword}
-						👁️‍🗨️
+						<!-- Eye Off Icon -->
+						<svg
+							xmlns="http://www.w3.org/2000/svg"
+							class="h-5 w-5"
+							fill="none"
+							viewBox="0 0 24 24"
+							stroke="currentColor"
+						>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M13.875 18.825A10.05 10.05 0 0112 19c-5.523 0-10-4.03-10-9s4.477-9 10-9a9.96 9.96 0 014.586 1.055M15 12a3 3 0 11-6 0 3 3 0 016 0z"
+							/>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M2.458 12C3.732 15.943 7.46 19 12 19c1.5 0 2.91-.358 4.158-.99M19.742 16.018a9.97 9.97 0 002.258-4.018"
+							/>
+						</svg>
 					{:else}
-						👁️‍🗨️
+						<!-- Eye Icon -->
+						<svg
+							xmlns="http://www.w3.org/2000/svg"
+							class="h-5 w-5"
+							fill="none"
+							viewBox="0 0 24 24"
+							stroke="currentColor"
+						>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
+							/>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M2.458 12C3.732 15.943 7.46 19 12 19c4.54 0 8.268-3.057 9.542-7-1.274-3.943-5.002-7-9.542-7S3.732 8.057 2.458 12z"
+							/>
+						</svg>
 					{/if}
 				</span>
 			</div>
@@ -107,13 +148,53 @@
 					class="w-full px-4 py-2 pr-10 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-500"
 				/>
 				<span
-					class="absolute inset-y-0 right-3 flex items-center cursor-pointer text-gray-500 dark:text-gray-400 text-lg"
+					class="absolute inset-y-0 right-3 flex items-center cursor-pointer text-gray-500 dark:text-gray-400"
 					on:click={togglePasswordVisibility}
 				>
 					{#if showPassword}
-						👁️‍🗨️
+						<!-- Eye Off Icon -->
+						<svg
+							xmlns="http://www.w3.org/2000/svg"
+							class="h-5 w-5"
+							fill="none"
+							viewBox="0 0 24 24"
+							stroke="currentColor"
+						>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M13.875 18.825A10.05 10.05 0 0112 19c-5.523 0-10-4.03-10-9s4.477-9 10-9a9.96 9.96 0 014.586 1.055M15 12a3 3 0 11-6 0 3 3 0 016 0z"
+							/>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M2.458 12C3.732 15.943 7.46 19 12 19c1.5 0 2.91-.358 4.158-.99M19.742 16.018a9.97 9.97 0 002.258-4.018"
+							/>
+						</svg>
 					{:else}
-						👁️‍🗨️
+						<!-- Eye Icon -->
+						<svg
+							xmlns="http://www.w3.org/2000/svg"
+							class="h-5 w-5"
+							fill="none"
+							viewBox="0 0 24 24"
+							stroke="currentColor"
+						>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
+							/>
+							<path
+								stroke-linecap="round"
+								stroke-linejoin="round"
+								stroke-width="2"
+								d="M2.458 12C3.732 15.943 7.46 19 12 19c4.54 0 8.268-3.057 9.542-7-1.274-3.943-5.002-7-9.542-7S3.732 8.057 2.458 12z"
+							/>
+						</svg>
 					{/if}
 				</span>
 			</div>
@@ -121,9 +202,22 @@
 			<!-- Buttons -->
 			<button
 				type="submit"
-				class="w-full bg-blue-500 hover:bg-blue-600 text-white py-2 rounded-lg transition"
+				class="w-full bg-blue-500 hover:bg-blue-600 text-white py-2 rounded-lg transition flex items-center justify-center gap-2"
+				disabled={isSubmitting}
 			>
-				Register
+				<div class="relative min-w-[150px] flex items-center justify-center gap-2">
+					<svg
+						xmlns="http://www.w3.org/2000/svg"
+						fill="none"
+						viewBox="0 0 24 24"
+						class={`h-5 w-5 animate-spin text-white ${!isSubmitting ? 'hidden' : ''}`}
+					>
+						<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
+						<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z" />
+					</svg>
+					<span class={isSubmitting ? 'hidden' : ''}>Register</span>
+					<span class={isSubmitting ? '' : 'hidden'}>Registering...</span>
+				</div>
 			</button>
 
 			<button

+ 18 - 7
src/routes/stocks/+page.svelte

@@ -59,7 +59,7 @@
 		const country = {
 			BVMF: 'br',
 			FRA: 'de',
-			ETR: 'eu',
+			ETR: 'eu'
 		};
 
 		return country[market] || 'us';
@@ -68,7 +68,6 @@
 	function openStock(code) {
 		goto(`/stocks/${code}`);
 	}
-
 </script>
 
 <svelte:head>
@@ -78,14 +77,22 @@
 
 {#if isLoading}
 	<div in:fade class="flex justify-center items-center py-10">
-		<svg class="animate-spin h-8 w-8 text-blue-500 dark:text-blue-300" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
-			<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
+		<svg
+			class="animate-spin h-8 w-8 text-blue-500 dark:text-blue-300"
+			xmlns="http://www.w3.org/2000/svg"
+			fill="none"
+			viewBox="0 0 24 24"
+		>
+			<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
+			></circle>
 			<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z"></path>
 		</svg>
 	</div>
 {:else}
 	<!-- Filter Input -->
-	<div class="mx-auto my-4 w-11/12 max-w-3xl px-4 py-4 bg-gradient-to-r from-gray-50 to-white dark:from-gray-800 dark:to-gray-900 shadow-md rounded-xl">
+	<div
+		class="mx-auto my-4 w-11/12 max-w-3xl px-4 py-4 bg-gradient-to-r from-gray-50 to-white dark:from-gray-800 dark:to-gray-900 shadow-md rounded-xl"
+	>
 		<input
 			type="text"
 			bind:value={stockQuery}
@@ -103,7 +110,9 @@
 					class="bg-white dark:bg-gray-800 border border-transparent dark:border-gray-700 hover:shadow-xl transition-all rounded-xl p-5 flex flex-col justify-between hover:-translate-y-1 duration-200"
 				>
 					<!-- Stock Info -->
-					<div class="flex justify-between items-start border-b border-gray-200 dark:border-gray-700 pb-3">
+					<div
+						class="flex justify-between items-start border-b border-gray-200 dark:border-gray-700 pb-3"
+					>
 						<div class="flex items-center gap-2 text-lg font-bold text-gray-900 dark:text-gray-100">
 							<img
 								src={`https://flagcdn.com/w40/${getFlag(stock.code)}.png`}
@@ -112,7 +121,9 @@
 							/>
 							{stock.code}
 						</div>
-						<div class="text-sm text-right text-gray-500 dark:text-gray-400 max-w-[60%] leading-snug">
+						<div
+							class="text-sm text-right text-gray-500 dark:text-gray-400 max-w-[60%] leading-snug"
+						>
 							{stock.name}
 						</div>
 					</div>

+ 46 - 20
src/routes/stocks/[code]/+page.svelte

@@ -43,7 +43,6 @@
 		}
 	}
 
-
 	function getFlag(code) {
 		const market = code.includes(':') ? code.split(':')[0].toUpperCase() : code.toUpperCase();
 
@@ -65,7 +64,9 @@
 {#if !stockInfo}
 	<div class="text-center py-8 text-lg text-gray-500 dark:text-gray-400">Loading...</div>
 {:else}
-	<div class="w-full bg-white dark:bg-gray-900 rounded-xl shadow-md p-6 box-border transition-all duration-300 max-w-6xl mx-auto mt-6">
+	<div
+		class="w-full bg-white dark:bg-gray-900 rounded-xl shadow-md p-6 box-border transition-all duration-300 max-w-6xl mx-auto mt-6"
+	>
 		<!-- Header -->
 		<div class="flex items-center gap-4 border-b border-gray-200 dark:border-gray-700 pb-6 mb-8">
 			<img
@@ -79,57 +80,81 @@
 
 		<!-- Details Grid -->
 		<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Code:</span>
-				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">{stockInfo.code}</span>
+				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg"
+					>{stockInfo.code}</span
+				>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Name:</span>
-				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">{stockInfo.name}</span>
+				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg"
+					>{stockInfo.name}</span
+				>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Description:</span>
 				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">
 					{stockInfo.description ?? 'N/A'}
 				</span>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Foundation:</span>
 				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">
 					{stockInfo.foundation ?? 'N/A'}
 				</span>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">IPO:</span>
-				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">{stockInfo.ipo ?? 'N/A'}</span>
+				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg"
+					>{stockInfo.ipo ?? 'N/A'}</span
+				>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Exchange:</span>
 				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">
 					{stockInfo.exchange ?? 'N/A'}
 				</span>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Headquarters:</span>
 				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">
 					{stockInfo.headquarters ?? 'N/A'}
 				</span>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Industry:</span>
 				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">
 					{stockInfo.industry ?? 'N/A'}
 				</span>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">Company Website:</span>
 				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">
 					{#if stockInfo.companyWebsite}
@@ -137,15 +162,17 @@
 							href={stockInfo.companyWebsite}
 							target="_blank"
 							rel="noopener noreferrer"
-							class="underline text-blue-600 dark:text-blue-400"
-						>website</a>
+							class="underline text-blue-600 dark:text-blue-400">website</a
+						>
 					{:else}
 						N/A
 					{/if}
 				</span>
 			</div>
 
-			<div class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center">
+			<div
+				class="bg-gray-50 dark:bg-gray-800 p-5 rounded-lg shadow-sm flex justify-between items-center"
+			>
 				<span class="text-gray-600 dark:text-gray-300 font-medium text-base">SEC Website:</span>
 				<span class="text-emerald-600 dark:text-emerald-400 font-semibold text-lg">
 					{#if stockInfo.secWebsite}
@@ -153,8 +180,8 @@
 							href={stockInfo.secWebsite}
 							target="_blank"
 							rel="noopener noreferrer"
-							class="underline text-blue-600 dark:text-blue-400"
-						>sec</a>
+							class="underline text-blue-600 dark:text-blue-400">sec</a
+						>
 					{:else}
 						N/A
 					{/if}
@@ -174,5 +201,4 @@
 	</div>
 
 	<StockPriceHistory code={stockInfo.code} />
-
 {/if}

+ 10 - 9
src/utils/api.js

@@ -1,14 +1,15 @@
 import { goto } from '$app/navigation';
 
 export async function getRequest(url, options = {}, token) {
-	const headers = token !== null
-		? {
-			...options.headers,
-			Authorization: `Bearer ${token}`
-		}
-		: {
-			...options.headers
-		};
+	const headers =
+		token !== null
+			? {
+					...options.headers,
+					Authorization: `Bearer ${token}`
+				}
+			: {
+					...options.headers
+				};
 
 	const response = await fetch(url, {
 		...options,
@@ -20,4 +21,4 @@ export async function getRequest(url, options = {}, token) {
 	}
 
 	return response;
-}
+}