ソースを参照

update stocks page

Daniel Bohry 9 ヶ月 前
コミット
d6705f6c4e
1 ファイル変更105 行追加124 行削除
  1. 105 124
      src/routes/stocks/+page.svelte

+ 105 - 124
src/routes/stocks/+page.svelte

@@ -2,23 +2,24 @@
 	import { onMount } from 'svelte';
 	import { fade } from 'svelte/transition';
 
-	let myStocks = ['AAPL', 'AME', 'BVMF:ABEV3'];
 	let result = [];
+	let isLoading = true;
 
 	onMount(async () => {
-		if (myStocks.length !== 0) {
-			for (const code of myStocks) {
-				const stockInfo = await get(code);
-				if (stockInfo) {
-					result = [...result, stockInfo[0]];
-				}
-			}
+		const stockInfo = await get(undefined);
+		if (stockInfo) {
+			result = stockInfo;
+			isLoading = false;
 		}
 	});
 
 	async function get(stock) {
+		let query = stock === undefined
+			? '/api/stocks'
+			: '/api/stocks?q=' + stock;
+
 		try {
-			const response = await fetch(import.meta.env.VITE_STOCKS_HOST + '/api/stocks?q=' + stock, {
+			const response = await fetch(import.meta.env.VITE_STOCKS_HOST + query, {
 				method: 'GET'
 			});
 
@@ -35,25 +36,13 @@
 		}
 	}
 
-	async function add(event) {
-		event.preventDefault();
-
-		const formData = new FormData(event.target);
-		const stock = formData.get('stock');
-
-		if (!stock) {
-			alert('Please enter a stock code.');
-			return;
-		}
-
-		const stockInfo = await get(stock);
-
-		if (stockInfo) {
-			if (result.some((item) => item.code === stockInfo[0].code)) return;
-			result = [...result, stockInfo[0]];
-			event.target.reset();
-		}
+	function formatCurrency(price, currency) {
+		return price.toLocaleString('en-US', {
+			style: 'currency',
+			currency: currency ? currency : 'USD'
+		});
 	}
+
 </script>
 
 <svelte:head>
@@ -61,104 +50,96 @@
 	<meta name="description" content="Stocks" />
 </svelte:head>
 
-<div in:fade>
-	<div class="card">
-		<form on:submit={add}>
-			<input
-				type="text"
-				name="stock"
-				placeholder="Enter a stock name or code"
-				class="input-field"
-			/>
-			<button type="submit" class="add-button">Add</button>
-		</form>
-	</div>
-
-	{#if result.length !== 0}
-		<div in:fade class="result">
-			{#each result as stock}
-				<div class="card card2">
-					<div class="stock-info">
-						<div class="stock-code">{stock.code}</div>
-						<div class="stock-name">{stock.name}</div>
-					</div>
-					<div class="stock-details">
-						<div class="stock-currency">{stock.currency}</div>
-						<div class="stock-price">{stock.price}</div>
+{#if isLoading}
+	<div in:fade>Loading...</div>
+{:else}
+	<div in:fade>
+		{#if result.length !== 0}
+			<div in:fade class="result">
+				{#each result as stock}
+					<div class="card card2">
+						<div class="stock-info">
+							<div class="stock-code">{stock.code}</div>
+							<div class="stock-name">{stock.name}</div>
+						</div>
+						<div class="stock-details">
+							<div class="stock-currency">{stock.currency}</div>
+							<div class="stock-price">{formatCurrency(stock.price, stock.currency)}</div>
+						</div>
 					</div>
-				</div>
-			{/each}
-		</div>
-	{/if}
-</div>
+				{/each}
+			</div>
+		{/if}
+	</div>
+{/if}
 
 <style>
-	.result {
-		margin-top: 1rem;
-		display: flex;
-		flex-wrap: wrap;
-		gap: 2rem;
-	}
-
-	.card {
-		flex: 1 1 300px;
-	}
-
-	.card2 {
-		background-color: #fafafa;
-		border: 1px solid #eee;
-		border-radius: 12px;
-		max-width: 267px;
-	}
-
-	.card:hover {
-		transform: translateY(-10px);
-	}
-
-	.stock-info {
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
-		margin-bottom: 10px;
-	}
-
-	.stock-code {
-		font-size: 1.5rem;
-		font-weight: bold;
-		color: #333;
-	}
-
-	.stock-name {
-		font-size: 1.1rem;
-		font-weight: normal;
-		color: #555;
-		text-align: right;
-	}
-
-	.stock-info:after {
-		content: '';
-		display: block;
-		width: 100%;
-		height: 1px;
-		background-color: #ddd;
-		margin-top: 10px;
-	}
-
-	.stock-details {
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
-		margin-top: 15px;
-	}
-
-	.stock-currency {
-		font-size: 1rem;
-		color: #888;
-	}
-
-	.stock-price {
-		font-size: 1.5rem;
-		font-weight: bold;
-		color: #27ae60;
-	}
+    .result {
+        margin-top: 1rem;
+        display: flex;
+        flex-wrap: wrap;
+        gap: 2rem;
+    }
+
+    .card {
+        flex: 1 1 300px;
+    }
+
+    .card2 {
+        background-color: #fafafa;
+        border: 1px solid #eee;
+        border-radius: 12px;
+        max-width: 267px;
+    }
+
+    .card:hover {
+        transform: translateY(-10px);
+    }
+
+    .stock-info {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+    }
+
+    .stock-code {
+        font-size: 1.5rem;
+        font-weight: bold;
+        color: #333;
+    }
+
+    .stock-name {
+        font-size: 1.1rem;
+        font-weight: normal;
+        color: #555;
+        text-align: right;
+    }
+
+    .stock-info:after {
+        content: '';
+        display: block;
+        width: 100%;
+        height: 1px;
+        background-color: #ddd;
+        margin-top: 10px;
+    }
+
+    .stock-details {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-top: 15px;
+    }
+
+    .stock-currency {
+        font-size: 1rem;
+        color: #888;
+    }
+
+    .stock-price {
+        font-size: 1.5rem;
+        font-weight: bold;
+        color: #27ae60;
+    }
 </style>