Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions docs/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,27 @@ export const {
callbacks: {
signIn: async (params) => {
if (params.profile!.sponsorInfo) {
// TODO
// user is sponsor
return true;
}
// user is signed in to github, but not a sponsor.
// TODO: We could redirect to pricing page here
return true;
return "https://github.com/sponsors/TypeCellOS"; // TODO
// return "https://www.blocknotejs.org/pricing";
},
// https://authjs.dev/guides/extending-the-session
jwt({ token, user }) {
if (user) {
// User is available during sign-in
token.sponsorInfo = (user as any).sponsorInfo;
}
return token;
},
session: async (params) => {
(params.session.user as any).sponsorInfo = (
params.token as any
).sponsorInfo;
return params.session;
},
},
providers: [
Expand Down Expand Up @@ -55,9 +71,11 @@ export const {
"Content-Type": "application/json",
Authorization: `Bearer ${tokens.access_token}`,
},
// organization(login:"TypeCellOS") {
// user(login:"YousefED") {
body: JSON.stringify({
query: `{
organization(login:"TypeCellOS") {
user(login:"YousefED") {
sponsorshipForViewerAsSponsor(activeOnly:false) {
isActive,
tier {
Expand All @@ -71,10 +89,19 @@ export const {
});

if (resSponsor.ok) {
const data = await resSponsor.json();
// Mock data. TODO: disable and test actial data
// profile.sponsorInfo = {
// isActive: true,
// tier: {
// name: "test",
// monthlyPriceInDollars: 100,
// },
// };
// use API data:

const data = await resSponsor.json();
profile.sponsorInfo =
data.data.organization.sponsorshipForViewerAsSponsor;
data.data.organization?.sponsorshipForViewerAsSponsor;
}

return profile;
Expand All @@ -87,7 +114,7 @@ export const {
email: profile.email,
image: profile.avatar_url,
username: profile.login,
sponsorInfo: profile.sponsorsTypeCell,
sponsorInfo: profile.sponsorInfo,
};
},
}),
Expand Down
17 changes: 9 additions & 8 deletions docs/components/AuthNavButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ export function AuthNavButton(props: any) {
/>
</NavbarMenu>
) : (
<></>
// TODO: design button
// <button
// onClick={async () => {
// await signIn("github");
// }}>
// Sign in
// </button>
<>
{/* TODO: move to footer */}{" "}
{/* <button
onClick={async () => {
await signIn("github", {});
}}>
Sign in
</button> */}
</>
);
}

Expand Down
28 changes: 18 additions & 10 deletions docs/components/cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import type { ComponentProps, CSSProperties, ReactNode } from "react";
const classes = {
cards: cn(
"nextra-cards nx-mt-4 nx-gap-4 nx-grid",
"nx-not-prose" // for nextra-theme-docs
"nx-not-prose", // for nextra-theme-docs
),
card: cn(
"nextra-card nx-group nx-flex nx-flex-col nx-justify-between nx-overflow-hidden nx-rounded-lg nx-border nx-border-gray-200",
"nx-text-current nx-no-underline dark:nx-shadow-none",
"hover:nx-shadow-gray-100 dark:hover:nx-shadow-none nx-shadow-gray-100",
"active:nx-shadow-sm active:nx-shadow-gray-200",
"nx-transition-all nx-duration-200 hover:nx-border-gray-300"
"nx-transition-all nx-duration-200 hover:nx-border-gray-300",
),
title: cn(
"nx-flex nx-font-semibold nx-items-start nx-text-gray-700 hover:nx-text-gray-900"
"nx-flex nx-font-semibold nx-items-start nx-text-gray-700 hover:nx-text-gray-900",
),
};

Expand Down Expand Up @@ -54,14 +54,14 @@ export function Card({
href={href}
className={cn(
classes.card,
"nx-bg-gray-100 nx-shadow dark:nx-border-neutral-700 dark:nx-bg-neutral-800 dark:nx-text-gray-50 hover:nx-shadow-lg dark:hover:nx-border-neutral-500 dark:hover:nx-bg-neutral-700"
"nx-bg-gray-100 nx-shadow dark:nx-border-neutral-700 dark:nx-bg-neutral-800 dark:nx-text-gray-50 hover:nx-shadow-lg dark:hover:nx-border-neutral-500 dark:hover:nx-bg-neutral-700",
)}
{...props}>
{children}
<span
className={cn(
classes.title,
"dark:nx-text-gray-300 dark:hover:nx-text-gray-100"
"dark:nx-text-gray-300 dark:hover:nx-text-gray-100",
)}>
{icon}
<span className="nx-flex nx-gap-1">
Expand All @@ -79,21 +79,29 @@ export function Card({
className={cn(
classes.card,
"nx-bg-transparent nx-shadow-sm dark:nx-border-neutral-800 hover:nx-bg-slate-50 hover:nx-shadow-md dark:hover:nx-border-neutral-700 dark:hover:nx-bg-neutral-900",
"nx-flex nx-items-start nx-gap-2 nx-p-4 nx-text-gray-700"
"nx-flex nx-items-start nx-gap-2 nx-p-4 nx-text-gray-700",
)}
{...props}>
<span
className={cn(
classes.title,
"dark:nx-text-neutral-200 dark:hover:nx-text-neutral-50 nx-flex nx-items-center"
"dark:nx-text-neutral-200 dark:hover:nx-text-neutral-50 nx-flex nx-items-center",
)}>
{icon}
{title}
{icon}
{animatedArrow}
</span>
{/* <div className="hover:nx-text-gray-900 nx-items-right">test</div> */}
<div className="text-xs nx-flex nx-items-center nx-gap-2">
{authorImage && <Image className="rounded-md size-5" width={50} height={50} src={authorImage} alt={authorName + " profile image"} />}{" "}
<div className="nx-flex nx-items-center nx-gap-2 text-xs">
{authorImage && (
<Image
className="size-5 rounded-md"
width={50}
height={50}
src={authorImage}
alt={authorName + " profile image"}
/>
)}{" "}
{authorName && <span>{authorName}</span>}
{/* <span>·</span>
<span>💖</span> */}
Expand Down
100 changes: 75 additions & 25 deletions docs/components/example/ExampleBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { signIn } from "next-auth/react";
import dynamic from "next/dynamic";
import { AiFillGithub } from "react-icons/ai";
import { SiStackblitz } from "react-icons/si";

import CTAButton from "../../components/pages/landing/shared/CTAButton";
import { SectionHeader } from "../../components/pages/landing/shared/Headings";
import { examples } from "./generated/exampleComponents.gen";

import "../pages/landing/gradients.css";
import "./styles.css";

const baseGitHubURL = "https://github.com/TypeCellOS/BlockNote/tree/main/";
Expand All @@ -20,38 +25,83 @@ export function ExampleBlock(props: {
name: keyof typeof examples;
path: string;
children: any;
isProExample?: {
userStatus: "business" | "starter" | "free" | undefined;
};
}) {
// const example = examplesFlattened.find((e) => e.slug === props.name);
// if (!example) {
// throw new Error("invalid example");
// }
const showCode =
!props.isProExample ||
props.isProExample.userStatus === "starter" ||
props.isProExample.userStatus === "business";

return (
<div className="demo nx-bg-primary-700/5 dark:nx-bg-primary-300/10 mt-6 rounded-lg p-4">
<div className={"flex flex-row gap-6 pb-4"}>
<a
className={
"nx-select-none nx-text-gray-600 hover:nx-text-black dark:nx-text-gray-200 dark:hover:nx-text-white flex flex-row items-center gap-1"
}
href={`${baseGitHubURL}${props.path}/`}
target="_blank">
<AiFillGithub />
<div className={"text-sm"}>GitHub</div>
</a>
<a
className={
"nx-select-none nx-text-gray-600 hover:nx-text-black dark:nx-text-gray-200 dark:hover:nx-text-white flex flex-row items-center gap-1"
}
href={`${baseStackBlitzURL}${props.path}/`}
target="_blank">
<SiStackblitz />
<div className={"text-sm"}>StackBlitz</div>
</a>
</div>
{showCode && (
<div className={"z-10 flex flex-row gap-6 pb-4"}>
<a
className={
"nx-select-none nx-text-gray-600 hover:nx-text-black dark:nx-text-gray-200 dark:hover:nx-text-white flex flex-row items-center gap-1"
}
href={`${baseGitHubURL}${props.path}/`}
target="_blank">
<AiFillGithub />
<div className={"text-sm"}>GitHub</div>
</a>
<a
className={
"nx-select-none nx-text-gray-600 hover:nx-text-black dark:nx-text-gray-200 dark:hover:nx-text-white flex flex-row items-center gap-1"
}
href={`${baseStackBlitzURL}${props.path}/`}
target="_blank">
<SiStackblitz />
<div className={"text-sm"}>StackBlitz</div>
</a>
</div>
)}
<div className={"demo-contents h-96 overflow-auto rounded-lg"}>
<ThemedExample name={props.name} />
</div>
{props.children}
{showCode ? (
props.children
) : (
<div
className={
"relative flex h-96 flex-col items-center justify-center gap-2"
}>
<div className={"absolute h-1/2 w-1/2"}>
<div className={"cta-glow h-full w-full"}></div>
</div>
<div className={"z-10 flex w-2/3 flex-col items-center"}>
<SectionHeader>Pro Example</SectionHeader>
<p className={"text-center text-[#00000080] dark:text-[#FFFFFFB2]"}>
Get access to the full source code for pro examples by subscribing
to BlockNote Pro
</p>
<div className={"mt-8"}>
<CTAButton
href={"/pricing"}
color={"pro"}
size={"large"}
hoverGlow={true}>
Get BlockNote Pro
</CTAButton>
</div>
{!props.isProExample?.userStatus && (
<p className={"mt-1 text-xs"}>
Or{" "}
<button
className={"nx-text-primary-600"}
onClick={async () => {
await signIn("github", {});
}}>
sign in
</button>{" "}
via GitHub
</p>
)}
</div>
</div>
)}
</div>
);
}
3 changes: 3 additions & 0 deletions docs/components/example/ExampleList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Card, Cards } from "../../components/cards";
import { EXAMPLES_LIST } from "../../components/example/generated/exampleList.gen";
import { ProBadge } from "../../components/example/ProBadge";
import { proExamplesList } from "../../components/example/proExamplesList";

export function ExampleGroup(props: { examples: (typeof EXAMPLES_LIST)[0] }) {
return (
Expand All @@ -14,6 +16,7 @@ export function ExampleGroup(props: { examples: (typeof EXAMPLES_LIST)[0] }) {
key={i}
title={project.text}
href={project.link}
icon={proExamplesList.includes(project.text) && <ProBadge />}
authorName={project.author}
authorImage={`https://github.com/${project.author}.png`}
/>
Expand Down
7 changes: 7 additions & 0 deletions docs/components/example/ProBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function ProBadge() {
return (
<span className="nx-rounded-full mx-1 inline-flex items-center bg-indigo-600/10 px-1.5 text-xs font-medium text-indigo-600 ring-1 ring-inset ring-indigo-600">
Pro
</span>
);
}
12 changes: 10 additions & 2 deletions docs/components/example/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { useSession } from "next-auth/react";
import { getProLevel } from "../../util/authUtil";
import { examples } from "./generated/exampleComponents.gen";

export function Example(props: { name: keyof typeof examples }) {

const session = useSession();
const example = examples[props.name];
if (!example) {
throw new Error(`Example ${props.name} not found`);
}
const ExampleWithCode = example.ExampleWithCode;
const userStatus = getProLevel(session);

return <ExampleWithCode name={props.name} />;
return (
<ExampleWithCode
name={props.name}
isProExample={example.pro ? { userStatus } : undefined}
/>
);
}
11 changes: 11 additions & 0 deletions docs/components/example/proExamplesList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { EXAMPLES_LIST } from "@/components/example/generated/exampleList.gen";
import { examples } from "@/components/example/generated/exampleComponents.gen";

export const proExamplesList = ([] as (typeof EXAMPLES_LIST)[number]["items"])
.concat(...EXAMPLES_LIST.map((example) => example.items))
.filter((example) => {
return examples[
example.link.replace("/examples/", "") as keyof typeof examples
].pro;
})
.map((example) => example.text);
4 changes: 2 additions & 2 deletions docs/components/pages/landing/faq/FAQ.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Link } from "nextra-theme-docs";
import { SectionIntro } from "@/components/pages/landing/shared/Headings";
import { Section } from "@/components/pages/landing/shared/Section";
import { Link } from "nextra-theme-docs";

const faqs = [
{
Expand All @@ -24,7 +24,7 @@ const faqs = [
id: 4,
question: "Is BlockNote really free?",
answer: `100% of BlockNote is open source. While the library is free, we offer paid consultancy and support services to help sustain BlockNote.
Sponsoring the project is encouraged if you are using BlockNote in a commercial project.`,
If you are using BlockNote in a commercial project, we encourage to sign up for BlockNote Pro!`,
},
];

Expand Down
Loading