refactor code

This commit is contained in:
MuslemRahimi 2024-10-31 11:27:08 +01:00
parent 4faa874d4f
commit f85a0e21d6
7 changed files with 1024 additions and 805 deletions

View File

@ -1,17 +1,11 @@
<script lang="ts"> <script lang="ts">
import { import { searchBarData, screenWidth } from "$lib/store";
searchBarData,
stockTicker,
etfTicker,
cryptoTicker,
screenWidth,
} from "$lib/store";
import { goto } from "$app/navigation";
import { onMount } from "svelte"; import { onMount } from "svelte";
import Search from "lucide-svelte/icons/search"; import Search from "lucide-svelte/icons/search";
import { goto } from "$app/navigation";
let searchHistory = []; let searchHistory = [];
let searchResults = []; let searchResults = [];
let updatedSearchHistory = [];
let dataLoaded = false; // Flag to track data loading let dataLoaded = false; // Flag to track data loading
@ -41,9 +35,8 @@
} }
} }
async function popularTicker(state, assetType) { async function popularTicker(state) {
searchOpen = false; searchOpen = false;
if (!state) return; if (!state) return;
// Convert state to uppercase once // Convert state to uppercase once
@ -54,51 +47,23 @@
({ symbol }) => symbol === upperState, ({ symbol }) => symbol === upperState,
); );
// Update search history:
// 1. Remove the item if it already exists (to avoid duplicates)
// 2. Add the new item at the beginning
// 3. Limit to 5 items
if (newSearchItem) { if (newSearchItem) {
searchHistory = [ // Ensure `upperState` matches the case of `item.symbol`
updatedSearchHistory = [
newSearchItem, newSearchItem,
...(searchHistory?.filter((item) => item.symbol !== upperState) || []), ...(searchHistory?.filter(
(item) => item?.symbol?.toUpperCase() !== upperState,
) || []),
].slice(0, 5); ].slice(0, 5);
} }
// Save recent ticker
searchHistory = [...searchHistory];
console.log(searchHistory);
await saveRecentTicker();
// Map of asset types to their corresponding actions
console.log(upperState, assetType);
const assetActions = {
ETF: () => {
etfTicker.update(() => upperState);
goto(`/etf/${upperState}`);
},
Stock: () => {
stockTicker.update(() => upperState);
goto(`/stocks/${upperState}`);
},
Crypto: () => {
cryptoTicker.update(() => upperState);
goto(`/crypto/${upperState}`);
},
};
// Execute the appropriate action for the asset type
if (assetActions[assetType]) {
assetActions[assetType]();
}
// Close search modal // Close search modal
const closePopup = document.getElementById("searchBarModal"); const closePopup = document.getElementById("searchBarModal");
closePopup?.dispatchEvent(new MouseEvent("click")); closePopup?.dispatchEvent(new MouseEvent("click"));
} }
async function searchBarTicker(state, assetType) { function searchBarTicker(state) {
showSuggestions = false; showSuggestions = false;
// Early return if state is empty or ticker not found // Early return if state is empty or ticker not found
if ( if (
!state || !state ||
@ -117,51 +82,25 @@
({ symbol }) => symbol === upperState, ({ symbol }) => symbol === upperState,
); );
// Update search history:
// 1. Remove the item if it already exists (to avoid duplicates)
// 2. Add the new item at the beginning
// 3. Limit to 5 items
if (newSearchItem) { if (newSearchItem) {
searchHistory = [ // Ensure `upperState` matches the case of `item.symbol`
updatedSearchHistory = [
newSearchItem, newSearchItem,
...(searchHistory?.filter((item) => item.symbol !== upperState) || []), ...(searchHistory?.filter(
(item) => item?.symbol?.toUpperCase() !== upperState,
) || []),
].slice(0, 5); ].slice(0, 5);
} }
// Map of asset types to their corresponding actions // Close search modal
searchHistory = [...searchHistory]; searchOpen = false;
console.log(searchHistory); const closePopup = document.getElementById("searchBarModal");
await saveRecentTicker(); closePopup?.dispatchEvent(new MouseEvent("click"));
const assetActions = {
ETF: () => {
etfTicker.update(() => upperState);
goto(`/etf/${upperState}`);
},
Stock: () => {
stockTicker.update(() => upperState);
goto(`/stocks/${upperState}`);
},
Crypto: () => {
cryptoTicker.update(() => upperState);
goto(`/crypto/${upperState}`);
},
};
// Execute the appropriate action for the asset type
if (assetActions[assetType]) {
assetActions[assetType]();
// Close search modal
searchOpen = false;
const closePopup = document.getElementById("searchBarModal");
closePopup?.dispatchEvent(new MouseEvent("click"));
}
searchQuery = ""; searchQuery = "";
} }
async function search() { function search() {
const normalizedSearchQuery = searchQuery?.toLowerCase(); const normalizedSearchQuery = searchQuery?.toLowerCase();
// Define names for which symbols without dots should be prioritized // Define names for which symbols without dots should be prioritized
@ -227,16 +166,25 @@
if (e?.charCode === 13) { if (e?.charCode === 13) {
focusedSuggestion = ""; focusedSuggestion = "";
if (searchResults?.length > 0) { const assetActions = {
ETF: () => goto(`/etf/${searchQuery}`),
Stock: () => goto(`/stocks/${searchQuery}`),
Crypto: () => goto(`/crypto/${searchQuery}`),
};
if (showSuggestions?.length > 0) {
// Use the first search result // Use the first search result
const firstResult = searchResults[0];
searchQuery = firstResult.symbol; searchQuery = firstResult.symbol;
assetType = firstResult.type; assetType = firstResult.type;
searchBarTicker(firstResult.symbol, firstResult.type);
} else if (!notFoundTicker && searchQuery) {
// Fallback to original behavior if no search results
searchBarTicker(searchQuery, assetType);
} }
// Execute the appropriate action for the asset type
if (assetActions[assetType]) {
assetActions[assetType]();
}
// Trigger search bar action
searchBarTicker(searchQuery);
} }
}; };
@ -398,6 +346,20 @@
notFoundTicker = false; notFoundTicker = false;
} }
} }
$: {
if (updatedSearchHistory?.length > 0 && searchBarModalChecked === false) {
(async () => {
// Add 500 ms delay is important otherwise bug since #each has searchHistory and updates too quickly and redirects to wrong symbol
await new Promise((resolve) => setTimeout(resolve, 500));
// Update search history after delay
searchHistory = updatedSearchHistory;
updatedSearchHistory = [];
saveRecentTicker();
})();
}
}
</script> </script>
<label <label
@ -510,7 +472,7 @@
autocomplete="off" autocomplete="off"
/> />
<button <button
on:click={() => searchBarTicker(searchQuery, assetType)} on:click={() => searchBarTicker(searchQuery)}
class="absolute inset-0 right-auto group" class="absolute inset-0 right-auto group"
type="submit" type="submit"
aria-label="Search" aria-label="Search"
@ -548,8 +510,9 @@
{#if !showSuggestions} {#if !showSuggestions}
{#each searchHistory?.length > 0 ? searchHistory : popularList as item} {#each searchHistory?.length > 0 ? searchHistory : popularList as item}
<li class="border-b border-gray-600"> <li class="border-b border-gray-600">
<label <a
on:click={() => popularTicker(item?.symbol, item?.type)} href={`/${item?.type === "ETF" ? "etf" : item?.type === "Crypto" ? "crypto" : "stocks"}/${item?.symbol}`}
on:click={() => popularTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group' ? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
: 'shake-ticker cursor-pointer bg-[#09090B] sm:hover:bg-[#27272A] rounded-lg flex justify-start items-center p-2 text-white group'} w-full" : 'shake-ticker cursor-pointer bg-[#09090B] sm:hover:bg-[#27272A] rounded-lg flex justify-start items-center p-2 text-white group'} w-full"
@ -578,7 +541,7 @@
{item?.type} {item?.type}
</div> </div>
</div> </div>
</label> </a>
</li> </li>
{/each} {/each}
{:else if showSuggestions && searchResults?.length > 0} {:else if showSuggestions && searchResults?.length > 0}
@ -589,9 +552,9 @@
<li class="border-b border-gray-600"> <li class="border-b border-gray-600">
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-label-has-associated-control --> <!-- svelte-ignore a11y-label-has-associated-control -->
<label <a
data-sveltekit-preload-data={false} href={`/${item?.type === "ETF" ? "etf" : item?.type === "Crypto" ? "crypto" : "stocks"}/${item?.symbol}`}
on:click={() => searchBarTicker(item?.symbol, item?.type)} on:click={() => searchBarTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group' ? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
: 'cursor-pointer mb-2 bg-[#09090B] sm:hover:bg-[#27272A] rounded-lg flex justify-start items-center p-2 text-white group'}" : 'cursor-pointer mb-2 bg-[#09090B] sm:hover:bg-[#27272A] rounded-lg flex justify-start items-center p-2 text-white group'}"
@ -610,7 +573,7 @@
{item?.type} {item?.type}
</div> </div>
</div> </div>
</label> </a>
</li> </li>
{/each} {/each}
{:else if showSuggestions && searchResults?.length === 0} {:else if showSuggestions && searchResults?.length === 0}
@ -697,7 +660,7 @@
autocomplete="off" autocomplete="off"
/> />
<button <button
on:click={() => searchBarTicker(searchQuery, assetType)} on:click={() => searchBarTicker(searchQuery)}
class="absolute inset-0 right-auto group" class="absolute inset-0 right-auto group"
type="submit" type="submit"
aria-label="Search" aria-label="Search"
@ -736,8 +699,9 @@
{#if !showSuggestions} {#if !showSuggestions}
{#each searchHistory?.length > 0 ? searchHistory : popularList as item} {#each searchHistory?.length > 0 ? searchHistory : popularList as item}
<li class="border-b border-gray-600"> <li class="border-b border-gray-600">
<label <a
on:click={() => popularTicker(item?.symbol, item?.type)} href={`/${item?.type === "ETF" ? "etf" : item?.type === "Crypto" ? "crypto" : "stocks"}/${item?.symbol}`}
on:click={() => popularTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group' ? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
: 'cursor-pointer bg-[#09090B] bg-opacity-[0.4] rounded-lg flex justify-start items-center p-2 text-white group'} w-full" : 'cursor-pointer bg-[#09090B] bg-opacity-[0.4] rounded-lg flex justify-start items-center p-2 text-white group'} w-full"
@ -766,7 +730,7 @@
{item?.type} {item?.type}
</div> </div>
</div> </div>
</label> </a>
</li> </li>
{/each} {/each}
{:else if showSuggestions && searchResults?.length > 0} {:else if showSuggestions && searchResults?.length > 0}
@ -777,10 +741,9 @@
<li class="border-b border-gray-600"> <li class="border-b border-gray-600">
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-label-has-associated-control --> <!-- svelte-ignore a11y-label-has-associated-control -->
<label <a
data-sveltekit-preload-data={false} href={`/${item?.type === "ETF" ? "etf" : item?.type === "Crypto" ? "crypto" : "stocks"}/${item?.symbol}`}
on:click={() => on:click={() => searchBarTicker(item?.symbol)}
searchBarTicker(item?.symbol, item?.type)}
class="mb-2 {item?.symbol === focusedSuggestion class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group' ? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
: 'cursor-pointer mb-2 bg-[#09090B] bg-opacity-[0.4] rounded-lg flex justify-start items-center p-2 text-white group'}" : 'cursor-pointer mb-2 bg-[#09090B] bg-opacity-[0.4] rounded-lg flex justify-start items-center p-2 text-white group'}"
@ -799,7 +762,7 @@
{item?.type} {item?.type}
</div> </div>
</div> </div>
</label> </a>
</li> </li>
{/each} {/each}
{:else if showSuggestions && searchResults?.length === 0} {:else if showSuggestions && searchResults?.length === 0}

View File

@ -83,5 +83,6 @@ export const load = async ({ params, locals, setHeaders }) => {
getOneDayPrice, getOneDayPrice,
getUserWatchlist, getUserWatchlist,
companyName, companyName,
getParams: params.tickerID,
}; };
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
import { displayCompanyName, cryptoTicker, assetType } from "$lib/store";
export const load = async ({ params, data }) => {
cryptoTicker.update((value) => params.tickerID?.toUpperCase());
assetType.update((value) => "crypto");
displayCompanyName.update((value) => data?.companyName);
};

View File

@ -94,5 +94,6 @@ export const load = async ({ params, locals }) => {
getNews, getNews,
getUserWatchlist, getUserWatchlist,
companyName: cleanString(getStockDeck?.companyName), companyName: cleanString(getStockDeck?.companyName),
getParams: params.tickerID,
}; };
}; };

