Skip to content
Open
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
14 changes: 7 additions & 7 deletions .env
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Public Environment Variables
NEXT_PUBLIC_CURRENCY=$
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=''
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_YWNlLWxhbWItNjguY2xlcmsuYWNjb3VudHMuZGV2JA

# Private Environment Variables
CLERK_SECRET_KEY=''
MONGODB_URI=''
INNGEST_SIGNING_KEY=''
INNGEST_EVENT_KEY=''
CLERK_SECRET_KEY=sk_test_69K1V59eStDC8kYB1rF1yNwLJgvbGmtt9y1RGdbAAC
MONGODB_URI='mongodb+srv://shreyankkasabale_db_user:peGCjRYmaICahya8@cluster0.uh84wxc.mongodb.net'
INNGEST_SIGNING_KEY='GhTo11zImUmfsYji2W7DMYSXrjFnv595l50owE-AA8aBcNtGFc_VtavbqdSwln9hNBOtkJiWpSPq62bAk9QyeQ'
INNGEST_EVENT_KEY='GhTo11zImUmfsYji2W7DMYSXrjFnv595l50owE-AA8aBcNtGFc_VtavbqdSwln9hNBOtkJiWpSPq62bAk9QyeQ'
# Cloudinary
CLOUDINARY_CLOUD_NAME =''
CLOUDINARY_API_KEY =''
CLOUDINARY_API_SECRET =''
CLOUDINARY_API_SECRET =''

11 changes: 11 additions & 0 deletions app/api/inngest/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { serve } from "inngest/next";
import inngest, {
syncUserCreation,
syncUserDeletion,
syncUserUpdate,
} from "@/config/ingest";

export const { GET, POST, PUT } = serve({
client: inngest,
functions: [syncUserCreation, syncUserUpdate, syncUserDeletion],
});
5 changes: 4 additions & 1 deletion app/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Outfit } from "next/font/google";
import "./globals.css";
import { AppContextProvider } from "@/context/AppContext";
import { Toaster } from "react-hot-toast";

import { ClerkProvider } from "@clerk/nextjs";

const outfit = Outfit({ subsets: ['latin'], weight: ["300", "400", "500"] })

