diff --git a/README.md b/README.md index 93c6d9f95..b83df450a 100644 --- a/README.md +++ b/README.md @@ -30,17 +30,8 @@ Contributor Covenant

-
- - - - - +
+
## About this project diff --git a/apps/marketing/src/app/(marketing)/blog/[post]/opengraph-image.tsx b/apps/marketing/src/app/(marketing)/blog/[post]/opengraph/route.tsx similarity index 77% rename from apps/marketing/src/app/(marketing)/blog/[post]/opengraph-image.tsx rename to apps/marketing/src/app/(marketing)/blog/[post]/opengraph/route.tsx index 4c01967d2..70233bbdd 100644 --- a/apps/marketing/src/app/(marketing)/blog/[post]/opengraph-image.tsx +++ b/apps/marketing/src/app/(marketing)/blog/[post]/opengraph/route.tsx @@ -1,25 +1,21 @@ import { ImageResponse } from 'next/og'; - -import { allBlogPosts } from 'contentlayer/generated'; +import { NextResponse } from 'next/server'; export const runtime = 'edge'; -export const contentType = 'image/png'; - -export const IMAGE_SIZE = { +const IMAGE_SIZE = { width: 1200, height: 630, }; -type BlogPostOpenGraphImageProps = { - params: { post: string }; -}; +export async function GET(_request: Request) { + const url = new URL(_request.url); -export default async function BlogPostOpenGraphImage({ params }: BlogPostOpenGraphImageProps) { - const blogPost = allBlogPosts.find((post) => post._raw.flattenedPath === `blog/${params.post}`); + const title = url.searchParams.get('title'); + const author = url.searchParams.get('author'); - if (!blogPost) { - return null; + if (!title || !author) { + return NextResponse.json({ error: 'Not found' }, { status: 404 }); } // The long urls are needed for a compiler optimisation on the Next.js side, lifting this up @@ -49,10 +45,10 @@ export default async function BlogPostOpenGraphImage({ params }: BlogPostOpenGra logo

- {blogPost.title} + {title}

-

Written by {blogPost.authorName}

+

Written by {author}

), { diff --git a/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx b/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx index bd5fdb2da..3e50f8305 100644 --- a/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx +++ b/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx @@ -20,11 +20,23 @@ export const generateMetadata = ({ params }: { params: { post: string } }) => { }; } + // Use the url constructor to ensure that things are escaped as they should be + const searchParams = new URLSearchParams({ + title: blogPost.title, + author: blogPost.authorName, + }); + return { title: { absolute: `${blogPost.title} - Documenso Blog`, }, description: blogPost.description, + openGraph: { + images: [`${blogPost.href}/opengraph?${searchParams.toString()}`], + }, + twitter: { + images: [`${blogPost.href}/opengraph?${searchParams.toString()}`], + }, }; }; @@ -94,7 +106,7 @@ export default function BlogPostPage({ params }: { params: { post: string } }) { - {post.cta && } + {post.cta && } ); } diff --git a/apps/web/src/app/(unauthenticated)/layout.tsx b/apps/web/src/app/(unauthenticated)/layout.tsx index 03a73278f..05055d508 100644 --- a/apps/web/src/app/(unauthenticated)/layout.tsx +++ b/apps/web/src/app/(unauthenticated)/layout.tsx @@ -10,7 +10,7 @@ type UnauthenticatedLayoutProps = { export default function UnauthenticatedLayout({ children }: UnauthenticatedLayoutProps) { return ( -
+
diff --git a/apps/web/src/components/forms/v2/signup.tsx b/apps/web/src/components/forms/v2/signup.tsx index a7e33a759..b3b502993 100644 --- a/apps/web/src/components/forms/v2/signup.tsx +++ b/apps/web/src/components/forms/v2/signup.tsx @@ -108,17 +108,6 @@ export const SignUpFormV2 = ({ const name = form.watch('name'); const url = form.watch('url'); - // To continue we need to make sure name, email, password and signature are valid - const canContinue = - form.formState.dirtyFields.name && - form.formState.errors.name === undefined && - form.formState.dirtyFields.email && - form.formState.errors.email === undefined && - form.formState.dirtyFields.password && - form.formState.errors.password === undefined && - form.formState.dirtyFields.signature && - form.formState.errors.signature === undefined; - const { mutateAsync: signup } = trpc.auth.signup.useMutation(); const onFormSubmit = async ({ name, email, password, signature, url }: TSignUpFormV2Schema) => { @@ -169,6 +158,14 @@ export const SignUpFormV2 = ({ } }; + const onNextClick = async () => { + const valid = await form.trigger(['name', 'email', 'password', 'signature']); + + if (valid) { + setStep('CLAIM_USERNAME'); + } + }; + const onSignUpWithGoogleClick = async () => { try { await signIn('google', { callbackUrl: SIGN_UP_REDIRECT_PATH }); @@ -224,7 +221,7 @@ export const SignUpFormV2 = ({
-
+
{step === 'BASIC_DETAILS' && (

Create a new account

@@ -257,8 +254,8 @@ export const SignUpFormV2 = ({ {step === 'BASIC_DETAILS' && (
@@ -360,8 +357,8 @@ export const SignUpFormV2 = ({ {step === 'CLAIM_USERNAME' && (
@@ -431,9 +428,8 @@ export const SignUpFormV2 = ({ type="button" size="lg" className="flex-1 disabled:cursor-not-allowed" - disabled={!canContinue} loading={form.formState.isSubmitting} - onClick={() => setStep('CLAIM_USERNAME')} + onClick={onNextClick} > Next