Skip to content

Commit 1a27103

Browse files
committed
working front end
1 parent 4994be3 commit 1a27103

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+29001
-1906
lines changed

package-lock.json

Lines changed: 26103 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
"@testing-library/jest-dom": "^5.16.5",
77
"@testing-library/react": "^13.4.0",
88
"@testing-library/user-event": "^14.4.3",
9-
"framer-motion": "4.1.17",
9+
"framer-motion": "^4.1.17",
1010
"postcss-cli": "^10.1.0",
1111
"react": "^18.1.0",
1212
"react-countup": "^6.1.1",
1313
"react-dom": "^18.1.0",
14-
"react-icons": "^4.3.1",
14+
"react-icons": "^4.12.0",
1515
"react-router-dom": "^6.0.2",
16-
"react-scripts": "4.0.3",
17-
"react-scroll": "^1.8.4",
16+
"react-scripts": "^4.0.3",
17+
"react-scroll": "^1.9.3",
1818
"styled-components": "^5.3.3",
1919
"web-vitals": "^1.0.1"
2020
},

public/images/experience/acm.png

1.33 MB
Loading

public/images/experience/gdg.png

2.31 KB
Loading
101 KB
Loading

public/images/experience/terafac.png

12 KB
Loading
54.9 KB
Loading

src/App.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,31 @@ import AppHeader from './components/shared/AppHeader';
77
import './css/App.css';
88
import UseScrollToTop from './hooks/useScrollToTop';
99

10+
// Lazy load pages
1011
const About = lazy(() => import('./pages/AboutMe'));
1112
const Contact = lazy(() => import('./pages/Contact.jsx'));
1213
const Home = lazy(() => import('./pages/Home'));
1314
const Projects = lazy(() => import('./pages/Projects'));
1415
const ProjectSingle = lazy(() => import('./pages/ProjectSingle.jsx'));
15-
16+
const Experience = lazy(() => import('./pages/Experience'));
17+
const Chatbot = lazy(() => import('./pages/Chatbot')); // 👈 Added chatbot page
1618

