mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
Merge branch 'main' of https://github.com/documenso/documenso into feat/swagger-styling
This commit is contained in:
13
README.md
13
README.md
@ -30,17 +30,8 @@
|
||||
<a href="CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg" alt="Contributor Covenant"></a>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://github.com/documenso/documenso/assets/1309312/67e08c98-c153-4115-aa2d-77979bb12c94)">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://github.com/documenso/documenso/assets/1309312/040cfbae-3438-4ca3-87f2-ce52c793dcaf">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://github.com/documenso/documenso/assets/1309312/72d445be-41e5-4936-bdba-87ef8e70fa09">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src="https://github.com/documenso/documenso/assets/1309312/d7b86c0f-a755-4476-a022-a608db2c4633">
|
||||
<img style="display: block; height: 120px; width: 24%"
|
||||
src=https://github.com/documenso/documenso/assets/1309312/c0f55116-ab82-433f-a266-f3fc8571d69f">
|
||||
<div align="center">
|
||||
<img src="https://github.com/documenso/documenso/assets/13398220/d96ed533-6f34-4a97-be9b-442bdb189c69" style="width: 80%;" />
|
||||
</div>
|
||||
|
||||
## About this project
|
||||
|
||||
@ -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
|
||||
<img src={logoImage} alt="logo" tw="h-8" />
|
||||
|
||||
<h1 tw="mt-8 text-6xl text-center flex items-center justify-center w-full max-w-[800px] font-bold text-center mx-auto">
|
||||
{blogPost.title}
|
||||
{title}
|
||||
</h1>
|
||||
|
||||
<p tw="font-normal">Written by {blogPost.authorName}</p>
|
||||
<p tw="font-normal">Written by {author}</p>
|
||||
</div>
|
||||
),
|
||||
{
|
||||
@ -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 } }) {
|
||||
</Link>
|
||||
</article>
|
||||
|
||||
{post.cta && <CallToAction className="mt-8" utmSource={`blog__${params.post}`} />}
|
||||
{post.cta && <CallToAction className="mt-8" utmSource={`blog_${params.post}`} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ type UnauthenticatedLayoutProps = {
|
||||
|
||||
export default function UnauthenticatedLayout({ children }: UnauthenticatedLayoutProps) {
|
||||
return (
|
||||
<main className="relative flex min-h-screen flex-col items-center justify-center overflow-hidden px-4 py-12 md:p-12 lg:p-24">
|
||||
<main className="relative flex min-h-screen flex-col items-center justify-center overflow-hidden px-4 py-12 md:p-12 lg:p-24">
|
||||
<div>
|
||||
<div className="absolute -inset-[min(600px,max(400px,60vw))] -z-[1] flex items-center justify-center opacity-70">
|
||||
<Image
|
||||
|
||||
@ -34,7 +34,7 @@ export default function SignUpPage({ searchParams }: SignUpPageProps) {
|
||||
|
||||
return (
|
||||
<SignUpFormV2
|
||||
className="w-screen max-w-screen-2xl px-4 md:px-16"
|
||||
className="w-screen max-w-screen-2xl px-4 md:px-16 lg:-my-16"
|
||||
initialEmail={email || undefined}
|
||||
isGoogleSSOEnabled={IS_GOOGLE_SSO_ENABLED}
|
||||
/>
|
||||
|
||||
@ -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 = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-border dark:bg-background relative z-10 flex min-h-[min(800px,80vh)] w-full max-w-lg flex-col rounded-xl border bg-neutral-100 p-6">
|
||||
<div className="border-border dark:bg-background relative z-10 flex min-h-[min(850px,80vh)] w-full max-w-lg flex-col rounded-xl border bg-neutral-100 p-6">
|
||||
{step === 'BASIC_DETAILS' && (
|
||||
<div className="h-20">
|
||||
<h1 className="text-xl font-semibold md:text-2xl">Create a new account</h1>
|
||||
@ -257,8 +254,8 @@ export const SignUpFormV2 = ({
|
||||
{step === 'BASIC_DETAILS' && (
|
||||
<fieldset
|
||||
className={cn(
|
||||
'flex h-[500px] w-full flex-col gap-y-4',
|
||||
isGoogleSSOEnabled && 'h-[600px]',
|
||||
'flex h-[550px] w-full flex-col gap-y-4',
|
||||
isGoogleSSOEnabled && 'h-[650px]',
|
||||
)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
@ -360,8 +357,8 @@ export const SignUpFormV2 = ({
|
||||
{step === 'CLAIM_USERNAME' && (
|
||||
<fieldset
|
||||
className={cn(
|
||||
'flex h-[500px] w-full flex-col gap-y-4',
|
||||
isGoogleSSOEnabled && 'h-[600px]',
|
||||
'flex h-[550px] w-full flex-col gap-y-4',
|
||||
isGoogleSSOEnabled && 'h-[650px]',
|
||||
)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
@ -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
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user