update financial page and pricing

This commit is contained in:
MuslemRahimi 2024-11-15 20:52:27 +01:00
parent 20f756a33a
commit e62c1fbc60
4 changed files with 128 additions and 412 deletions

View File

@ -0,0 +1,53 @@
<script lang="ts">
import { abbreviateNumber } from "$lib/utils";
export let data;
const fields = [
{ label: "Revenue", key: "revenue" },
{ label: "Cost of Revenue", key: "costOfRevenue" },
{ label: "Gross Profit", key: "grossProfit" },
{ label: "Net Income", key: "netIncome" },
{ label: "Operating Income", key: "operatingIncome" },
{
label: "Selling, General & Admin",
key: "sellingGeneralAndAdministrativeExpenses",
},
{
label: "Selling & Marketing Expenses",
key: "sellingAndMarketingExpenses",
},
{ label: "Research & Development", key: "researchAndDevelopmentExpenses" },
{ label: "Other Expenses", key: "otherExpenses" },
{ label: "Operating Expenses", key: "operatingExpenses" },
{ label: "Cost & Expenses", key: "costAndExpenses" },
{ label: "Interest Expense", key: "interestExpense" },
{ label: "Pretax Income", key: "incomeBeforeTax" },
{ label: "Income Tax", key: "incomeTaxExpense" },
{ label: "Interest Income", key: "interestIncome" },
{ label: "Interest Expense", key: "interestExpense" },
{ label: "Shares Outstanding (Basic)", key: "weightedAverageShsOut" },
{ label: "Shares Outstanding (Diluted)", key: "weightedAverageShsOutDil" },
{ label: "EPS (Basic)", key: "eps" },
{ label: "EPS (Diluted)", key: "epsdiluted" },
{ label: "EBITDA", key: "ebitda" },
{ label: "Depreciation & Amortization", key: "depreciation" },
];
</script>
{#each fields as { label, key }}
<tr class="text-white odd:bg-[#27272A] whitespace-nowrap">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>
{label}
</td>
{#each data as item}
<td class="text-sm sm:text-[1rem] text-end">
{item[key] !== null && item[key] !== 0
? abbreviateNumber(item[key])
: "-"}
</td>
{/each}
</tr>
{/each}

View File

@ -1,150 +0,0 @@
<script>
import { numberOfUnreadNotification, screenWidth } from "$lib/store";
import ArrowLogo from "lucide-svelte/icons/move-up-right";
</script>
<svelte:head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""} Price
Plan
</title>
</svelte:head>
<section
class="w-full max-w-3xl sm:max-w-screen-2xl overflow-hidden pb-20 min-h-screen pt-5 px-4 lg:px-3"
>
<div class="text-sm sm:text-[1rem] breadcrumbs">
<ul>
<li><a href="/" class="text-gray-300">Home</a></li>
<li class="text-gray-300">Price Plan</li>
</ul>
</div>
<div class="w-full overflow-hidden 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-5">
<div class="mb-6 border-b-[2px]">
<h1 class="mb-1 text-white text-2xl sm:text-3xl font-bold">
Price Plan
</h1>
</div>
<div class="w-full bg-[#09090B] m-auto">
<div class="h-full">
<h2 class="text-white text-xl font-semibold mb-5">
Hi everyone 👋,
</h2>
<p class="text-white mb-5 text-[1rem]">
After gathering feedback from users and analyzing our data at
the $1.99/month price point, I wanted to share some insights and
plans with you.
<br />
<br />
At our current rate, Stocknear is on track to reach profitability
in about 22.5 years, a timeline that may not be sustainable for
our platform. To give us a stronger chance of sustaining the platform
over the next 12 months, we're considering a new price point of
<strong>$4.99/month</strong>, which still keeps us among the
most affordable option for premium Wall Street data.
</p>
<div class="text-white mb-5 text-[1rem]">
If you're already a Pro Member, your current rate will remain
locked in as long as your subscription stays active.
<br />
<br />
This new price plan will take effect on
<strong>Monday, November 11, 2024</strong>. Now is the last
chance to secure the
<a href="/pricing" class="sm:hover:text-white text-blue-400"
>Pro Subscription</a
>
at <strong>$1.99/month</strong>—after this, the introductory
price will no longer be available.
<br />
<br />
To my Pro Members, I want to take a moment to say thank you. You're
the reason Im doing this. The mission of Stocknear has always been
to support small retail investors who may not have the resources
to pay for high-priced subscriptions. Many of you have supported
me through valuable feedback, bug reports, donations, and by subscribing
to the platform. Hearing how Stocknear has helped so many of you
has been incredibly motivating. Thank you for sticking with me!
<br />
<br />
Cheers,
<br />
<br /> Your Chief of Nothing
</div>
</div>
</div>
</main>
<aside class="hidden lg:block relative fixed w-1/4 ml-4">
<div
class="w-full text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer"
>
<a
href="/pricing"
class="w-auto lg:w-full p-1 flex flex-col m-auto px-2 sm:px-0"
>
<div class="w-full flex justify-between items-center p-3 mt-3">
<h2 class="text-start text-xl font-semibold text-white ml-3">
Pro Subscription
</h2>
<ArrowLogo class="w-8 h-8 mr-3 flex-shrink-0" />
</div>
<span class="text-white p-3 ml-3 mr-3">
Upgrade now for unlimited access to all data and tools.
</span>
</a>
</div>
<div
class="w-full text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer"
>
<a
href="/about"
class="w-auto lg:w-full p-1 flex flex-col m-auto px-2 sm:px-0"
>
<div class="w-full flex justify-between items-center p-3 mt-3">
<h2 class="text-start text-xl font-semibold text-white ml-3">
About Us
</h2>
<ArrowLogo class="w-8 h-8 mr-3 flex-shrink-0" />
</div>
<span class="text-white p-3 ml-3 mr-3">
Learn more about why we're doing this here
</span>
</a>
</div>
<div
class="w-full text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer"
>
<a
href="/contact"
class="w-auto lg:w-full p-1 flex flex-col m-auto px-2 sm:px-0"
>
<div class="w-full flex justify-between items-center p-3 mt-3">
<h2 class="text-start text-xl font-semibold text-white ml-3">
Contact Us
</h2>
<ArrowLogo class="w-8 h-8 mr-3 flex-shrink-0" />
</div>
<span class="text-white p-3 ml-3 mr-3">
Let me know if you need something
</span>
</a>
</div>
</aside>
</div>
</div>
</div>
</section>

View File

@ -10,16 +10,13 @@
export let form;
let cloudFrontUrl = import.meta.env.VITE_IMAGE_URL;
let mode = true;
//let mode = false;
const emailAddress = "support@stocknear.com";
/*
function toggleMode()
{
function toggleMode() {
mode = !mode;
}
*/
}
let LoginPopup;
@ -47,8 +44,10 @@ function toggleMode()
if (subscriptionType === "lifeTime") {
subId = import.meta.env.VITE_LEMON_SQUEEZY_LIFE_TIME_ACCESS_ID;
} else {
} else if (mode) {
subId = import.meta.env.VITE_LEMON_SQUEEZY_ANNUAL_ID;
} else {
subId = import.meta.env.VITE_LEMON_SQUEEZY_MONTHLY_ID;
}
const isDarkMode =
@ -147,29 +146,30 @@ function toggleMode()
</p>
</div>
<!--
<div class="flex flex-row items-center justify-center mt-6 pb-5">
<span class="text-sm font-semibold text-white mr-3">
Pay Monthly
</span>
<label class="inline-flex cursor-pointer relative ">
<input on:click={toggleMode} type="checkbox" checked={mode} value={mode} class="sr-only peer">
<div class="w-14 h-7 bg-gray-400 rounded-full peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[0.40rem] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-[#1563F9] {mode === false ? 'after:translate-x-[-0.2rem]' : ''} "></div>
</label>
<div class="ml-3 -mb-4 flex flex-col items-start">
<span class="text-sm font-semibold text-white">
Pay Yearly
</span>
<span class="text-[#fff] text-sm font-semibold">
Save up 16%
</span>
</div>
</div>
-->
<div class="flex flex-row items-center justify-center mt-6 pb-5">
<span class="text-sm font-semibold text-white mr-3"> Pay Monthly </span>
<label class="inline-flex cursor-pointer relative">
<input
on:click={toggleMode}
type="checkbox"
checked={mode}
value={mode}
class="sr-only peer"
/>
<div
class="w-14 h-7 bg-gray-400 rounded-full peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[0.40rem] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-[#1563F9] {mode ===
false
? 'after:translate-x-[-0.2rem]'
: ''} "
></div>
</label>
<div class="ml-3 -mb-4 flex flex-col items-start">
<span class="text-sm font-semibold text-white"> Pay Yearly </span>
<span class="text-[#fff] text-sm font-semibold"> Save 50% </span>
</div>
</div>
</div>
<!--<Discount/>-->
@ -347,38 +347,42 @@ function toggleMode()
<div
class="sm:order-2 rounded-md box sm:-mt-10 flex flex-col p-6 lg:p-8 mx-auto w-full text-center text-white bg-[#27272A]"
>
<!--<div class="{!mode ? 'hidden' : ''} ribbon ribbon-top-right"><span class="text-white">Discount</span></div>-->
<div
class="absolute top-0 left-1/2 transform -translate-x-1/2 rounded-b-2xl flex flex-row items-center bg-red-600 p-2"
>
<svg
class="w-6 h-6 mr-2"
fill="#D6D6DC"
viewBox="0 0 48 48"
xmlns="http://www.w3.org/2000/svg"
stroke=""
><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g><g id="SVGRepo_iconCarrier">
<title>star-solid</title>
<g id="Layer_2" data-name="Layer 2">
<g id="invisible_box" data-name="invisible box">
<rect width="48" height="48" fill="none"></rect>
</g>
<g id="icons_Q2" data-name="icons Q2">
<path
d="M24,3a2.1,2.1,0,0,0-1.8,1.1L16.5,15.7,3.7,17.5A2.1,2.1,0,0,0,2.6,21l9.2,8.9L9.7,42.7A2,2,0,0,0,11.6,45l1-.2,11.4-6,11.4,6,1,.2a2,2,0,0,0,1.9-2.3L36.2,29.9,45.4,21a2.1,2.1,0,0,0-1.1-3.5L31.5,15.7,25.8,4.1A2.1,2.1,0,0,0,24,3Z"
></path>
</g>
</g>
</g></svg
>
<span class="text-white text-md font-medium"> Most Popular </span>
<div class="{!mode ? 'hidden' : ''} ribbon ribbon-top-right">
<span class="text-white">Discount</span>
</div>
{#if mode}
<div
class="absolute top-0 left-1/2 transform -translate-x-1/2 rounded-b-2xl flex flex-row items-center bg-red-600 p-2"
>
<svg
class="w-6 h-6 mr-2"
fill="#fff"
viewBox="0 0 48 48"
xmlns="http://www.w3.org/2000/svg"
stroke=""
><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g><g id="SVGRepo_iconCarrier">
<title>star-solid</title>
<g id="Layer_2" data-name="Layer 2">
<g id="invisible_box" data-name="invisible box">
<rect width="48" height="48" fill="none"></rect>
</g>
<g id="icons_Q2" data-name="icons Q2">
<path
d="M24,3a2.1,2.1,0,0,0-1.8,1.1L16.5,15.7,3.7,17.5A2.1,2.1,0,0,0,2.6,21l9.2,8.9L9.7,42.7A2,2,0,0,0,11.6,45l1-.2,11.4-6,11.4,6,1,.2a2,2,0,0,0,1.9-2.3L36.2,29.9,45.4,21a2.1,2.1,0,0,0-1.1-3.5L31.5,15.7,25.8,4.1A2.1,2.1,0,0,0,24,3Z"
></path>
</g>
</g>
</g></svg
>
<span class="text-white text-md font-semibold"> Most Popular </span>
</div>
{/if}
<div class="flex flex-row justify-start items-center mt-10 mb-3">
<img
src={cloudFrontUrl + "/assets/pro_tier_logo.png"}
@ -392,13 +396,17 @@ function toggleMode()
<div class="flex flex-col mb-6 items-center">
<div class="flex flex-row items-center">
<span class="mr-2 text-4xl font-bold">$4.99</span>
<span class="mr-2 text-4xl font-bold"
>{mode ? "$4.99" : "$9.99"}</span
>
<span class="text-white text-xl">/month</span>
</div>
<div class="text-white">(Billed Annually)</div>
<div class="flex items-center mt-2 text-[1rem] text-center">
less than a 🍔
</div>
{#if mode}
<div class="text-white">(Billed Annually)</div>
<div class="flex items-center mt-2 text-[1rem] text-center">
less than a 🍔
</div>
{/if}
<!--
<div class="flex flex-col items-center">
<div class="flex flex-row items-center">

View File

@ -9,6 +9,7 @@
import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js";
import { Button } from "$lib/components/shadcn/button/index.js";
//import * as XLSX from 'xlsx';
import FinancialTable from "$lib/components/FinancialTable.svelte";
import { Chart } from "svelte-echarts";
import { goto } from "$app/navigation";
import { init, use } from "echarts/core";
@ -742,203 +743,7 @@
</thead>
<tbody>
<!-- row -->
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Revenue</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.revenue)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Cost of Revenue</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.costOfRevenue)}</td
>
{/each}
</tr>
<!-- row -->
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Gross Profit</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.grossProfit)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Selling, General & Admin</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(
cash?.sellingGeneralAndAdministrativeExpenses,
)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Research & Development</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(
cash?.researchAndDevelopmentExpenses,
)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Other Expenses</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.otherExpenses)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Operating Expenses</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.o)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Interest Expense</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.interestExpense)}</td
>
{/each}
</tr>
<!-- row -->
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Pretax Income</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.incomeBeforeTax)}</td
>
{/each}
</tr>
<!-- row -->
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Income Tax</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.incomeTaxExpense)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Net Income</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.netIncome)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Shares Outstanding (Basic)</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.weightedAverageShsOut)}</td
>
{/each}
</tr>
<!-- row -->
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>Shares Outstanding (Diluted)</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(
cash?.weightedAverageShsOutDil,
)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>EPS (Basic)</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{cash?.eps?.toFixed(2)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>EPS (Diluted)</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{cash?.epsdiluted?.toFixed(2)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r border-gray-700 text-white text-sm sm:text-[1rem]"
>EBITDA</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.ebitda)}</td
>
{/each}
</tr>
<tr class="text-white odd:bg-[#27272A]">
<td
class="text-start border-r whitespace-nowrap border-[#191E24] text-white text-sm sm:text-[1rem]"
>Depreciation & Amortization</td
>
{#each income as cash}
<td class=" text-sm sm:text-[1rem] text-end">
{abbreviateNumber(cash?.depreciation)}</td
>
{/each}
</tr>
<FinancialTable data={income} />
</tbody>
</table>
</div>