export const metadata = {
Expand All @@ -12,6 +13,7 @@ export const metadata = {

export default function RootLayout({ children }) {
return (
<ClerkProvider>
<html lang="en">
<body className={`${outfit.className} antialiased text-gray-700`} >
<Toaster />
Expand All @@ -20,5 +22,6 @@ export default function RootLayout({ children }) {
</AppContextProvider>
</body>
</html>
</ClerkProvider>
);
}
57 changes: 48 additions & 9 deletions components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"use client"
import React from "react";
import { assets} from "@/assets/assets";
import { assets, CartIcon, HomeIcon, BoxIcon, BagIcon, } from "@/assets/assets";
import Link from "next/link"
import { useAppContext } from "@/context/AppContext";
import Image from "next/image";
import { useClerk, useUser, UserButton } from "@clerk/nextjs";

const Navbar = () => {

const { isSeller, router } = useAppContext();
const { openSignIn } = useClerk();
const { user } = useUser();

return (
<nav className="flex items-center justify-between px-6 md:px-16 lg:px-32 py-3 border-b border-gray-300 text-gray-700">
Expand Down Expand Up @@ -37,18 +40,54 @@ const Navbar = () => {

<ul className="hidden md:flex items-center gap-4 ">
<Image className="w-4 h-4" src={assets.search_icon} alt="search icon" />
<button className="flex items-center gap-2 hover:text-gray-900 transition">
<Image src={assets.user_icon} alt="user icon" />
Account
</button>
{ !user
? <button onClick={openSignIn} className="flex items-center gap-2 hover:text-gray-900 transition">
<Image src={assets.user_icon} alt="user icon" />
Account
</button>
: <>
<UserButton>
<UserButton.MenuItems>
<UserButton.Action label="Home" labelIcon={<HomeIcon/>} onClick={() => router.push('/')}/>
</UserButton.MenuItems>
<UserButton.MenuItems>
<UserButton.Action label="Products" labelIcon={<BoxIcon/>} onClick={() => router.push('/all-products')}/>
</UserButton.MenuItems>
<UserButton.MenuItems>
<UserButton.Action label="Cart" labelIcon={<CartIcon/>} onClick={() => router.push('/cart')}/>
</UserButton.MenuItems>
<UserButton.MenuItems>
<UserButton.Action label="My Orders" labelIcon={<BagIcon/>} onClick={() => router.push('/my-orders')}/>
</UserButton.MenuItems>
</UserButton>
</>
}
</ul>

<div className="flex items-center md:hidden gap-3">
{isSeller && <button onClick={() => router.push('/seller')} className="text-xs border px-4 py-1.5 rounded-full">Seller Dashboard</button>}
<button className="flex items-center gap-2 hover:text-gray-900 transition">
<Image src={assets.user_icon} alt="user icon" />
Account
</button>
{ !user
? <button onClick={openSignIn} className="flex items-center gap-2 hover:text-gray-900 transition">
<Image src={assets.user_icon} alt="user icon" />
Account
</button>
: <>
<UserButton>
<UserButton.MenuItems>
<UserButton.Action label="Home" labelIcon={<HomeIcon/>} onClick={() => router.push('/')}/>
</UserButton.MenuItems>
<UserButton.MenuItems>
<UserButton.Action label="Products" labelIcon={<BoxIcon/>} onClick={() => router.push('/all-products')}/>
</UserButton.MenuItems>
<UserButton.MenuItems>
<UserButton.Action label="Cart" labelIcon={<CartIcon/>} onClick={() => router.push('/cart')}/>
</UserButton.MenuItems>
<UserButton.MenuItems>
<UserButton.Action label="My Orders" labelIcon={<BagIcon/>} onClick={() => router.push('/my-orders')}/>
</UserButton.MenuItems>
</UserButton>
</>
}
</div>
</nav>
);
Expand Down
12 changes: 12 additions & 0 deletions components/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { clerkMiddleware } from '@clerk/nextjs/server';

export default clerkMiddleware();

export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
// Always run for API routes
'/(api|trpc)(.*)',
],
};
28 changes: 28 additions & 0 deletions config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import mongoose from "mongoose";

let cached = global.mongoose;

if (!cached) {
cached = global.mongoose = { conn: null, promise: null };
}

export const connectDB = async () => {
if (cached.conn) return cached.conn;
if (!cached.promise) {
const opts = {
bufferCommands: false,
};
cached.promise = mongoose.connect(`${process.env.MONGODB_URI}/ecommerce`, opts).then((mongoose) => {
return mongoose;
});
}
try {
cached.conn = await cached.promise;
} catch (e) {
cached.promise = null;
throw e;
}
return cached.conn;
}

export default connectDB;
53 changes: 53 additions & 0 deletions config/ingest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Inngest } from "inngest";
import { connectDB } from "@/config/db";
import User from "@/models/user";

const inngest = new Inngest({
id: "quickcart",
name: "QuickCart",
});

export const syncUserCreation = inngest.createFunction(
{ id: "sync-user-created-from-clerk" },
{ event: "clerk/user.created" },
async ({ event }) => {
const { id, email_addresses, image_url, first_name, last_name } =
event.data;
const userData = {
_id: id,
name: `${first_name || ""} ${last_name || ""}`.trim() || "User",
email: email_addresses?.[0]?.email_address,
imageUrl: image_url,
};
await connectDB();
await User.create(userData);
}
);

export const syncUserUpdate = inngest.createFunction(
{ id: "sync-user-updated-from-clerk" },
{ event: "clerk/user.updated" },
async ({ event }) => {
const { id, email_addresses, image_url, first_name, last_name } =
event.data;
const userData = {
name: `${first_name || ""} ${last_name || ""}`.trim() || "User",
email: email_addresses?.[0]?.email_address,
imageUrl: image_url,
};
await connectDB();
await User.findByIdAndUpdate(id, userData);
}
);

export const syncUserDeletion = inngest.createFunction(
{ id: "sync-user-deleted-from-clerk" },
{ event: "clerk/user.deleted" },
async ({ event }) => {
const { id } = event.data;
await connectDB();
await User.findByIdAndDelete(id);
}
);

export default inngest;
4 changes: 4 additions & 0 deletions context/AppContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { productsDummyData, userDummyData } from "@/assets/assets";
import { useRouter } from "next/navigation";
import { createContext, useContext, useEffect, useState } from "react";
import { useUser } from "@clerk/nextjs";

export const AppContext = createContext();

Expand All @@ -14,6 +15,8 @@ export const AppContextProvider = (props) => {
const currency = process.env.NEXT_PUBLIC_CURRENCY
const router = useRouter()

const { user } = useUser();

const [products, setProducts] = useState([])
const [userData, setUserData] = useState(false)
const [isSeller, setIsSeller] = useState(true)
Expand Down Expand Up @@ -82,6 +85,7 @@ export const AppContextProvider = (props) => {
}, [])

const value = {
user,
currency, router,
isSeller, setIsSeller,
userData, fetchUserData,
Expand Down
29 changes: 29 additions & 0 deletions models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import mongoose from "mongoose";

const userSchema = new mongoose.Schema({
_id: {
type: String,
required: true,
},
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
imageUrl: {
type: String,
required: true,
},
cartItems: {
type: Object,
default: {},
},

}, { minimize: false });

const User = mongoose.models.User || mongoose.model('User', userSchema);

export default User;
Loading