diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index d7735c57..b2a6ee8f 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -111,18 +111,16 @@ {#if data?.user} {/if} -

{ + + const apiKey = import.meta.env.VITE_LEMON_SQUEEZY_API_KEY; + + const getLTDCount = async () => { + // make the POST request to the endpoint + const response = await fetch('https://api.lemonsqueezy.com/v1/order-items?page[size]=100', { + headers: { + 'Accept': 'application/vnd.api+json', + 'Content-Type': 'application/vnd.api+json', + 'Authorization': `Bearer ${apiKey}` + } + }); + const output = await response.json(); + const filteredData = output?.data?.filter(item => item?.attributes?.product_name === 'Pro Subscription (Life Time Access)'); + const count = filteredData?.length || 0; + + return count; + }; + + return { + getLTDCount: await getLTDCount(), + }; + }; +*/ + +export const actions = { + login: async ({ request, locals }) => { + const { formData, errors } = await validateData( + await request.formData(), + loginUserSchema, + ); + + if (errors) { + return fail(400, { + data: formData, + errors: errors.fieldErrors, + }); + } + + try { + await locals.pb + .collection("users") + .authWithPassword(formData.email, formData.password); + + /* + if (!locals.pb?.authStore?.model?.verified) { + locals.pb.authStore.clear(); + return { + notVerified: true, + }; + } + */ + } catch (err) { + console.log("Error: ", err); + error(err.status, err.message); + } + + redirect(302, "/pricing"); + }, + + register: async ({ locals, request }) => { + const { formData, errors } = await validateData( + await request.formData(), + registerUserSchema, + ); + + if (errors) { + return fail(400, { + data: formData, + errors: errors.fieldErrors, + }); + } + + try { + await locals.pb.collection("users").create(formData); + /* +await locals.pb?.collection('users').update( + newUser?.id, { + 'freeTrial' : true, + 'tier': 'Pro', //Give new users a free trial for the Pro Subscription + }); +*/ + await locals.pb.collection("users").requestVerification(formData.email); + } catch (err) { + console.log("Error: ", err); + error(err.status, err.message); + } + + try { + await locals.pb + .collection("users") + .authWithPassword(formData.email, formData.password); + } catch (err) { + console.log("Error: ", err); + error(err.status, err.message); + } + + redirect(302, "/pricing"); + }, + + oauth2: async ({ url, locals, request, cookies }) => { + + const path = url?.href?.replace("/oauth2","") + const authMethods = (await locals?.pb + ?.collection("users") + ?.listAuthMethods())?.oauth2; + + + const data = await request?.formData(); + const providerSelected = data?.get("provider"); + + if (!authMethods) { + return { + authProviderRedirect: "", + authProviderState: "", + }; + } + const redirectURL = `${url.origin}/oauth`; + + const targetItem = authMethods?.providers?.findIndex( + (item) => item?.name === providerSelected, + ); + //console.log("==================") + //console.log(authMethods.authProviders) + //console.log('target item is: ', targetItem) + + const provider = authMethods.providers[targetItem]; + const authProviderRedirect = `${provider.authUrl}${redirectURL}`; + const state = provider.state; + const verifier = provider.codeVerifier; + + + + cookies.set("state", state, { + httpOnly: true, + sameSite: "lax", + secure: true, + path: "/", + maxAge: 60 * 60, + }); + + cookies.set("verifier", verifier, { + httpOnly: true, + sameSite: "lax", + secure: true, + path: "/", + maxAge: 60 * 60, + }); + + cookies.set("provider", providerSelected, { + httpOnly: true, + sameSite: "lax", + secure: true, + path: "/", + maxAge: 60 * 60, + }); + + cookies.set("path", path, { + httpOnly: true, + sameSite: "lax", + secure: true, + path: "/", + maxAge: 60, + }); + + redirect(302, authProviderRedirect); + }, +}; + diff --git a/src/routes/discord-bot/+page.svelte b/src/routes/discord-bot/+page.svelte new file mode 100644 index 00000000..253a282a --- /dev/null +++ b/src/routes/discord-bot/+page.svelte @@ -0,0 +1,597 @@ + + + + + + + + + +
+
+
+

+ Instantly 10x Your Discord Server's Value & Engagement +

+
+ + + +
+
+ Monthly + + + +
Annually
+
+
+ +
+
+

+ Stocknear Discord Bot +

+

+ Our bots are designed to help you and your community stay ahead of the + curve by providing data on significant stock data, options and dark + pool trades. +

+
+ +
+

Pro

+

+ Best for Professional Traders +

+
+ {mode ? "$15" : "$20"}/Month +
+

+ (Billed Annually) +

+ +
    +
  • + Everything in Plus and ... +
  • + +
  • + Watchlist with up to 300 stocks +
  • + +
  • + 1,000 Bulk Download Credits +
  • + +
  • + + + Realtime Options Activity +
  • +
  • + + + Realtime Dark Pool Trades +
  • +
+ +
+ +
+
+
+ + +
+
+

+ Compare plans & features +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Research company stocks + + Free + + Plus + + Pro +
Full Market Access
Hedge Fund Portfolio
US Congress Portfolio
Stock ScreenerUnlimitedUnlimited
+ Unusual Activity +
Realtime Options Data from OPRA
Realtime Dark Pool Data
+ Trade Ideas +
No. of Watchlists1UnlimitedUnlimited
No. of Bulk Downloads105001,000
No. of Price Alerts3UnlimitedUnlimited
Wallstreet Analyst Rating
AI Model Forecasts
+
+
+
+ + + + + +
+
+
+ +
+

Frequently Asked Questions

+
+ + +
    +
  • +
    + What are the advantages of Stocknear Service? +
    +

    + Stocknear Service provides simplified, actionable trading + data and an extensive tool suite for every trader, featuring + exclusive, high-quality Wall Street data at an unmatched + price. We also offer proprietary AI models for accurate + forecasting and timely alerts, all within a single, unified + platform. +

    +
    +
    +
  • + +
  • +
    + + What is a Credit and How Can I Use It? + +
    +

    + Your monthly credit allows you to download historical price + data in bulk for all the companies in your watchlist. In the + future, you’ll be able to download a wide range of financial + data in bulk as well. Each company download costs one + credit. For example, in the Plus Tier you can download data + for up to 500 companies per month, while the Pro Tier lets + you download data for up to 1,000 companies. +

    +
    +
    +
  • + +
  • +
    + + Can I change my plan at any time? + +
    +

    + Yes! Simply reach out to us via email, and we’ll take care + of it for you. + + {emailAddress} + +

    +
    +
    +
  • + +
  • +
    + + Are there any commissions in addition to the subscription + plans? + +
    +

    + No, we do not charge any additional commissions or hidden + fees beyond our subscription plans. +

    +
    +
    +
  • +
  • +
    + + Can I request a refund? + +
    +

    + We offer a 30 day money back guarantee, no questions asked. + Just send an email to {emailAddress} and you will get a full refund. +

    +
    +
    +
  • + +
  • +
    + + What are my payment options? + +
    +

    + We support Credit Card & Paypal payments. +

    +
    +
    +
  • + +
  • +
    + + Can I cancel at any time? + +
    +

    + Of course. There is a "Cancel Subscription" button in your + account area that you get access to after signing up. You + can also send us a message and we will cancel for you. +

    +
    +
    +
  • +
  • +
    + + Why is Stocknear so much cheaper than other platforms? + +
    +

    + Stocknear is a solo project, which means I handle everything + myself—eliminating the need for a large team and costly + overhead. This allows me to keep prices low while still + delivering a high-quality service. Unlike many financial + platforms that prioritize high profit margins, my goal is to + make market data accessible to everyone. +

    +
    +
    +
  • +
+
+
+
+ + +
+
+ + +{#if LoginPopup} + +{/if} + + diff --git a/src/routes/learning-center/article/[slug]/+page.svelte b/src/routes/learning-center/article/[slug]/+page.svelte index 2030ca9c..a3525e41 100644 --- a/src/routes/learning-center/article/[slug]/+page.svelte +++ b/src/routes/learning-center/article/[slug]/+page.svelte @@ -7,9 +7,12 @@ let article = data?.getArticle; + let faqs = []; + $: { if (data?.getParams) { article = data?.getArticle; + faqs = data?.getFAQ; } } diff --git a/src/routes/sitemap/+page.svelte b/src/routes/sitemap/+page.svelte index 141284e4..0d81a05a 100644 --- a/src/routes/sitemap/+page.svelte +++ b/src/routes/sitemap/+page.svelte @@ -162,9 +162,13 @@ link: "/donation", }, { - title: "Stock Analysis Pro", + title: "Pricing", link: "/pricing", }, + { + title: "Discord Bot", + link: "/discord-bot", + }, { title: "Free Newsletter", link: "/newsletter", diff --git a/src/routes/sitemaps/[slug]/+server.ts b/src/routes/sitemaps/[slug]/+server.ts index 1efbe4b1..adee88a4 100644 --- a/src/routes/sitemaps/[slug]/+server.ts +++ b/src/routes/sitemaps/[slug]/+server.ts @@ -55,6 +55,7 @@ const pages = [ { title: "/watchlist/stocks" }, { title: "/watchlist/options" }, { title: "/pricing" }, + { title: "/discord-bot" }, { title: "/terms-of-use" }, { title: "/privacy-policy" }, { title: "/imprint" }, diff --git a/static/img/discord-dark-pool-order.png b/static/img/discord-dark-pool-order.png new file mode 100644 index 00000000..7dccf9e6 Binary files /dev/null and b/static/img/discord-dark-pool-order.png differ