Skip to content

Instantly share code, notes, and snippets.

@adrianhajdin
Created May 5, 2023 13:13
Show Gist options
  • Save adrianhajdin/6df61c6cd5ed052dce814a765bff9032 to your computer and use it in GitHub Desktop.
Save adrianhajdin/6df61c6cd5ed052dce814a765bff9032 to your computer and use it in GitHub Desktop.
Next.js 13 Full Course 2023 | Build and Deploy a Full Stack App Using the Official React Framework
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;
/*
Note: The styles for this gradient grid background is heavily inspired by the creator of this amazing site (https://dub.sh) – all credits go to them!
*/
.main {
width: 100vw;
min-height: 100vh;
position: fixed;
display: flex;
justify-content: center;
padding: 120px 24px 160px 24px;
pointer-events: none;
}
.main:before {
background: radial-gradient(circle, rgba(2, 0, 36, 0) 0, #fafafa 100%);
position: absolute;
content: "";
z-index: 2;
width: 100%;
height: 100%;
top: 0;
}
.main:after {
content: "";
background-image: url("/assets/images/grid.svg");
z-index: 1;
position: absolute;
width: 100%;
height: 100%;
top: 0;
opacity: 0.4;
filter: invert(1);
}
.gradient {
height: fit-content;
z-index: 3;
width: 100%;
max-width: 640px;
background-image: radial-gradient(
at 27% 37%,
hsla(215, 98%, 61%, 1) 0px,
transparent 0%
),
radial-gradient(at 97% 21%, hsla(125, 98%, 72%, 1) 0px, transparent 50%),
radial-gradient(at 52% 99%, hsla(354, 98%, 61%, 1) 0px, transparent 50%),
radial-gradient(at 10% 29%, hsla(256, 96%, 67%, 1) 0px, transparent 50%),
radial-gradient(at 97% 96%, hsla(38, 60%, 74%, 1) 0px, transparent 50%),
radial-gradient(at 33% 50%, hsla(222, 67%, 73%, 1) 0px, transparent 50%),
radial-gradient(at 79% 53%, hsla(343, 68%, 79%, 1) 0px, transparent 50%);
position: absolute;
content: "";
width: 100%;
height: 100%;
filter: blur(100px) saturate(150%);
top: 80px;
opacity: 0.15;
}
@media screen and (max-width: 640px) {
.main {
padding: 0;
}
}
/* Tailwind Styles */
.app {
@apply relative z-10 flex justify-center items-center flex-col max-w-7xl mx-auto sm:px-16 px-6;
}
.black_btn {
@apply rounded-full border border-black bg-black py-1.5 px-5 text-white transition-all hover:bg-white hover:text-black text-center text-sm font-inter flex items-center justify-center;
}
.outline_btn {
@apply rounded-full border border-black bg-transparent py-1.5 px-5 text-black transition-all hover:bg-black hover:text-white text-center text-sm font-inter flex items-center justify-center;
}
.head_text {
@apply mt-5 text-5xl font-extrabold leading-[1.15] text-black sm:text-6xl;
}
.orange_gradient {
@apply bg-gradient-to-r from-amber-500 via-orange-600 to-yellow-500 bg-clip-text text-transparent;
}
.green_gradient {
@apply bg-gradient-to-r from-green-400 to-green-500 bg-clip-text text-transparent;
}
.blue_gradient {
@apply bg-gradient-to-r from-blue-600 to-cyan-600 bg-clip-text text-transparent;
}
.desc {
@apply mt-5 text-lg text-gray-600 sm:text-xl max-w-2xl;
}
.search_input {
@apply block w-full rounded-md border border-gray-200 bg-white py-2.5 font-satoshi pl-5 pr-12 text-sm shadow-lg font-medium focus:border-black focus:outline-none focus:ring-0;
}
.copy_btn {
@apply w-7 h-7 rounded-full bg-white/10 shadow-[inset_10px_-50px_94px_0_rgb(199,199,199,0.2)] backdrop-blur flex justify-center items-center cursor-pointer;
}
.glassmorphism {
@apply rounded-xl border border-gray-200 bg-white/20 shadow-[inset_10px_-50px_94px_0_rgb(199,199,199,0.2)] backdrop-blur p-5;
}
.prompt_layout {
@apply space-y-6 py-8 sm:columns-2 sm:gap-6 xl:columns-3;
}
/* Feed Component */
.feed {
@apply mt-16 mx-auto w-full max-w-xl flex justify-center items-center flex-col gap-2;
}
/* Form Component */
.form_textarea {
@apply w-full flex rounded-lg h-[200px] mt-2 p-3 text-sm text-gray-500 outline-0;
}
.form_input {
@apply w-full flex rounded-lg mt-2 p-3 text-sm text-gray-500 outline-0;
}
/* Nav Component */
.logo_text {
@apply max-sm:hidden font-satoshi font-semibold text-lg text-black tracking-wide;
}
.dropdown {
@apply absolute right-0 top-full mt-3 w-full p-5 rounded-lg bg-white min-w-[210px] flex flex-col gap-2 justify-end items-end;
}
.dropdown_link {
@apply text-sm font-inter text-gray-700 hover:text-gray-500 font-medium;
}
/* PromptCard Component */
.prompt_card {
@apply flex-1 break-inside-avoid rounded-lg border border-gray-300 bg-white/20 bg-clip-padding p-6 pb-4 backdrop-blur-lg backdrop-filter md:w-[360px] w-full h-fit;
}
.flex-center {
@apply flex justify-center items-center;
}
.flex-start {
@apply flex justify-start items-start;
}
.flex-end {
@apply flex justify-end items-center;
}
.flex-between {
@apply flex justify-between items-center;
}
{
"compilerOptions": {
"paths": {
"@*": ["./*"]
}
}
}
import Prompt from "@models/prompt";
import { connectToDB } from "@utils/database";
export const GET = async (request, { params }) => {
try {
await connectToDB()
const prompt = await Prompt.findById(params.id).populate("creator")
if (!prompt) return new Response("Prompt Not Found", { status: 404 });
return new Response(JSON.stringify(prompt), { status: 200 })
} catch (error) {
return new Response("Internal Server Error", { status: 500 });
}
}
export const PATCH = async (request, { params }) => {
const { prompt, tag } = await request.json();
try {
await connectToDB();
// Find the existing prompt by ID
const existingPrompt = await Prompt.findById(params.id);
if (!existingPrompt) {
return new Response("Prompt not found", { status: 404 });
}
// Update the prompt with new data
existingPrompt.prompt = prompt;
existingPrompt.tag = tag;
await existingPrompt.save();
return new Response("Successfully updated the Prompts", { status: 200 });
} catch (error) {
return new Response("Error Updating Prompt", { status: 500 });
}
};
export const DELETE = async (request, { params }) => {
try {
await connectToDB();
// Find the prompt by ID and remove it
await Prompt.findByIdAndRemove(params.id);
return new Response("Prompt deleted successfully", { status: 200 });
} catch (error) {
return new Response("Error deleting prompt", { status: 500 });
}
};
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
fontFamily: {
satoshi: ['Satoshi', 'sans-serif'],
inter: ['Inter', 'sans-serif'],
},
colors: {
'primary-orange': '#FF5722',
}
},
},
plugins: [],
}
username: {
type: String,
required: [true, 'Username is required!'],
match: [/^(?=.{8,20}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(?<![_.])$/, "Username invalid, it should contain 8-20 alphanumeric letters and be unique!"]
},
@NateSewel
Copy link

Thanks for the update

@GWMolekoa
Copy link

Hi Guys this is the build-error I recieved when trying to deploy the app to vercel. How I can resolve this? your assistance will be highly appreciated..

here is the build error:

at u (/vercel/path0/.next/server/app/api/prompt/route.js:1:564)
at /vercel/path0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:36963
at /vercel/path0/node_modules/next/dist/server/lib/trace/tracer.js:140:36
at NoopContextManager.with (/vercel/path0/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:7062)
at ContextAPI.with (/vercel/path0/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:518)
at NoopTracer.startActiveSpan (/vercel/path0/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:18093)

Generating static pages (4/9)
Generating static pages (6/9)
⨯ useSearchParams() should be wrapped in a suspense boundary at page "/update-prompt". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
at a (/vercel/path0/.next/server/chunks/494.js:1:31244)
at c (/vercel/path0/.next/server/chunks/494.js:1:42184)
at i (/vercel/path0/.next/server/app/update-prompt/page.js:1:2082)
at nj (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:46251)
at nM (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47571)
at nN (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64546)
at nI (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47010)
at nM (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:47717)
at nM (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:61546)
at nN (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:64546)
Error occurred prerendering page "/update-prompt". Read more: https://nextjs.org/docs/messages/prerender-error
✓ Generating static pages (9/9)

Export encountered errors on following paths:
/update-prompt/page: /update-prompt
Error: Command "npm run build" exited with 1

@kousar-coder
Copy link

@Wriloant
Copy link

can anyone help me out with this one ...! (TypeError: Cannot read properties of undefined (reading 'image')
at PromptCard (webpack-internal:///(app-pages-browser)/./components/PromptCard.jsx:46:51)
at react-stack-bottom-frame (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:22349:20)
at renderWithHooks (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:5740:22)
at updateFunctionComponent (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:8001:19)
at beginWork (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:9666:18)
at runWithFiberInDEV (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:544:16)
at performUnitOfWork (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14997:22)
at workLoopSync (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14827:41)
at renderRootSync (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14807:11)
at performWorkOnRoot (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14342:44)
at performWorkOnRootViaSchedulerTask (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:15853:7)
at MessagePort.performWorkUntilDeadline (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:44:48)
Screenshot (654)
)

@PokePiece
Copy link

Make sure to have a return true statement at the end of your async signIn function. This might help solve an access denied error. That way the server knows to log the user in after creation.

async signIn({ profile }) {
try {
await connectToDB();

        const userExists = await User.findOne({
            email: profile.email
        })

        if(!userExists) {
            await User.create({
                email: profile.email,
                username: profile.name.replace(/\s/g, "").toLowerCase(),
                image: profile.picture
            })
        }

        return true;

@andrewchiu198
Copy link

Hello everyone. I´ve been having this issue and don´t know how to fix it. imagem_2024-07-18_211952807 Would appreciate some help.

Hello pls if u solve the problem tell how to do because i have the same error

Check your MongoDB database, for any prompts that are missing the creator key/field and delete those prompts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment