Skip to content

Commit

Permalink
refactored the code base
Browse files Browse the repository at this point in the history
  • Loading branch information
lakshaybhushan committed Aug 23, 2024
1 parent 7d98186 commit ce02241
Show file tree
Hide file tree
Showing 21 changed files with 377 additions and 277 deletions.
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

{
"plugins": ["prettier-plugin-tailwindcss"],
"bracketSameLine": true
}
36 changes: 0 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +0,0 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
41 changes: 22 additions & 19 deletions app/api/mail/route.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import { render } from "@react-email/render"
import { render } from "@react-email/render";

import WelcomeTemplate from "../../../emails"
import WelcomeTemplate from "../../../emails";

import { Resend } from "resend"
import { NextRequest, NextResponse } from "next/server"
import { Redis } from "@upstash/redis"
import { Ratelimit } from "@upstash/ratelimit"
import { Resend } from "resend";
import { NextRequest, NextResponse } from "next/server";
import { Redis } from "@upstash/redis";
import { Ratelimit } from "@upstash/ratelimit";

const resend = new Resend(process.env.RESEND_API_KEY)
const resend = new Resend(process.env.RESEND_API_KEY);

const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
})
});

const ratelimit = new Ratelimit({
redis,
limiter: Ratelimit.fixedWindow(3, "1 m"),
})
// 2 requests per minute from the same IP address in a sliding window of 1 minute duration which means that the window slides forward every second and the rate limit is reset every minute for each IP address.
limiter: Ratelimit.slidingWindow(2, "1 m"),
});

export async function POST(request: NextRequest, response: NextResponse) {
const ip = request.ip ?? "127.0.0.1"
const ip = request.ip ?? "127.0.0.1";

const result = await ratelimit.limit(ip)
const result = await ratelimit.limit(ip);

if (!result.success) {
return Response.json(
Expand All @@ -31,27 +32,29 @@ export async function POST(request: NextRequest, response: NextResponse) {
},
{
status: 429,
}
)
},
);
}

const { email, firstname } = await request.json()
const { email, firstname } = await request.json();

const { data, error } = await resend.emails.send({
from: "morph2json <[email protected]>",
to: [email],
subject: "Thankyou for waitlisting morph2json!",
reply_to: "[email protected]",
html: render(WelcomeTemplate({ userFirstname: firstname })),
})
});

// const { data, error } = { data: true, error: null }

if (error) {
return NextResponse.json(error)
return NextResponse.json(error);
}

if (!data) {
return NextResponse.json({ message: "Failed to send email" })
return NextResponse.json({ message: "Failed to send email" });
}

return NextResponse.json({ message: "Email sent successfully" })
return NextResponse.json({ message: "Email sent successfully" });
}
16 changes: 8 additions & 8 deletions app/api/notion/waitlist/route.ts → app/api/notion/route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Client } from "@notionhq/client"
import { NextResponse } from "next/server"
import { Client } from "@notionhq/client";
import { NextResponse } from "next/server";

export async function POST(request: Request) {
const body = await request.json()
const body = await request.json();
try {
const notion = new Client({ auth: process.env.NOTION_SECRET })
const notion = new Client({ auth: process.env.NOTION_SECRET });
const response = await notion.pages.create({
parent: {
database_id: `${process.env.NOTION_DB}`,
Expand All @@ -31,14 +31,14 @@ export async function POST(request: Request) {
],
},
},
})
});

if (!response) {
throw new Error("Failed to add email to Notion")
throw new Error("Failed to add email to Notion");
}

return NextResponse.json({ success: true }, { status: 200 })
return NextResponse.json({ success: true }, { status: 200 });
} catch (error) {
return NextResponse.json({ success: false }, { status: 500 })
return NextResponse.json({ success: false }, { status: 500 });
}
}
Binary file modified app/favicon.ico
Binary file not shown.
23 changes: 11 additions & 12 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import "./globals.css"
import type { Metadata } from "next"
import { Figtree } from "next/font/google"
import { Toaster } from "@/components/ui/sonner"
import { Analytics } from "@vercel/analytics/react"
import "./globals.css";
import type { Metadata } from "next";
import { Figtree } from "next/font/google";
import { Toaster } from "@/components/ui/sonner";
import { Analytics } from "@vercel/analytics/react";

const FigtreeFont = Figtree({ subsets: ["latin"] })
const FigtreeFont = Figtree({ subsets: ["latin"] });

export const metadata: Metadata = {
title:
"morph2json | Effortlessly Convert your raw data into a well structured JSON",
title: "Next.js + Notion — Waitlist",
description:
"Join the waitlist to get early access to morph2json and get notified when it's ready for you to use.",
}
"A simple Next.js waitlist template with Notion as CMS and Resend to send emails created with React Email and Upstash Redis for rate limiting. Deployed on Vercel.",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
children: React.ReactNode;
}>) {
return (
<html lang="en" className="dark" suppressHydrationWarning>
Expand All @@ -26,5 +25,5 @@ export default function RootLayout({
<Analytics />
</body>
</html>
)
);
}
Loading

0 comments on commit ce02241

Please sign in to comment.