Skip to content

Commit 4daccdf

Browse files
authored
Merge pull request #19 from dev-tahir/dark
dark mode added
2 parents 76739d3 + 4806fbe commit 4daccdf

File tree

6 files changed

+88
-23
lines changed

6 files changed

+88
-23
lines changed

app/components/ChatInterface.tsx

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use client';
22
import { useState, useEffect, useRef } from 'react';
3-
import { Send, Bot, User, Trash2, MessageCircle, LogOut, Settings } from 'lucide-react';
3+
import { Send, Bot, User, Trash2, MessageCircle, LogOut, Settings, Sun, Moon } from 'lucide-react';
44
import { signOut, useSession } from 'next-auth/react';
55

66
import { useRouter } from 'next/navigation'
7+
import DarkModeToggle from './DarkModeToggle'; // Import DarkModeToggle
78
const router = useRouter();
89

910
interface Message {
@@ -124,10 +125,10 @@ export default function ChatInterface() {
124125
};
125126

126127
return (
127-
<div className="min-h-screen bg-gradient-to-br from-purple-50 via-blue-50 to-indigo-100">
128+
<div className="min-h-screen bg-gradient-to-br from-purple-50 via-blue-50 to-indigo-100 dark:from-gray-900 dark:via-gray-800 dark:to-gray-700 text-gray-900 dark:text-gray-100">
128129
<div className="container mx-auto max-w-4xl h-screen flex flex-col">
129130
{/* Header */}
130-
<div className="bg-white/80 backdrop-blur-sm border-b border-gray-200 p-4 sticky top-0 z-10">
131+
<div className="bg-white/80 backdrop-blur-sm border-b border-gray-200 p-4 sticky top-0 z-10 dark:bg-gray-800/80 dark:border-gray-700">
131132
<div className="flex items-center justify-between">
132133
<div className="flex items-center space-x-3">
133134
<div className="w-10 h-10 bg-gradient-to-r from-purple-500 to-blue-500 rounded-full flex items-center justify-center">
@@ -137,7 +138,7 @@ export default function ChatInterface() {
137138
<h1 className="text-2xl font-bold bg-gradient-to-r from-purple-600 to-blue-600 bg-clip-text text-transparent">
138139
Gemini AI Assistant 2
139140
</h1>
140-
<p className="text-sm text-gray-500">
141+
<p className="text-sm text-gray-500 dark:text-gray-400">
141142
Welcome, {session?.user?.name}!
142143
</p>
143144
</div>
@@ -148,15 +149,15 @@ export default function ChatInterface() {
148149
<>
149150
<button
150151
onClick={clearChat}
151-
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors duration-200"
152+
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors duration-200 dark:text-gray-300 dark:hover:text-red-400 dark:hover:bg-gray-700"
152153
title="Clear chat history"
153154
>
154155
<Trash2 className="w-4 h-4" />
155156
<span className="hidden sm:inline">Clear</span>
156157
</button>
157158
<button
158159
onClick={() => router.push('/conversations')}
159-
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-colors duration-200"
160+
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-colors duration-200 dark:text-gray-300 dark:hover:text-blue-400 dark:hover:bg-gray-700"
160161
title="Recent Conversations"
161162
>
162163
<MessageCircle className="w-4 h-4" />
@@ -166,12 +167,13 @@ export default function ChatInterface() {
166167
)}
167168
<button
168169
onClick={() => router.push('/settings')}
169-
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-purple-600 hover:bg-purple-50 rounded-lg transition-colors duration-200"
170+
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-purple-600 hover:bg-purple-50 rounded-lg transition-colors duration-200 dark:text-gray-300 dark:hover:text-purple-400 dark:hover:bg-gray-700"
170171
title="Settings"
171172
>
172173
<Settings className="w-4 h-4" />
173174
<span className="hidden sm:inline">Settings</span>
174175
</button>
176+
<DarkModeToggle /> {/* Add DarkModeToggle component here */}
175177
<div className="flex items-center space-x-2">
176178
{session?.user?.image && (
177179
<img
@@ -182,7 +184,7 @@ export default function ChatInterface() {
182184
)}
183185
<button
184186
onClick={handleSignOut}
185-
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors duration-200"
187+
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors duration-200 dark:text-gray-300 dark:hover:text-red-400 dark:hover:bg-gray-700"
186188
title="Sign out"
187189
>
188190
<LogOut className="w-4 h-4" />
@@ -200,11 +202,11 @@ export default function ChatInterface() {
200202
<div className="w-20 h-20 bg-gradient-to-r from-purple-400 to-blue-400 rounded-full flex items-center justify-center mb-4">
201203
<MessageCircle className="w-10 h-10 text-white" />
202204
</div>
203-
<h2 className="text-2xl font-semibold text-gray-700 mb-2">
205+
<h2 className="text-2xl font-semibold text-gray-700 dark:text-gray-200 mb-2">
204206
Welcome back, {session?.user?.name?.split(' ')[0]}!
205207
</h2>
206-
<p className="text-gray-500 max-w-md">
207-
Start a conversation with me! I can help with questions, creative writing,
208+
<p className="text-gray-500 dark:text-gray-400 max-w-md">
209+
Start a conversation with me! I can help with questions, creative writing,
208210
problem-solving, and much more. Your chat history is saved securely.
209211
</p>
210212
</div>
@@ -241,20 +243,20 @@ export default function ChatInterface() {
241243
<Bot className="w-4 h-4 text-white" />
242244
)}
243245
</div>
244-
246+
245247
<div
246248
className={`px-4 py-3 rounded-2xl shadow-sm ${
247249
message.role === 'user'
248250
? 'bg-gradient-to-r from-blue-500 to-indigo-500 text-white'
249-
: 'bg-white border border-gray-200 text-gray-800'
251+
: 'bg-white border border-gray-200 text-gray-800 dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100'
250252
}`}
251253
>
252254
<div className="whitespace-pre-wrap text-sm leading-relaxed">
253255
{message.content}
254256
</div>
255257
<div
256258
className={`text-xs mt-2 ${
257-
message.role === 'user' ? 'text-blue-100' : 'text-gray-400'
259+
message.role === 'user' ? 'text-blue-100' : 'text-gray-400 dark:text-gray-300'
258260
}`}
259261
>
260262
{formatTime(message.timestamp)}
@@ -270,14 +272,14 @@ export default function ChatInterface() {
270272
<div className="w-8 h-8 rounded-full bg-gradient-to-r from-purple-500 to-pink-500 flex items-center justify-center flex-shrink-0">
271273
<Bot className="w-4 h-4 text-white" />
272274
</div>
273-
<div className="px-4 py-3 rounded-2xl bg-white border border-gray-200">
275+
<div className="px-4 py-3 rounded-2xl bg-white border border-gray-200 dark:bg-gray-700 dark:border-gray-600">
274276
<div className="flex items-center space-x-2">
275277
<div className="flex space-x-1">
276278
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
277279
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{animationDelay: '0.1s'}}></div>
278280
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{animationDelay: '0.2s'}}></div>
279281
</div>
280-
<span className="text-sm text-gray-500">AI is thinking...</span>
282+
<span className="text-sm text-gray-500 dark:text-gray-300">AI is thinking...</span>
281283
</div>
282284
</div>
283285
</div>
@@ -288,7 +290,7 @@ export default function ChatInterface() {
288290
</div>
289291

290292
{/* Input Form */}
291-
<div className="bg-white/80 backdrop-blur-sm border-t border-gray-200 p-4">
293+
<div className="bg-white/80 backdrop-blur-sm border-t border-gray-200 p-4 dark:bg-gray-800/80 dark:border-gray-700">
292294
<form onSubmit={sendMessage} className="flex items-center space-x-4">
293295
<div className="flex-1 relative">
294296
<input
@@ -297,12 +299,12 @@ export default function ChatInterface() {
297299
value={input}
298300
onChange={(e) => setInput(e.target.value)}
299301
placeholder="Type your message..."
300-
className="w-full px-4 py-3 pr-12 rounded-full border text-black border-gray-300 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent bg-white shadow-sm"
302+
className="w-full px-4 py-3 pr-12 rounded-full border text-black border-gray-300 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent bg-white shadow-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100 dark:placeholder-gray-400"
301303
disabled={loading}
302304
autoFocus
303305
/>
304306
<div className="absolute right-3 top-1/2 transform -translate-y-1/2">
305-
<div className="text-xs text-gray-400">
307+
<div className="text-xs text-gray-400 dark:text-gray-300">
306308
{input.length}/1000
307309
</div>
308310
</div>
@@ -318,7 +320,7 @@ export default function ChatInterface() {
318320
</form>
319321

320322
<div className="text-center mt-2">
321-
<p className="text-xs text-gray-500">
323+
<p className="text-xs text-gray-500 dark:text-gray-400">
322324
Your chat history is saved securely. Press Enter to send.
323325
</p>
324326
</div>

app/components/DarkModeToggle.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use client';
2+
3+
import { useTheme } from 'next-themes';
4+
import { useState, useEffect } from 'react';
5+
import { Sun, Moon } from 'lucide-react';
6+
7+
export default function DarkModeToggle() {
8+
const [mounted, setMounted] = useState(false);
9+
const { theme, setTheme } = useTheme();
10+
11+
// useEffect only runs on the client, so now we can safely show the UI
12+
useEffect(() => {
13+
setMounted(true);
14+
}, []);
15+
16+
if (!mounted) {
17+
return null;
18+
}
19+
20+
return (
21+
<button
22+
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
23+
className="flex items-center space-x-2 px-3 py-2 text-gray-600 hover:text-purple-600 hover:bg-purple-50 rounded-lg transition-colors duration-200 dark:text-gray-300 dark:hover:text-purple-300 dark:hover:bg-gray-700"
24+
title="Toggle dark mode"
25+
>
26+
{theme === 'dark' ? (
27+
<Sun className="w-4 h-4" />
28+
) : (
29+
<Moon className="w-4 h-4" />
30+
)}
31+
<span className="hidden sm:inline">
32+
{theme === 'dark' ? 'Light Mode' : 'Dark Mode'}
33+
</span>
34+
</button>
35+
);
36+
}

app/layout.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Metadata } from 'next'
22
import { Inter } from 'next/font/google'
33
import './globals.css'
44
import { AuthProvider } from './providers'
5+
import { ThemeProvider } from 'next-themes'
56

67
const inter = Inter({ subsets: ['latin'] })
78

@@ -18,9 +19,11 @@ export default function RootLayout({
1819
return (
1920
<html lang="en">
2021
<body className={inter.className}>
21-
<AuthProvider>
22-
{children}
23-
</AuthProvider>
22+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
23+
<AuthProvider>
24+
{children}
25+
</AuthProvider>
26+
</ThemeProvider>
2427
</body>
2528
</html>
2629
)

package-lock.json

Lines changed: 10 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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"mysql2": "^3.14.1",
1717
"next": "15.3.4",
1818
"next-auth": "^4.24.11",
19+
"next-themes": "^0.4.6",
1920
"react": "^19.0.0",
2021
"react-dom": "^19.0.0"
2122
},

tailwind.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/** @type {import('tailwindcss').Config} */
2+
module.exports = {
3+
darkMode: 'class', // Enable dark mode based on the 'class' strategy
4+
content: [
5+
'./app/**/*.{js,ts,jsx,tsx,mdx}',
6+
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
7+
'./components/**/*.{js,ts,jsx,tsx,mdx}',
8+
],
9+
theme: {
10+
extend: {},
11+
},
12+
plugins: [],
13+
}

0 commit comments

Comments
 (0)