View File

@ -12,8 +12,9 @@
isCrosshairMoveActive, isCrosshairMoveActive,
currentPrice, currentPrice,
priceIncrease, priceIncrease,
displayCompanyName,
stockTicker, stockTicker,
assetType,
displayCompanyName,
isOpen, isOpen,
shouldUpdatePriceChart, shouldUpdatePriceChart,
priceChartData, priceChartData,
@ -315,6 +316,9 @@ function handleTypeOfTrade(state:string)
$: { $: {
if ($page?.url?.pathname && typeof window !== "undefined") { if ($page?.url?.pathname && typeof window !== "undefined") {
stockTicker.update((value) => (value = data?.getParams?.toUpperCase()));
assetType.update((value) => (value = "stock"));
displayCompanyName.update((value) => (value = data?.companyName));
const parts = $page?.url?.pathname?.split("/"); const parts = $page?.url?.pathname?.split("/");
const sectionMap = { const sectionMap = {
statistics: "statistics", statistics: "statistics",

View File

@ -1,7 +1,4 @@
import { import {
displayCompanyName,
stockTicker,
assetType,
isOpen, isOpen,
isAfterMarketClose, isAfterMarketClose,
isBeforeMarketOpen, isBeforeMarketOpen,
@ -53,8 +50,5 @@ const checkMarketHour = async () => {
}; };
export const load = async ({ params, data }) => { export const load = async ({ params, data }) => {
stockTicker.update((value) => (value = params.tickerID?.toUpperCase()));
assetType.update((value) => (value = "stock"));
displayCompanyName.update((value) => (value = data?.companyName));
await checkMarketHour(); await checkMarketHour();
}; };