Skip to content
Open

done #33

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
13 changes: 6 additions & 7 deletions .env
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# Public Environment Variables
NEXT_PUBLIC_CURRENCY=$
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=''

# Private Environment Variables
CLERK_SECRET_KEY=''
MONGODB_URI=''
INNGEST_SIGNING_KEY=''
INNGEST_EVENT_KEY=''
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_bW9kZXJuLWJsdWVqYXktNzQuY2xlcmsuYWNjb3VudHMuZGV2JA
# Private Environment Variable
CLERK_SECRET_KEY=sk_test_coposGXvRcb6TqMXPtF5fUYox4R1G4ko83h3I6pU97
MONGODB_URI='mongodb+srv://John:J355984n@cluster0.9bpobcz.mongodb.net'
INNGEST_SIGNING_KEY='signkey-prod-c41d40a4e322b59154f9b506ffee9b2b095c57fca0b888fab56f11bc488cd437'
INNGEST_EVENT_KEY='C-82wnCdq-PV8PTlCFvc2hQbae9clh13gQHAk6LEgo1Vfl4FO-QjDnHcTzB7O79uFF5xuYLG-f_NrVzDcNtiCg'
# Cloudinary
CLOUDINARY_CLOUD_NAME =''
CLOUDINARY_API_KEY =''
Expand Down
12 changes: 12 additions & 0 deletions app/api/inngest/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { serve } from "inngest/next";
import { inngest, syncUserCreation, syncUserDeletion, syncUserUpdation } from "@/config/inngest";

// Create an API that serves zero functions
export const { GET, POST, PUT } = serve({
client: inngest,
functions: [
syncUserCreation,
syncUserUpdation,
syncUserDeletion
],
});
5 changes: 4 additions & 1 deletion app/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ 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 = {
title: "QuickCart - GreatStack",
title: "QuickCart - Ecommerce",
description: "E-Commerce with Next.js ",
};

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>
);
}
56 changes: 46 additions & 10 deletions components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
"use client"
import React from "react";
import { assets} from "@/assets/assets";
import { assets, BagIcon, BoxIcon, CartIcon, HomeIcon } from "@/assets/assets";
import Link from "next/link"
import { useAppContext } from "@/context/AppContext";
import Image from "next/image";
import { useClerk, UserButton } from "@clerk/nextjs";

const Navbar = () => {

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

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 +39,52 @@ 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
? <>
<UserButton>
<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>
</>
: <button onClick={openSignIn} className="flex items-center gap-2 hover:text-gray-900 transition">
<Image src={assets.user_icon} alt="user icon" />
Account
</button>}
</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
? <>
<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>
</>
: <button onClick={openSignIn} className="flex items-center gap-2 hover:text-gray-900 transition">
<Image src={assets.user_icon} alt="user icon" />
Account
</button>}
</div>
</nav>
);
Expand Down
26 changes: 26 additions & 0 deletions config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import mongoose from "mongoose";

let cached = global.mongoose

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

async function connectDB() {
if(cached.conn){
return cached.conn
}

if(!cached.promise){
const opts = {
bufferCommands:false
}
cached.promise = mongoose.connect(`${process.env.MONGODB_URI}/quickcart`,opts).then(mongoose =>{
return mongoose
})
}
cached.conn = await cached.promise
return cached.conn
}

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


// Create a client to send and receive events
export const inngest = new Inngest({ id: "quickcart-next" });

// Inngest Function to save use data to a database

export const syncUserCreation = inngest.createFunction(
{
id:'sync-user-from-clerk'
},
{ event:'clerk/user.created' },
async ({event}) =>{
const { id, first_name, last_name, email_addresses, image_url } = event.data
const userData ={
_id:id,
email:email_addresses[0].email_address,
name:first_name + ' ' + last_name,
imageUrl:image_url

}
await connectDB()
await User.create(userData)
}
)

// Inngest Function to update user data in a database

export const syncUserUpdation = inngest.createFunction(
{
id:'update-user-from-clerk'
},
{ event:'clerk/user.updated' },
async ({event}) =>{
const { id, first_name, last_name, email_addresses, image_url } = event.data
const userData ={
_id:id,
email:email_addresses[0].email_address,
name:first_name + ' ' + last_name,
imageUrl:image_url

}
await connectDB()
await User.findByIdAndUpdate(id,userData )
}
)

// Inngest Function to delete user from the databas
export const syncUserDeletion = inngest.createFunction(
{
id:'delete-user-with-clerk'
},
{event:'clerk/user.deleted'},
async ({event}) =>{
const {id} = event.data

await connectDB()
await User.findByIdAndDelete(id)
}
)
4 changes: 4 additions & 0 deletions context/AppContext.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client'
import { productsDummyData, userDummyData } from "@/assets/assets";
import { useUser } from "@clerk/nextjs";
import { useRouter } from "next/navigation";
import { createContext, useContext, useEffect, useState } from "react";

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
17 changes: 17 additions & 0 deletions models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import mongoose from "mongoose";

const userSchema = new mongoose.Schema(
{
_id: { type: String, required: true },
name: { type: String, required: true },
email: { type: String, required: true, unique: 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