add searchbar endpoint to watchlist
This commit is contained in:
parent
6cef095e3d
commit
e4c90148a6
@ -1,9 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import { screenWidth, numberOfUnreadNotification } from "$lib/store";
|
||||||
searchBarData,
|
|
||||||
screenWidth,
|
|
||||||
numberOfUnreadNotification,
|
|
||||||
} from "$lib/store";
|
|
||||||
import { formatDate, abbreviateNumber } from "$lib/utils";
|
import { formatDate, abbreviateNumber } from "$lib/utils";
|
||||||
import toast from "svelte-french-toast";
|
import toast from "svelte-french-toast";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
@ -14,7 +10,8 @@
|
|||||||
import { Combobox } from "bits-ui";
|
import { Combobox } from "bits-ui";
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
let timeoutId;
|
||||||
|
let searchBarData = [];
|
||||||
let searchQuery = "";
|
let searchQuery = "";
|
||||||
let switchWatchlist = false;
|
let switchWatchlist = false;
|
||||||
let editMode = false;
|
let editMode = false;
|
||||||
@ -151,22 +148,6 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
async function loadSearchData() {
|
|
||||||
if ($searchBarData.length !== 0 || searchDataLoaded) return;
|
|
||||||
else {
|
|
||||||
searchDataLoaded = true;
|
|
||||||
// make the GET request to the endpoint
|
|
||||||
const response = await fetch("/api/searchbar-data", {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
$searchBarData = await response.json();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getWatchlistData() {
|
async function getWatchlistData() {
|
||||||
const postData = {
|
const postData = {
|
||||||
watchListId: displayWatchList?.id,
|
watchListId: displayWatchList?.id,
|
||||||
@ -586,55 +567,21 @@
|
|||||||
let inputValue = "";
|
let inputValue = "";
|
||||||
let touchedInput = false;
|
let touchedInput = false;
|
||||||
|
|
||||||
$: filteredStocks = inputValue ? search() : [];
|
async function search() {
|
||||||
|
clearTimeout(timeoutId); // Clear any existing timeout
|
||||||
|
|
||||||
function search() {
|
if (!inputValue.trim()) {
|
||||||
const normalizedSearchQuery = inputValue.toLowerCase();
|
// Skip if query is empty or just whitespace
|
||||||
|
searchBarData = []; // Clear previous results
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const filteredList = $searchBarData
|
timeoutId = setTimeout(async () => {
|
||||||
.map((item) => ({
|
const response = await fetch(
|
||||||
...item,
|
`/api/searchbar?query=${encodeURIComponent(inputValue)}&limit=10`,
|
||||||
nameLower: item?.name?.toLowerCase(),
|
|
||||||
symbolLower: item?.symbol?.toLowerCase(),
|
|
||||||
}))
|
|
||||||
.filter(
|
|
||||||
({ nameLower, symbolLower }) =>
|
|
||||||
nameLower.includes(normalizedSearchQuery) ||
|
|
||||||
symbolLower.includes(normalizedSearchQuery),
|
|
||||||
);
|
);
|
||||||
|
searchBarData = await response?.json();
|
||||||
filteredList.sort((a, b) => {
|
}, 50); // delay
|
||||||
const aSymbolLower = a.symbolLower;
|
|
||||||
const bSymbolLower = b.symbolLower;
|
|
||||||
const aNameLower = a.nameLower;
|
|
||||||
const bNameLower = b.nameLower;
|
|
||||||
|
|
||||||
// Check for exact symbol matches
|
|
||||||
const isExactMatchA = aSymbolLower === normalizedSearchQuery;
|
|
||||||
const isExactMatchB = bSymbolLower === normalizedSearchQuery;
|
|
||||||
|
|
||||||
if (isExactMatchA && !isExactMatchB) {
|
|
||||||
return -1; // Prioritize exact symbol match for A
|
|
||||||
} else if (!isExactMatchA && isExactMatchB) {
|
|
||||||
return 1; // Prioritize exact symbol match for B
|
|
||||||
}
|
|
||||||
|
|
||||||
const aSymbolIndex = aSymbolLower.indexOf(normalizedSearchQuery);
|
|
||||||
const bSymbolIndex = bSymbolLower.indexOf(normalizedSearchQuery);
|
|
||||||
|
|
||||||
const aNameIndex = aNameLower.indexOf(normalizedSearchQuery);
|
|
||||||
const bNameIndex = bNameLower.indexOf(normalizedSearchQuery);
|
|
||||||
|
|
||||||
// If no exact symbol match, prioritize based on the combined position in name and symbol
|
|
||||||
const positionComparison =
|
|
||||||
aSymbolIndex + aNameIndex - (bSymbolIndex + bNameIndex);
|
|
||||||
|
|
||||||
return positionComparison;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Limit results to 5
|
|
||||||
const resultList = filteredList?.slice(0, 5);
|
|
||||||
return resultList;
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -847,7 +794,7 @@
|
|||||||
: ''}"
|
: ''}"
|
||||||
>
|
>
|
||||||
<Combobox.Root
|
<Combobox.Root
|
||||||
items={filteredStocks}
|
items={searchBarData}
|
||||||
bind:inputValue
|
bind:inputValue
|
||||||
bind:touchedInput
|
bind:touchedInput
|
||||||
>
|
>
|
||||||
@ -871,7 +818,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<Combobox.Input
|
<Combobox.Input
|
||||||
on:click={loadSearchData}
|
on:input={search}
|
||||||
class="text-sm sm:text-[1rem] controls-input text-white bg-[#09090B] focus:outline-none border border-gray-600 rounded-md placeholder:text-white/80 px-3 py-2 pl-8 xs:pl-10 flex-grow w-full sm:min-w-56 max-w-xs"
|
class="text-sm sm:text-[1rem] controls-input text-white bg-[#09090B] focus:outline-none border border-gray-600 rounded-md placeholder:text-white/80 px-3 py-2 pl-8 xs:pl-10 flex-grow w-full sm:min-w-56 max-w-xs"
|
||||||
placeholder="Add new stock"
|
placeholder="Add new stock"
|
||||||
aria-label="Add new stock"
|
aria-label="Add new stock"
|
||||||
@ -882,7 +829,7 @@
|
|||||||
class="w-auto z-10 rounded-md border border-gray-700 bg-[#09090B] px-1 py-3 shadow-popover outline-none"
|
class="w-auto z-10 rounded-md border border-gray-700 bg-[#09090B] px-1 py-3 shadow-popover outline-none"
|
||||||
sideOffset={8}
|
sideOffset={8}
|
||||||
>
|
>
|
||||||
{#each filteredStocks as item}
|
{#each searchBarData as item}
|
||||||
<Combobox.Item
|
<Combobox.Item
|
||||||
class="cursor-pointer text-white border-b border-gray-600 last:border-none flex h-fit w-auto select-none items-center rounded-button py-3 pl-5 pr-1.5 text-sm capitalize outline-none transition-all duration-75 data-[highlighted]:bg-[#27272A]"
|
class="cursor-pointer text-white border-b border-gray-600 last:border-none flex h-fit w-auto select-none items-center rounded-button py-3 pl-5 pr-1.5 text-sm capitalize outline-none transition-all duration-75 data-[highlighted]:bg-[#27272A]"
|
||||||
value={item.symbol}
|
value={item.symbol}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user