Skip to content

Commit 408b466

Browse files
committed
feat: Add mongoose dependency and create API endpoints for fetching and adding user data
- Add "mongoose" dependency to the client's package.json file - Create a new API endpoint "fetchdata" in the client's pages/api directory to fetch user data from the MongoDB database - Create a new API endpoint "add" in the client's pages/api directory to add new user data to the database - Define the "UserData" model in the client's models/userdata.ts file to represent the structure of user data in the database Related to #123
1 parent 8e59bf3 commit 408b466

File tree

8 files changed

+303
-17
lines changed

8 files changed

+303
-17
lines changed

client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
},
1111
"dependencies": {
1212
"axios": "^1.7.3",
13+
"mongoose": "^8.5.2",
1314
"next": "14.2.5",
1415
"react": "^18",
1516
"react-dom": "^18"

client/src/app/components/GenerateStats.tsx

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { data as defaultData } from "./Card";
77
const GenerateStats = ({ showStats, setShowStats }: any) => {
88
const [username, setUsername] = useState("");
99
const [data, setData] = useState<any>(defaultData);
10+
1011
const generateStats = (e: React.FormEvent) => {
1112
e.preventDefault();
1213

@@ -26,6 +27,26 @@ const GenerateStats = ({ showStats, setShowStats }: any) => {
2627
}
2728
};
2829

30+
const addToLeetboard = async () => {
31+
try {
32+
const response = await fetch("/api/add", {
33+
method: "POST",
34+
headers: {
35+
"Content-Type": "application/json",
36+
},
37+
body: JSON.stringify(data),
38+
});
39+
const result = await response.json();
40+
if (result.success) {
41+
console.log("Data added to the hall of fame");
42+
} else {
43+
console.error("Error adding data to the hall of fame");
44+
}
45+
} catch (error) {
46+
console.error("An error occurred while adding data to the hall of fame");
47+
}
48+
};
49+
2950
return (
3051
<div
3152
onClick={() => setShowStats(false)}
@@ -69,7 +90,11 @@ const GenerateStats = ({ showStats, setShowStats }: any) => {
6990
>
7091
Generate <span className="hidden sm:inline-block">Stats</span>
7192
</button>
72-
<button className=" border bg-[#010101] px-4 h-[40px] rounded-md text-white font-semibold text-lg mt-4">
93+
<button
94+
type="button"
95+
onClick={addToLeetboard}
96+
className=" border bg-[#010101] px-4 h-[40px] rounded-md text-white font-semibold text-lg mt-4"
97+
>
7398
Add to <span className="">Leetboard</span>
7499
</button>
75100
</div>

client/src/app/page.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,28 @@ import Navbar from "./components/Navbar";
55
import Card from "./components/Card";
66
import Footer from "./components/Footer";
77
import GenerateStats from "./components/GenerateStats";
8-
import { useState } from "react";
8+
import { useEffect, useState } from "react";
99
import PromotionCard from "./components/PromotionCard";
1010

1111
export default function Home() {
12+
const [data, setData] = useState<any>();
13+
const [loading, setLoading] = useState(true);
14+
const fetchData = async () => {
15+
try {
16+
const res = await fetch("/api/fetchdata");
17+
const data = await res.json();
18+
setData(data.data);
19+
console.log(data.data);
20+
setLoading(false);
21+
} catch (error) {
22+
console.error("Error fetching messages:", error);
23+
}
24+
};
25+
26+
useEffect(() => {
27+
fetchData();
28+
}, []);
29+
1230
const [showStats, setShowStats] = useState(false);
1331
return (
1432
<section className="px-4 lg:px-24 relative ">
@@ -30,7 +48,10 @@ export default function Home() {
3048

3149
<div className="mt-32 max-w-7xl mx-auto place-items-center grid grid-cols-1 md:grid-cols-2 gap-y-8 xl:grid-cols-3 font-sourcecodepro gap-x-4">
3250
<PromotionCard />
33-
{[Array.from({ length: 12 }, (_, i) => <Card key={i} />)]}
51+
{data &&
52+
data.map((userData: any, index: number) => (
53+
<Card userData={userData} index={index} key={index} />
54+
))}
3455
</div>
3556

3657
<Footer />

client/src/lib/mongodb.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import mongoose from 'mongoose';
2+
3+
const MONGODB_URI = 'mongodb+srv://hackerdruv:TwE0oLsj8kd0ql78@workflo.skbz2gj.mongodb.net/leetcode?retryWrites=true&w=majority&appName=workflo';
4+
if (!MONGODB_URI) {
5+
throw new Error('Please define the MONGODB_URI environment variable inside .env.local');
6+
}
7+
8+
let cached = global.mongoose;
9+
10+
if (!cached) {
11+
cached = global.mongoose = { conn: null, promise: null };
12+
}
13+
14+
async function connectToDatabase() {
15+
if (cached.conn) {
16+
return cached.conn;
17+
}
18+
19+
if (!cached.promise) {
20+
const opts = {
21+
useNewUrlParser: true,
22+
useUnifiedTopology: true,
23+
bufferCommands: false,
24+
25+
};
26+
27+
cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
28+
return mongoose;
29+
});
30+
}
31+
cached.conn = await cached.promise;
32+
return cached.conn;
33+
}
34+
35+
export default connectToDatabase;

client/src/models/userdata.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import mongoose from "mongoose";
2+
3+
const userDataSchema = new mongoose.Schema({
4+
profileData: {
5+
image: String,
6+
fullName: String,
7+
username: String,
8+
rank: String,
9+
},
10+
aboutData: {
11+
github: {
12+
link: String,
13+
text: String,
14+
},
15+
twitter: {
16+
link: String,
17+
text: String,
18+
},
19+
linkedin: {
20+
link: String,
21+
text: String,
22+
},
23+
website: {
24+
link: String,
25+
text: String,
26+
},
27+
},
28+
29+
totalSolved: Number,
30+
easySolved: Number,
31+
easyTotal: Number,
32+
mediumSolved: Number,
33+
mediumTotal: Number,
34+
hardSolved: Number,
35+
hardTotal: Number,
36+
});
37+
38+
export default mongoose.models.userdatas ||
39+
mongoose.model("userdatas", userDataSchema);

client/src/pages/api/add.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// pages/api/messages.js
2+
import connectToDatabase from "../../lib/mongodb";
3+
import UserData from "../../models/userdata";
4+
5+
export default async function handler(req: any, res: any) {
6+
const { method } = req;
7+
8+
await connectToDatabase();
9+
10+
switch (method) {
11+
case "POST":
12+
try {
13+
const { username } = req.body.profileData;
14+
15+
// Check if the user already exists
16+
const existingUser = await UserData.findOne({
17+
"profileData.username": username,
18+
});
19+
20+
if (existingUser) {
21+
return res
22+
.status(400)
23+
.json({ success: false, message: "Username already exists" });
24+
}
25+
26+
// Create new user if username doesn't exist
27+
const message = await UserData.create(req.body);
28+
res.status(201).json({ success: true, data: message });
29+
} catch (error) {
30+
res.status(400).json({ success: false, error });
31+
}
32+
break;
33+
34+
default:
35+
res.status(400).json({ success: false });
36+
break;
37+
}
38+
}

client/src/pages/api/fetchdata.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// pages/api/messages.js
2+
import connectToDatabase from "../../lib/mongodb";
3+
import UserData from "../../models/userdata";
4+
5+
export default async function handler(req: any, res: any) {
6+
const { method } = req;
7+
8+
await connectToDatabase();
9+
10+
switch (method) {
11+
case "GET":
12+
try {
13+
const messages = await UserData.find({});
14+
res.status(200).json({ success: true, data: messages });
15+
} catch (error) {
16+
res.status(400).json({ success: false, error });
17+
}
18+
break;
19+
20+
default:
21+
res.status(400).json({ success: false });
22+
break;
23+
}
24+
}

0 commit comments

Comments
 (0)