frontend/src/routes/ipos/[slug]/+page.svelte
MuslemRahimi 18c46c4a28 ui fix
2025-03-11 13:25:24 +01:00

199 lines
7.8 KiB
Svelte

<script lang="ts">
import { formatString, abbreviateNumber } from "$lib/utils";
import { screenWidth } from "$lib/store";
import { page } from "$app/stores";
import { onMount } from "svelte";
import Infobox from "$lib/components/Infobox.svelte";
import SEO from "$lib/components/SEO.svelte";
export let data;
let rawData = data?.getIPOCalendar?.filter(
(item) => new Date(item?.ipoDate).getFullYear() >= data?.getYear,
);
let ipoList = rawData?.slice(0, 150);
let year = data?.getYear;
let ipoNews = data?.getNews;
async function handleScroll() {
const scrollThreshold = document.body.offsetHeight * 0.8; // 80% of the website height
const isBottom = window.innerHeight + window.scrollY >= scrollThreshold;
if (isBottom && ipoList?.length !== rawData?.length) {
const nextIndex = ipoList?.length;
const filteredNewResults = rawData?.slice(nextIndex, nextIndex + 50);
ipoList = [...ipoList, ...filteredNewResults];
}
}
onMount(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
});
$: {
if ($page?.url?.pathname) {
rawData = data?.getIPOCalendar?.filter(
(item) => new Date(item?.ipoDate).getFullYear() == data?.getYear,
);
ipoList = rawData?.slice(0, 150);
year = data?.getYear;
}
}
$: charNumber = $screenWidth < 640 ? 20 : 30;
</script>
<SEO
title={`All ${data?.getYear} IPOs - A Complete List`}
description={`A list of all the initial public offerings (IPOs) on the US stock market in the year ${data?.getYear}.`}
/>
<div class="w-full overflow-hidden min-h-screen pb-20 m-auto mt-5">
<div class="sm:p-0 flex justify-center w-full m-auto overflow-hidden">
<div
class="relative flex justify-center items-start overflow-hidden w-full"
>
<main class="w-full lg:w-3/4 lg:pr-10">
<div class="flex flex-col justify-center items-center">
{#if rawData?.length !== 0}
<h2 class=" text-xl font- text-start mt-5 w-full font-semibold">
{rawData?.length} IPOs
</h2>
<div class="w-full overflow-x-auto">
<table
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-white dark:bg-table border border-gray-300 dark:border-gray-800 m-auto mt-4"
>
<thead class="text-muted dark:text-white dark:bg-default">
<tr>
<th class=" font-semibold text-sm text-start">IPO Date</th>
<th class=" font-semibold text-sm text-start">Symbol</th>
<th class=" font-semibold text-sm">Name</th>
<th class=" font-semibold text-end text-sm">IPO Price</th>
<th class=" font-semibold text-end text-sm"
>Current Price</th
>
<th class=" font-semibold text-end text-sm">Return Since</th
>
</tr>
</thead>
<tbody>
{#each ipoList as item}
<tr
class="dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd"
>
<td
class=" text-sm sm:text-[1rem] whitespace-nowrap text-start whitespace-nowrap"
>
{new Date(item?.ipoDate)?.toLocaleString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
daySuffix: "2-digit",
})}
</td>
<td
class="text-sm sm:text-[1rem] whitespace-nowrap text-start whitespace-nowrap"
>
<a
href={"/stocks/" + item?.symbol}
class="text-blue-500 sm:hover:text-muted dark:sm:hover:text-white dark:text-blue-400"
>
{item?.symbol}
</a>
</td>
<td class=" whitespace-nowrap text-sm sm:text-[1rem]">
<span class=""
>{item?.name?.length > charNumber
? formatString(item?.name?.slice(0, charNumber)) +
"..."
: formatString(item?.name)}</span
>
</td>
<td
class=" text-sm sm:text-[1rem] whitespace-nowrap text-end"
>
{item?.ipoPrice !== null ? item?.ipoPrice : "n/a"}
</td>
<td class=" text-sm sm:text-[1rem] text-end">
{item?.currentPrice !== null
? item?.currentPrice
: "n/a"}
</td>
<td
class=" text-end flex flex-row items-center justify-end"
>
{#if item?.return >= 0 && item?.return !== null}
<span
class="inline-block text-green-600 dark:text-[#00FC50] text-sm sm:text-[1rem] whitespace-nowrap"
>+{abbreviateNumber(item?.return)}%</span
>
{:else if item?.return < 0 && item?.return !== null}
<span
class="inline-block text-red-600 dark:text-[#FF2F1F] text-sm sm:text-[1rem] whitespace-nowrap"
>{abbreviateNumber(item?.return)}%
</span>
{:else}
<span
class="inline-block text-sm sm:text-[1rem] whitespace-nowrap"
>
n/a
</span>
{/if}
</td>
</tr>
{/each}
</tbody>
</table>
</div>
{:else}
<div class="w-full">
<Infobox
text={`No IPOs found. Please adjust your search timeframe for the latest ${year}
IPOs.`}
/>
</div>
{/if}
</div>
</main>
<aside class="hidden lg:block relative fixed w-1/4">
{#if ipoNews?.length !== 0}
<div
class="w-full border border-gray-300 dark:border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer bg-inherit"
>
<div class="p-4 text-sm">
<h3 class="text-xl font-bold mb-3">IPO News</h3>
<ul class="">
{#each ipoNews?.slice(0, 10) as item}
<li class="mb-3 last:mb-1">
{item?.timestamp}
<a
class="text-blue-500 sm:hover:text-muted dark:sm:hover:text-white dark:text-blue-400"
href={item?.link}
target="_blank"
rel="noopener noreferrer nofollow">{item?.title}</a
>
</li>
{/each}
</ul>
<a
href={`/ipos/news`}
class="flex justify-center items-center rounded cursor-pointer w-full py-2 mt-3 text-[1rem] text-center font-semibold text-white dark:text-black m-auto sm:hover:bg-blue-600 dark:sm:hover:bg-gray-300 bg-[#3B82F6] dark:bg-[#fff] transition duration-100"
>
More IPO News
</a>
</div>
</div>
{/if}
</aside>
</div>
</div>
</div>