Skip to content

Commit 72afa5f

Browse files
authored
Merge pull request #6 from druvkotwani/searchingFeat
searching complete/
2 parents f07599b + 8b0ec7c commit 72afa5f

File tree

3 files changed

+59
-29
lines changed

3 files changed

+59
-29
lines changed

client/src/App.jsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,27 @@ import Navbar from "./components/Navbar";
22
import Stat from "./components/Stat";
33
import StatsGenerator from "./components/StatsGenerator";
44
import { useEffect, useState } from "react";
5-
import { collection, getDocs } from "firebase/firestore";
5+
import { collection, getDocs, onSnapshot } from "firebase/firestore";
66
import { firestore } from "./firebase";
77

88
import "./App.css";
99

1010
export default function App() {
1111
const [showStats, setShowStats] = useState(false);
12-
1312
const [data, setData] = useState([]);
13+
const [filteredData, setFilteredData] = useState([]);
1414

1515
useEffect(() => {
1616
const getContacts = async () => {
1717
try {
1818
const dataCollection = collection(firestore, "users_stats");
19-
const dataSnapshot = await getDocs(dataCollection);
20-
const dataList = dataSnapshot.docs.map((doc) => {
21-
return doc.data()
22-
})
23-
setData(dataList);
19+
const unsubscribe = onSnapshot(dataCollection, (snapshot) => {
20+
const dataList = snapshot.docs.map((doc) => doc.data());
21+
setData(dataList);
22+
setFilteredData(dataList);
23+
});
24+
// Return a cleanup function to unsubscribe from the snapshot listener when the component unmounts
25+
return () => unsubscribe();
2426
} catch (error) {
2527
console.log(error);
2628
}
@@ -29,6 +31,13 @@ export default function App() {
2931
getContacts();
3032
}, []);
3133

34+
const handleSearch = (query) => {
35+
const filtered = data.filter((item) =>
36+
item.username.toLowerCase().includes(query.toLowerCase())
37+
);
38+
setFilteredData(filtered);
39+
};
40+
3241
useEffect(() => {
3342
// Set an interval to toggle the animation class every 5 seconds
3443
const interval = setInterval(() => {
@@ -52,12 +61,12 @@ export default function App() {
5261
<path fillRule="evenodd" clipRule="evenodd" d="M49.9118 2.02335C52.3173 -0.55232 56.3517 -0.686894 58.9228 1.72277C61.494 4.13244 61.6284 8.17385 59.2229 10.7495L16.4276 56.5729C11.7768 61.552 12.2861 69.5738 17.6453 74.8292L37.4088 94.2091C39.9249 96.6764 39.968 100.72 37.505 103.24C35.042 105.761 31.0056 105.804 28.4895 103.337L8.72593 83.9567C-1.42529 74.0021 -2.43665 58.0741 7.1169 47.8463L49.9118 2.02335Z" fill="white"></path>
5362
</svg>
5463
</button>
55-
<Navbar />
64+
<Navbar onSearch={handleSearch} />
5665
<div className="flex flex-col mx-auto max-w-screen-xl px-2 sm:px-6 lg:px-8">
5766
<div className="grid grid-cols-1 gap-4 py-4 ">
5867
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
5968
{
60-
data.map(data => (
69+
filteredData.map(data => (
6170
<Stat key={data.username} data={data} />
6271
))
6372
}

client/src/components/Navbar.jsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
import React from 'react'
2+
import { useState } from 'react'
3+
4+
const Navbar = ({ onSearch }) => {
5+
const [searchQuery, setSearchQuery] = useState('');
6+
7+
const handleSearch = (e) => {
8+
const query = e.target.value;
9+
setSearchQuery(query);
10+
onSearch(query);
11+
};
12+
const handleKeyPress = (e) => {
13+
if (e.key === 'Enter') {
14+
e.preventDefault(); // Prevent form submission
15+
onSearch(searchQuery); // Trigger search when Enter is pressed
16+
}
17+
};
218

3-
const Navbar = () => {
419
return (
520
<div className='sticky top-0 z-50 bg-[#292829] shadow-lg border-b border-[#E0E0E0] overflow-hidden'>
621
<div className='mx-auto max-w-screen-xl px-4 sm:px-6 lg:px-8 '>
@@ -19,12 +34,13 @@ const Navbar = () => {
1934

2035
{/* Search Bar */}
2136
<div className="hidden sm:block">
22-
<form className="flex items-center w-80">
37+
<div className="flex items-center w-80">
2338
<label htmlFor="simple-search" className="sr-only">Search</label>
2439
<div className="relative w-full">
25-
<input type="text" id="simple-search" className="border border-gray text-sm rounded-lg block shadow w-full pl-3 p-2.5 bg-[#0e0e0e] border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 focus:border-blue-500" placeholder="Search by Name or Username..." required="" />
40+
<input type="text" id="simple-search" className="border border-gray text-sm rounded-lg block shadow w-full pl-3 p-2.5 bg-[#0e0e0e] border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 focus:border-blue-500" value={searchQuery}
41+
onChange={handleSearch} onKeyDown={handleKeyPress} placeholder="Search by Name or Username..." required="" />
2642
</div>
27-
</form>
43+
</div>
2844
</div>
2945

3046
{/* icons */}
@@ -47,12 +63,12 @@ const Navbar = () => {
4763

4864
{/* Smaller devices */}
4965
<div className="sm:hidden flex gap-2">
50-
<form className="items-center flex">
66+
<div className="items-center flex">
5167
<label htmlFor="simple-search" className="sr-only">Search</label>
5268
<div className="relative w-full">
53-
<input type="text" id="simple-search" className="border border-gray text-sm rounded-lg block w-full pl-3 p-2.5 bg-[#0e0e0e] border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 shadow focus:border-blue-500" placeholder="Search user profile..." required="" />
69+
<input type="text" id="simple-search" value={searchQuery} className="border border-gray text-sm rounded-lg block w-full pl-3 p-2.5 bg-[#0e0e0e] border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 shadow focus:border-blue-500" onChange={handleSearch} onKeyDown={handleKeyPress} placeholder="Search user profile..." required="" />
5470
</div>
55-
</form>
71+
</div>
5672
<div className='flex'>
5773
<a className="rounded-md bg-[#0e0e0e] text-white hover:bg-[#292829] border border-gray-600 px-3 ml-1 py-2.5 text-sm font-medium shadow" href="https://github.com/druvkotwani/Leetcode-Profiles/"></a>
5874
<a className="rounded-md bg-[#0e0e0e] text-white hover:bg-[#292829] border border-gray-600 px-3 ml-1 py-2 text-sm font-medium shadow" href="https://linkedin.com/in/dhruv-kotwani">

client/src/components/StatsGenerator.jsx

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,22 @@ export default function StatsGenerator({ setShowStats }) {
101101
});
102102
}
103103

104+
function wrongUsername() {
105+
toast.warn('I think!! your username is not correct', {
106+
position: "top-center",
107+
autoClose: 5000,
108+
hideProgressBar: false,
109+
closeOnClick: true,
110+
pauseOnHover: true,
111+
draggable: true,
112+
progress: undefined,
113+
theme: "dark",
114+
});
115+
}
116+
104117

105-
const addData = async () => {
118+
const addData = async (e) => {
119+
e.preventDefault();
106120
try {
107121
const transformedUserData = transformUserData(userData);
108122
const dataCollection = collection(firestore, "users_stats")
@@ -120,7 +134,6 @@ export default function StatsGenerator({ setShowStats }) {
120134
} else {
121135
console.log("User data already exists in Firestore.");
122136
dataThere()
123-
124137
}
125138
}
126139
catch (err) {
@@ -134,14 +147,7 @@ export default function StatsGenerator({ setShowStats }) {
134147

135148
function handleSubmit(e) {
136149
e.preventDefault();
137-
if (userName.trim() !== '') {
138-
// Proceed with the action since the input is not empty
139-
// Your logic here
140-
} else {
141-
// Input is empty, show an error message or prevent the action
142-
// For now, let's just console log a message
143-
console.log('Please enter a username.');
144-
}
150+
145151
setLoading(true); // Start loading when fetching data
146152
// Make an HTTP request to your backend
147153
axios.get(`https://bakcen.onrender.com/${userName}`)
@@ -151,12 +157,11 @@ export default function StatsGenerator({ setShowStats }) {
151157
setLoading(false); // Stop loading after data is fetched
152158
})
153159
.catch(error => {
160+
wrongUsername()
154161
console.error('Error fetching data:', error);
155162
});
156163
}
157164

158-
159-
160165
return (
161166
<div className="flex justify-center flex-col items-center">
162167

@@ -206,7 +211,7 @@ export default function StatsGenerator({ setShowStats }) {
206211

207212

208213
{/* Buttons + Input */}
209-
<form className="flex items-center w-80">
214+
<form className="flex items-center w-80" onSubmit={addData}>
210215
<label htmlFor="simple-search" className="sr-only">Search</label>
211216
<div className="relative w-full">
212217
<input onChange={handleInputChange} type="text" id="simple-search" className="border border-gray text-sm rounded-lg block shadow w-full pl-3 p-2.5 bg-[#0e0e0e] border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 focus:border-blue-500" placeholder="Enter the username to Generate Stats..." required="" />

0 commit comments

Comments
 (0)