1719
function App() {
1820
return (
1921
<AnimatePresence>
20-
<div className=" bg-secondary-light dark:bg-primary-dark transition duration-300">
22+
<div className="bg-secondary-light dark:bg-primary-dark transition duration-300">
2123
<Router>
2224
<ScrollToTop />
2325
<AppHeader />
2426
<Suspense fallback={""}>
2527
<Routes>
2628
<Route path="/" element={<Home />} />
2729
<Route path="projects" element={<Projects />} />
28-
<Route
29-
path="projects/single-project"
30-
element={<ProjectSingle />}
31-
/>
32-
30+
<Route path="project/:id" element={<ProjectSingle />} />
3331
<Route path="about" element={<About />} />
3432
<Route path="contact" element={<Contact />} />
33+
<Route path="experience" element={<Experience />} />
34+
<Route path="chatbot" element={<Chatbot />} /> {/* ✅ Chatbot Route */}
3535
</Routes>
3636
</Suspense>
3737
<AppFooter />

src/components/about/AboutClientSingle.jsx

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/components/about/AboutCounter.jsx

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,55 @@ import { useCountUp } from 'react-countup';
22
import CounterItem from './CounterItem';
33

44
const AboutCounter = () => {
5-
useCountUp({ ref: 'experienceCounter', end: 12, duration: 2 });
6-
useCountUp({ ref: 'githubStarsCounter', end: 20, duration: 2 });
7-
useCountUp({ ref: 'feedbackCounter', end: 92, duration: 2 });
8-
useCountUp({ ref: 'projectsCounter', end: 77, duration: 2 });
5+
useCountUp({ ref: 'projectsCounter', end: 5, duration: 2 });
6+
useCountUp({ ref: 'eventsCounter', end: 10, duration: 2 });
7+
useCountUp({ ref: 'internshipsCounter', end: 3, duration: 2 });
8+
useCountUp({ ref: 'publicationsCounter', end: 2, duration: 2 });
9+
useCountUp({ ref: 'leadershipCounter', end: 3, duration: 2 });
10+
useCountUp({ ref: 'bookCounter', end: 1, duration: 2 });
911

1012
return (
1113
<div className="mt-10 sm:mt-20 bg-primary-light dark:bg-ternary-dark shadow-sm">
12-
<div className="font-general-medium container mx-auto py-20 block sm:flex sm:justify-between items-center">
13-
<CounterItem
14-
title="Years of experience"
15-
counter={<span id="experienceCounter" />}
16-
measurement=""
17-
/>
14+
<div className="font-general-medium container mx-auto py-20 flex flex-col items-center justify-center">
15+
16+
{/* Top Row */}
17+
<div className="grid grid-cols-1 sm:grid-cols-3 gap-8 mb-12 w-full text-center">
18+
<CounterItem
19+
title="Research Projects"
20+
counter={<span id="projectsCounter" />}
21+
measurement="+"
22+
/>
23+
<CounterItem
24+
title="Hackathons & Workshops"
25+
counter={<span id="eventsCounter" />}
26+
measurement="+"
27+
/>
28+
<CounterItem
29+
title="Internships"
30+
counter={<span id="internshipsCounter" />}
31+
measurement=""
32+
/>
33+
</div>
1834

19-
<CounterItem
20-
title="Stars on GitHub"
21-
counter={<span id="githubStarsCounter" />}
22-
measurement="k+"
23-
/>
35+
{/* Bottom Row */}
36+
<div className="grid grid-cols-1 sm:grid-cols-3 gap-8 w-full text-center">
37+
<CounterItem
38+
title="Publications"
39+
counter={<span id="publicationsCounter" />}
40+
measurement=""
41+
/>
42+
<CounterItem
43+
title="Leadership Roles"
44+
counter={<span id="leadershipCounter" />}
45+
measurement=""
46+
/>
47+
<CounterItem
48+
title="Books Authored"
49+
counter={<span id="bookCounter" />}
50+
measurement=""
51+
/>
52+
</div>
2453

25-
<CounterItem
26-
title="Positive feedback"
27-
counter={<span id="feedbackCounter" />}
28-
measurement="%"
29-
/>
30-
31-
<CounterItem
32-
title="Projects completed"
33-
counter={<span id="projectsCounter" />}
34-
measurement="%"
35-
/>
3654
</div>
3755
</div>
3856
);
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { useContext } from 'react';
22
import AboutMeContext from '../../context/AboutMeContext';
3-
import AboutClientSingle from './AboutClientSingle';
3+
import AboutTechSingle from './AboutTechSingle';
44

5-
const AboutClients = () => {
6-
const { clientsData, clientsHeading } = useContext(AboutMeContext);
5+
const AboutTech = () => {
6+
const { techStack, Heading } = useContext(AboutMeContext);
77

88
return (
99
<div className="mt-10 sm:mt-20">
1010
<p className="font-general-medium text-2xl sm:text-3xl text-center text-primary-dark dark:text-primary-light">
11-
{clientsHeading}
11+
{Heading}
1212
</p>
1313
<div className="grid grid-cols-2 sm:grid-cols-4 mt-10 sm:mt-14 gap-2">
14-
{clientsData.map((client) => (
15-
<AboutClientSingle
14+
{techStack.map((client) => (
15+
<AboutTechSingle
1616
title={client.title}
1717
image={client.img}
1818
key={client.id}
@@ -23,4 +23,4 @@ const AboutClients = () => {
2323
);
2424
};
2525

26-
export default AboutClients;
26+
export default AboutTech;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const AboutTechSingle = ({ title, image }) => {
2+
return (
3+
<div
4+
title={title}
5+
className="transform hover:scale-105 transition-transform duration-200 ease-in-out flex items-center justify-center h-12 w-20 bg-secondary-light border border-ternary-light dark:border-ternary-dark shadow-sm rounded-md mb-4 cursor-pointer p-2"
6+
>
7+
<img
8+
src={image}
9+
alt={title}
10+
className="h-6 w-6 sm:h-8 sm:w-8 object-contain"
11+
/>
12+
</div>
13+
);
14+
};
15+
16+
export default AboutTechSingle;

src/components/chat/ChatFullPage.jsx

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import React, { useState, useEffect, useRef } from 'react';
2+
import { FiSend } from 'react-icons/fi';
3+
4+
const ChatFullPage = () => {
5+
const [input, setInput] = useState('');
6+
const [conversation, setConversation] = useState([]);
7+
const [loading, setLoading] = useState(false);
8+
const chatRef = useRef(null);
9+
10+
useEffect(() => {
11+
const saved = sessionStorage.getItem('chatHistory');
12+
if (saved) {
13+
setConversation(JSON.parse(saved));
14+
}
15+
}, []);
16+
17+
useEffect(() => {
18+
const handleBeforeUnload = () => {
19+
sessionStorage.removeItem('chatHistory');
20+
};
21+
window.addEventListener('beforeunload', handleBeforeUnload);
22+
return () => window.removeEventListener('beforeunload', handleBeforeUnload);
23+
}, []);
24+
25+
useEffect(() => {
26+
chatRef.current?.scrollTo(0, chatRef.current.scrollHeight);
27+
}, [conversation, loading]);
28+
29+
const sendMessage = async (e) => {
30+
e.preventDefault();
31+
if (!input.trim()) return;
32+
33+
const userMessage = { sender: 'user', text: input };
34+
const updated = [...conversation, userMessage];
35+
setConversation(updated);
36+
setInput('');
37+
setLoading(true);
38+
39+
try {
40+
const res = await fetch('https://rahat15-personal-chatbot.hf.space/chat', {
41+
method: 'POST',
42+
headers: { 'Content-Type': 'application/json' },
43+
body: JSON.stringify({ question: input }),
44+
});
45+
46+
const data = await res.json();
47+
const botMessage = { sender: 'bot', text: data.answer };
48+
const final = [...updated, botMessage];
49+
setConversation(final);
50+
sessionStorage.setItem('chatHistory', JSON.stringify(final));
51+
} catch (err) {
52+
console.error(err);
53+
setConversation(prev => [...prev, { sender: 'bot', text: '⚠️ Error fetching response.' }]);
54+
} finally {
55+
setLoading(false);
56+
}
57+
};
58+
59+
return (
60+
<div className="container mx-auto min-h-screen flex flex-col bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-100">
61+
62+
63+
{/* Header - Centered, no border */}
64+
<header className="w-full px-6 py-4 mt-10 text-center">
65+
<h1 className="text-xl font-medium text-gray-800 dark:text-gray-200">
66+
Chat with RahBot
67+
</h1>
68+
</header>
69+
70+
71+
72+
73+
74+
<div className="mt-4 pt-2 pb-2 border-t-2 border-primary-light dark:border-secondary-dark"></div>
75+
76+
77+
{/* Chat Area */}
78+
<main
79+
ref={chatRef}
80+
className="flex-1 overflow-y-auto px-4 sm:px-8 py-6 w-full max-w-4xl mx-auto"
81+
>
82+
{conversation.map((msg, idx) => (
83+
<div
84+
key={idx}
85+
className={`mb-4 flex ${msg.sender === 'bot' ? 'justify-end' : 'justify-start'}`}
86+
>
87+
<div
88+
className="inline-block rounded-lg px-4 py-2 shadow-sm whitespace-pre-wrap break-words text-sm text-left"
89+
style={{
90+
backgroundColor: '#c7d2fe', // Your original indigo color
91+
color: '#1e1e1e',
92+
maxWidth: '80%',
93+
marginLeft: msg.sender === 'bot' ? 'auto' : '0' // Force right-side only for bot
94+
}}
95+
>
96+
<div className="text-xs font-medium mb-1 text-gray-700">
97+
{msg.sender === 'bot' ? 'RahBot' : 'You'}
98+
</div>
99+
{msg.text}
100+
</div>
101+
</div>
102+
))}
103+
104+
{loading && (
105+
<div className="text-sm italic text-center text-gray-500 dark:text-gray-400">
106+
RahBot is thinking...
107+
</div>
108+
)}
109+
</main>
110+
111+
112+
<form
113+
onSubmit={sendMessage}
114+
className="w-full px-4 sm:px-8 py-4 bg-white dark:bg-gray-900"
115+
>
116+
<div className="w-full max-w-4xl mx-auto">
117+
<div className="relative flex items-center">
118+
<input
119+
type="text"
120+
className="w-full px-4 py-3 pr-11 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-sm text-gray-800 dark:text-white focus:outline-none focus:ring-2 focus:ring-indigo-500"
121+
placeholder="Ask anything about Rahat..."
122+
value={input}
123+
onChange={(e) => setInput(e.target.value)}
124+
/>
125+
126+
{/* Embedded send button on right inside input */}
127+
<button
128+
type="submit"
129+
className="absolute right-2 top-1/2 -translate-y-1/2 text-gray-700 dark:text-gray-200 hover:text-indigo-600 dark:hover:text-indigo-300"
130+
>
131+
<FiSend className="w-5 h-5" />
132+
</button>
133+
</div>
134+
</div>
135+
</form>
136+
137+
138+
139+
</div>
140+
);
141+
};
142+
143+
export default ChatFullPage;

0 commit comments

Comments
 (0)