|
@@ -2,6 +2,7 @@
|
|
|
import { authentication } from '../store.js';
|
|
import { authentication } from '../store.js';
|
|
|
import { onMount } from 'svelte';
|
|
import { onMount } from 'svelte';
|
|
|
import { fade } from 'svelte/transition';
|
|
import { fade } from 'svelte/transition';
|
|
|
|
|
+ import AddStock from '../../components/AddStock.svelte';
|
|
|
|
|
|
|
|
let portfolioId = undefined;
|
|
let portfolioId = undefined;
|
|
|
let result = [];
|
|
let result = [];
|
|
@@ -148,7 +149,7 @@
|
|
|
|
|
|
|
|
if (data.length === 1 && !alreadyInPortfolio) {
|
|
if (data.length === 1 && !alreadyInPortfolio) {
|
|
|
await addSelectedStock(data[0]);
|
|
await addSelectedStock(data[0]);
|
|
|
- closeOrOpenModal();
|
|
|
|
|
|
|
+ closeModal()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -168,7 +169,7 @@
|
|
|
}
|
|
}
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
- closeOrOpenModal();
|
|
|
|
|
|
|
+ closeModal();
|
|
|
|
|
|
|
|
await updatePortfolio(result);
|
|
await updatePortfolio(result);
|
|
|
}
|
|
}
|
|
@@ -200,9 +201,14 @@
|
|
|
updatePortfolio(result);
|
|
updatePortfolio(result);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function closeOrOpenModal() {
|
|
|
|
|
|
|
+ function openModal() {
|
|
|
searchStockResult = [];
|
|
searchStockResult = [];
|
|
|
- showModal = !showModal;
|
|
|
|
|
|
|
+ showModal = true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function closeModal() {
|
|
|
|
|
+ searchStockResult = [];
|
|
|
|
|
+ showModal = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function updateOrderBy(event) {
|
|
function updateOrderBy(event) {
|
|
@@ -237,7 +243,7 @@
|
|
|
class="btn btn-primary btn-sm"
|
|
class="btn btn-primary btn-sm"
|
|
|
data-toggle="modal"
|
|
data-toggle="modal"
|
|
|
data-target="#exampleModal"
|
|
data-target="#exampleModal"
|
|
|
- on:click={closeOrOpenModal}
|
|
|
|
|
|
|
+ on:click={openModal}
|
|
|
>
|
|
>
|
|
|
Add
|
|
Add
|
|
|
</button>
|
|
</button>
|
|
@@ -251,54 +257,29 @@
|
|
|
</select>
|
|
</select>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- {#if showModal}
|
|
|
|
|
- <div class="modal-container">
|
|
|
|
|
- <div class="modal-content">
|
|
|
|
|
- <form on:submit|preventDefault={handleSubmit}>
|
|
|
|
|
- <div class="row">
|
|
|
|
|
- <div class="col">
|
|
|
|
|
- <input
|
|
|
|
|
- type="text"
|
|
|
|
|
- class="form-control"
|
|
|
|
|
- placeholder="stock code or name"
|
|
|
|
|
- name="stock_code"
|
|
|
|
|
- oninput="this.value = this.value.toUpperCase()"
|
|
|
|
|
- autocomplete="off"
|
|
|
|
|
- autofocus
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="col">
|
|
|
|
|
- <input
|
|
|
|
|
- type="reset"
|
|
|
|
|
- value="cancel"
|
|
|
|
|
- class="btn btn-danger"
|
|
|
|
|
- on:click={closeOrOpenModal}
|
|
|
|
|
- />
|
|
|
|
|
- <input type="submit" value="search" class="btn btn-primary" />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </form>
|
|
|
|
|
-
|
|
|
|
|
- {#if searchStockResult.length > 0}
|
|
|
|
|
- <div class="modal-result">
|
|
|
|
|
- <div class="card" style="width: 100%;">
|
|
|
|
|
- <ul class="list-group list-group-flush">
|
|
|
|
|
- {#each searchStockResult as result}
|
|
|
|
|
- <li
|
|
|
|
|
- class="list-group-item d-flex justify-content-between align-items-center"
|
|
|
|
|
- on:click={addSelectedStock(result)}
|
|
|
|
|
- >
|
|
|
|
|
- ({result.code}) {result.name}
|
|
|
|
|
- <button class="btn btn-primary btn-sm">+</button>
|
|
|
|
|
- </li>
|
|
|
|
|
- {/each}
|
|
|
|
|
- </ul>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- {/if}
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- {/if}
|
|
|
|
|
|
|
+ <AddStock
|
|
|
|
|
+ show={showModal}
|
|
|
|
|
+ onClose={closeModal}
|
|
|
|
|
+ onSearch={async (code) => {
|
|
|
|
|
+ const data = await searchStock(code);
|
|
|
|
|
+ if (!data || data.length === 0) {
|
|
|
|
|
+ alert('Stock not found.');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ searchStockResult = data;
|
|
|
|
|
+
|
|
|
|
|
+ const alreadyInPortfolio = result.some((s) => s.code === data[0]?.code);
|
|
|
|
|
+ if (data.length === 1 && !alreadyInPortfolio) {
|
|
|
|
|
+ await addSelectedStock(data[0]);
|
|
|
|
|
+ closeModal();
|
|
|
|
|
+ }
|
|
|
|
|
+ }}
|
|
|
|
|
+ onAddStock={async (stock) => {
|
|
|
|
|
+ await addSelectedStock(stock);
|
|
|
|
|
+ closeModal();
|
|
|
|
|
+ }}
|
|
|
|
|
+ searchResults={searchStockResult}
|
|
|
|
|
+ />
|
|
|
|
|
|
|
|
<div in:fade class="table-container">
|
|
<div in:fade class="table-container">
|
|
|
<table class="stock-table">
|
|
<table class="stock-table">
|
|
@@ -364,7 +345,6 @@
|
|
|
{/if}
|
|
{/if}
|
|
|
|
|
|
|
|
<style>
|
|
<style>
|
|
|
- /* General Styles for Table (Unchanged) */
|
|
|
|
|
.table-container {
|
|
.table-container {
|
|
|
margin-top: 2rem;
|
|
margin-top: 2rem;
|
|
|
overflow-x: auto;
|
|
overflow-x: auto;
|
|
@@ -473,25 +453,10 @@
|
|
|
color: #2980b9;
|
|
color: #2980b9;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* Responsive design */
|
|
|
|
|
@media (max-width: 768px) {
|
|
@media (max-width: 768px) {
|
|
|
- .modal-content {
|
|
|
|
|
- width: 90%;
|
|
|
|
|
- padding: 1.5rem;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- input[type='text'],
|
|
|
|
|
input[type='number'] {
|
|
input[type='number'] {
|
|
|
font-size: 0.9rem;
|
|
font-size: 0.9rem;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- .modal-result {
|
|
|
|
|
- max-height: 200px;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .list-group-item {
|
|
|
|
|
- font-size: 0.9rem;
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
@media (max-width: 768px) {
|
|
@@ -505,33 +470,6 @@
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* Modal Styling */
|
|
|
|
|
- .modal-container {
|
|
|
|
|
- position: fixed;
|
|
|
|
|
- top: 20%;
|
|
|
|
|
- left: 0;
|
|
|
|
|
- right: 0;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- justify-content: center;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- z-index: 9999;
|
|
|
|
|
- animation: fadeIn 0.3s ease;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /* Modal content styling */
|
|
|
|
|
- .modal-content {
|
|
|
|
|
- background-color: #fff;
|
|
|
|
|
- color: #333;
|
|
|
|
|
- width: 450px;
|
|
|
|
|
- height: auto;
|
|
|
|
|
- max-width: 500px;
|
|
|
|
|
- border-radius: 10px;
|
|
|
|
|
- padding: 2rem;
|
|
|
|
|
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
|
|
|
|
- transition: transform 0.3s ease-in-out;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /* Button container for Add and Dropdown */
|
|
|
|
|
.button-container {
|
|
.button-container {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
gap: 10px;
|
|
gap: 10px;
|
|
@@ -554,8 +492,6 @@
|
|
|
outline: none;
|
|
outline: none;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* Input Fields (Stock code and search) */
|
|
|
|
|
- input[type='text'],
|
|
|
|
|
input[type='number'] {
|
|
input[type='number'] {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
padding: 0.8rem;
|
|
padding: 0.8rem;
|
|
@@ -568,13 +504,11 @@
|
|
|
transition: border-color 0.3s ease;
|
|
transition: border-color 0.3s ease;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- input[type='text']:focus,
|
|
|
|
|
input[type='number']:focus {
|
|
input[type='number']:focus {
|
|
|
border-color: #2980b9;
|
|
border-color: #2980b9;
|
|
|
outline: none;
|
|
outline: none;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /* Button styles */
|
|
|
|
|
.btn {
|
|
.btn {
|
|
|
padding: 0.6rem 1.2rem;
|
|
padding: 0.6rem 1.2rem;
|
|
|
font-size: 1rem;
|
|
font-size: 1rem;
|
|
@@ -593,68 +527,6 @@
|
|
|
background-color: #3498db;
|
|
background-color: #3498db;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- .btn-danger {
|
|
|
|
|
- background-color: #e74c3c;
|
|
|
|
|
- color: white;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .btn-danger:hover {
|
|
|
|
|
- background-color: #c0392b;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /* Reset Button (Modal) */
|
|
|
|
|
- input[type='reset'] {
|
|
|
|
|
- background-color: #e74c3c;
|
|
|
|
|
- color: white;
|
|
|
|
|
- font-size: 1rem;
|
|
|
|
|
- padding: 0.6rem 1.2rem;
|
|
|
|
|
- border-radius: 8px;
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- border: none;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /* Modal result items */
|
|
|
|
|
- .modal-result {
|
|
|
|
|
- max-width: 100%;
|
|
|
|
|
- max-height: 300px;
|
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
- padding: 0.8rem;
|
|
|
|
|
- background-color: #fafafa;
|
|
|
|
|
- border-radius: 10px;
|
|
|
|
|
- margin-top: 1rem;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .list-group-item {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- justify-content: space-between;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- padding: 10px;
|
|
|
|
|
- border: 1px solid #ddd;
|
|
|
|
|
- margin-bottom: 0.5rem;
|
|
|
|
|
- border-radius: 8px;
|
|
|
|
|
- background-color: #f9f9f9;
|
|
|
|
|
- transition: background-color 0.3s ease;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .list-group-item:hover {
|
|
|
|
|
- background-color: #f1f1f1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .list-group-item .btn-primary {
|
|
|
|
|
- background-color: #2980b9;
|
|
|
|
|
- color: white;
|
|
|
|
|
- border-radius: 50%;
|
|
|
|
|
- height: 30px;
|
|
|
|
|
- width: 30px;
|
|
|
|
|
- padding: 0;
|
|
|
|
|
- border: none;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .list-group-item .btn-primary:hover {
|
|
|
|
|
- background-color: #3498db;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /* Modal transition */
|
|
|
|
|
@keyframes fadeIn {
|
|
@keyframes fadeIn {
|
|
|
from {
|
|
from {
|
|
|
opacity: 0;
|
|
opacity: 0;
|