vaibhav07112004 commited on
Commit
27cc733
Β·
verified Β·
1 Parent(s): be8ee1b

Upload 3 files

Browse files
Files changed (3) hide show
  1. app/globals.css +132 -0
  2. app/layout.tsx +27 -0
  3. app/page.tsx +253 -0
app/globals.css ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ :root {
7
+ --background: 0 0% 100%;
8
+ --foreground: 240 10% 3.9%;
9
+ --card: 0 0% 100%;
10
+ --card-foreground: 240 10% 3.9%;
11
+ --popover: 0 0% 100%;
12
+ --popover-foreground: 240 10% 3.9%;
13
+ --primary: 329 100% 61%;
14
+ --primary-foreground: 0 0% 98%;
15
+ --secondary: 240 4.8% 95.9%;
16
+ --secondary-foreground: 240 5.9% 10%;
17
+ --muted: 240 4.8% 95.9%;
18
+ --muted-foreground: 240 3.8% 46.1%;
19
+ --accent: 240 4.8% 95.9%;
20
+ --accent-foreground: 240 5.9% 10%;
21
+ --destructive: 0 84.2% 60.2%;
22
+ --destructive-foreground: 0 0% 98%;
23
+ --border: 240 5.9% 90%;
24
+ --input: 240 5.9% 90%;
25
+ --ring: 329 100% 61%;
26
+ --radius: 0.5rem;
27
+ }
28
+
29
+ .dark {
30
+ --background: 240 10% 3.9%;
31
+ --foreground: 0 0% 98%;
32
+ --card: 240 10% 3.9%;
33
+ --card-foreground: 0 0% 98%;
34
+ --popover: 240 10% 3.9%;
35
+ --popover-foreground: 0 0% 98%;
36
+ --primary: 329 100% 61%;
37
+ --primary-foreground: 0 0% 98%;
38
+ --secondary: 240 3.7% 15.9%;
39
+ --secondary-foreground: 0 0% 98%;
40
+ --muted: 240 3.7% 15.9%;
41
+ --muted-foreground: 240 5% 64.9%;
42
+ --accent: 240 3.7% 15.9%;
43
+ --accent-foreground: 0 0% 98%;
44
+ --destructive: 0 62.8% 30.6%;
45
+ --destructive-foreground: 0 0% 98%;
46
+ --border: 240 3.7% 15.9%;
47
+ --input: 240 3.7% 15.9%;
48
+ --ring: 329 100% 61%;
49
+ }
50
+ }
51
+
52
+ @layer base {
53
+ * {
54
+ @apply border-border;
55
+ }
56
+ body {
57
+ @apply bg-background text-foreground;
58
+ }
59
+ }
60
+
61
+ .text-gradient {
62
+ -webkit-background-clip: text;
63
+ -webkit-text-fill-color: transparent;
64
+ }
65
+
66
+ .scrollbar-hide {
67
+ -ms-overflow-style: none;
68
+ scrollbar-width: none;
69
+ }
70
+ .scrollbar-hide::-webkit-scrollbar {
71
+ display: none;
72
+ }
73
+
74
+ /* Custom Scrollbar Styles */
75
+ .scrollbar-thin {
76
+ scrollbar-width: thin;
77
+ }
78
+
79
+ .scrollbar-thumb-gray-600::-webkit-scrollbar-thumb {
80
+ background-color: #4b5563;
81
+ border-radius: 0.375rem;
82
+ }
83
+
84
+ .scrollbar-thumb-gray-500::-webkit-scrollbar-thumb {
85
+ background-color: #6b7280;
86
+ border-radius: 0.375rem;
87
+ }
88
+
89
+ .scrollbar-track-gray-800::-webkit-scrollbar-track {
90
+ background-color: #1f2937;
91
+ border-radius: 0.375rem;
92
+ }
93
+
94
+ .scrollbar-track-gray-700::-webkit-scrollbar-track {
95
+ background-color: #374151;
96
+ border-radius: 0.375rem;
97
+ }
98
+
99
+ .scrollbar-thin::-webkit-scrollbar {
100
+ width: 6px;
101
+ height: 6px;
102
+ }
103
+
104
+ .scrollbar-thin::-webkit-scrollbar-thumb {
105
+ background-color: #4b5563;
106
+ border-radius: 0.375rem;
107
+ }
108
+
109
+ .scrollbar-thin::-webkit-scrollbar-thumb:hover {
110
+ background-color: #6b7280;
111
+ }
112
+
113
+ .scrollbar-thin::-webkit-scrollbar-track {
114
+ background-color: #1f2937;
115
+ border-radius: 0.375rem;
116
+ }
117
+
118
+ /* Smooth scrolling */
119
+ .scrollbar-thin {
120
+ scroll-behavior: smooth;
121
+ }
122
+
123
+ /* Hide scrollbar for specific elements but keep functionality */
124
+ .scrollbar-hide-but-functional {
125
+ -ms-overflow-style: none;
126
+ scrollbar-width: none;
127
+ overflow: auto;
128
+ }
129
+
130
+ .scrollbar-hide-but-functional::-webkit-scrollbar {
131
+ display: none;
132
+ }
app/layout.tsx ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type React from "react"
2
+ import type { Metadata } from "next"
3
+ import { Inter } from "next/font/google"
4
+ import "./globals.css"
5
+ import AuthGuard from "@/components/auth-guard"
6
+
7
+ const inter = Inter({ subsets: ["latin"] })
8
+
9
+ export const metadata: Metadata = {
10
+ title: "MoodVibe - AI-Powered Emotion Detection",
11
+ description: "Discover your emotions through AI-powered image analysis and get personalized music recommendations",
12
+ generator: 'v0.dev'
13
+ }
14
+
15
+ export default function RootLayout({
16
+ children,
17
+ }: {
18
+ children: React.ReactNode
19
+ }) {
20
+ return (
21
+ <html lang="en">
22
+ <body className={inter.className}>
23
+ <AuthGuard>{children}</AuthGuard>
24
+ </body>
25
+ </html>
26
+ )
27
+ }
app/page.tsx ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import { useState, useEffect } from "react"
4
+ import StoryInterface from "@/components/story-interface"
5
+ import UserAccountDropdown from "@/components/user-account-dropdown"
6
+ import { Button } from "@/components/ui/button"
7
+ import { LogIn } from "lucide-react"
8
+ import Link from "next/link"
9
+
10
+ interface User {
11
+ id: string
12
+ name: string
13
+ email: string
14
+ createdAt: string
15
+ emailNotifications: boolean
16
+ weeklyRecap: boolean
17
+ dailyMoodCheck: boolean
18
+ reminderTime: string
19
+ profilePicture?: string
20
+ }
21
+
22
+ export default function Home() {
23
+ const [currentUser, setCurrentUser] = useState<User | null>(null)
24
+ const [showAccountDropdown, setShowAccountDropdown] = useState(false)
25
+
26
+ useEffect(() => {
27
+ // Check for user data in URL params (from OAuth callback)
28
+ const urlParams = new URLSearchParams(window.location.search)
29
+ const userDataParam = urlParams.get("userData")
30
+
31
+ if (userDataParam) {
32
+ try {
33
+ const userData = JSON.parse(decodeURIComponent(userDataParam))
34
+ localStorage.setItem("user", JSON.stringify(userData))
35
+ setCurrentUser(userData)
36
+
37
+ // Clean up URL
38
+ window.history.replaceState({}, document.title, window.location.pathname)
39
+ } catch (error) {
40
+ console.error("Error parsing user data from URL:", error)
41
+ }
42
+ } else {
43
+ // Check localStorage for existing user
44
+ try {
45
+ const savedUser = localStorage.getItem("user")
46
+ if (savedUser && savedUser !== "undefined") {
47
+ const userData = JSON.parse(savedUser)
48
+ setCurrentUser(userData)
49
+ }
50
+ } catch (error) {
51
+ console.error("Error loading user from localStorage:", error)
52
+ }
53
+ }
54
+ }, [])
55
+
56
+ const getInitials = (name: string) => {
57
+ return name
58
+ .split(" ")
59
+ .map((n) => n[0])
60
+ .join("")
61
+ .toUpperCase()
62
+ .slice(0, 2)
63
+ }
64
+
65
+ const getAvatarColor = (email: string) => {
66
+ const colors = [
67
+ "bg-red-500",
68
+ "bg-blue-500",
69
+ "bg-green-500",
70
+ "bg-purple-500",
71
+ "bg-pink-500",
72
+ "bg-indigo-500",
73
+ "bg-yellow-500",
74
+ "bg-teal-500",
75
+ ]
76
+ const hash = email.split("").reduce((a, b) => {
77
+ a = (a << 5) - a + b.charCodeAt(0)
78
+ return a & a
79
+ }, 0)
80
+ return colors[Math.abs(hash) % colors.length]
81
+ }
82
+
83
+ const renderUserAvatar = () => {
84
+ if (!currentUser) return null
85
+
86
+ if (currentUser.profilePicture) {
87
+ return (
88
+ <img
89
+ src={currentUser.profilePicture || "/placeholder.svg"}
90
+ alt={currentUser.name}
91
+ className="w-8 h-8 rounded-full object-cover"
92
+ />
93
+ )
94
+ }
95
+
96
+ return (
97
+ <div
98
+ className={`w-8 h-8 rounded-full ${getAvatarColor(currentUser.email)} flex items-center justify-center text-white text-sm font-bold`}
99
+ >
100
+ {getInitials(currentUser.name)}
101
+ </div>
102
+ )
103
+ }
104
+
105
+ const handleUserUpdate = (updatedUser: User) => {
106
+ setCurrentUser(updatedUser)
107
+ }
108
+
109
+ return (
110
+ <main className="min-h-screen bg-gradient-to-br from-purple-900 via-black to-pink-900 text-white">
111
+ {/* Animated background elements */}
112
+ <div className="fixed inset-0 overflow-hidden pointer-events-none">
113
+ <div className="absolute top-20 left-10 w-72 h-72 bg-pink-500/20 rounded-full blur-3xl animate-pulse"></div>
114
+ <div className="absolute bottom-20 right-10 w-96 h-96 bg-purple-500/20 rounded-full blur-3xl animate-pulse delay-1000"></div>
115
+ <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-blue-500/10 rounded-full blur-3xl animate-pulse delay-500"></div>
116
+ </div>
117
+
118
+ {/* Grid pattern overlay */}
119
+ <div
120
+ className="fixed inset-0 opacity-30 pointer-events-none"
121
+ style={{
122
+ backgroundImage: `url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fillRule='evenodd'%3E%3Cg fill='%23ffffff' fillOpacity='0.03'%3E%3Ccircle cx='30' cy='30' r='1'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`,
123
+ }}
124
+ ></div>
125
+
126
+ {/* Main content container */}
127
+ <div className="relative z-10 min-h-screen flex flex-col">
128
+ {/* Header with User Account or Sign In/Up buttons */}
129
+ <div className="absolute top-4 right-4 z-30">
130
+ {currentUser ? (
131
+ // User Account Button
132
+ <button
133
+ onClick={() => setShowAccountDropdown(true)}
134
+ className="flex items-center gap-3 bg-white/10 backdrop-blur-sm border border-white/20 rounded-full px-4 py-2 hover:bg-white/20 transition-all duration-200"
135
+ >
136
+ {renderUserAvatar()}
137
+ <span className="text-white text-sm font-medium hidden sm:block">{currentUser.name.split(" ")[0]}</span>
138
+ </button>
139
+ ) : (
140
+ // Sign In/Up Buttons
141
+ <div className="flex gap-3">
142
+ <Link href="/auth/login">
143
+ <Button
144
+ variant="outline"
145
+ className="bg-white/10 backdrop-blur-sm border-white/20 text-white hover:bg-white/20 transition-all duration-200"
146
+ >
147
+ <LogIn className="h-4 w-4 mr-2" />
148
+ Sign In
149
+ </Button>
150
+ </Link>
151
+ <Link href="/auth/signup">
152
+ <Button className="bg-gradient-to-r from-pink-500 to-purple-500 hover:from-pink-600 hover:to-purple-600 text-white border-0 transition-all duration-200">
153
+ Sign Up
154
+ </Button>
155
+ </Link>
156
+ </div>
157
+ )}
158
+ </div>
159
+
160
+ {/* User Account Dropdown */}
161
+ <UserAccountDropdown
162
+ isOpen={showAccountDropdown}
163
+ onClose={() => setShowAccountDropdown(false)}
164
+ currentUser={currentUser}
165
+ onUserUpdate={handleUserUpdate}
166
+ />
167
+
168
+ {/* Hero section */}
169
+ <div className="flex-1 flex flex-col items-center justify-center p-4 pb-8">
170
+ <div className="text-center mb-8 max-w-4xl mx-auto">
171
+ <div className="mb-6">
172
+ <div className="inline-flex items-center gap-3 bg-white/10 backdrop-blur-sm rounded-full px-6 py-3 mb-6">
173
+ <span className="text-2xl">🎭</span>
174
+ <span className="text-sm font-medium text-gray-300">AI-Powered Emotion Detection</span>
175
+ </div>
176
+ </div>
177
+
178
+ <h1 className="text-4xl md:text-6xl lg:text-7xl font-bold mb-6 bg-gradient-to-r from-pink-400 via-purple-400 to-blue-400 bg-clip-text text-transparent leading-tight">
179
+ Mood & Vibe
180
+ <br />
181
+ <span className="text-3xl md:text-5xl lg:text-6xl">Detection</span>
182
+ </h1>
183
+
184
+ <p className="text-lg md:text-xl text-gray-300 mb-8 max-w-3xl mx-auto leading-relaxed">
185
+ Discover your emotions through AI-powered image analysis and get
186
+ <span className="text-pink-400 font-semibold"> personalized music recommendations </span>
187
+ that perfectly match your mood
188
+ </p>
189
+ </div>
190
+
191
+ {/* App interface - Main Interactive Component */}
192
+ <div className="relative w-full max-w-lg mx-auto">
193
+ {/* Glow effect around the app */}
194
+ <div className="absolute -inset-4 bg-gradient-to-r from-pink-500/30 via-purple-500/30 to-blue-500/30 rounded-3xl blur-2xl"></div>
195
+
196
+ {/* App container with proper z-index */}
197
+ <div className="relative z-20">
198
+ <StoryInterface />
199
+ </div>
200
+ </div>
201
+
202
+ {/* Features preview - Moved below the app */}
203
+ <div className="grid md:grid-cols-3 gap-4 mt-8 max-w-3xl mx-auto">
204
+ <div className="bg-white/5 backdrop-blur-sm rounded-xl p-4 border border-white/10">
205
+ <div className="text-2xl mb-2">🧠</div>
206
+ <h3 className="text-sm font-semibold mb-1">AI Detection</h3>
207
+ <p className="text-xs text-gray-400">Advanced emotion analysis</p>
208
+ </div>
209
+ <div className="bg-white/5 backdrop-blur-sm rounded-xl p-4 border border-white/10">
210
+ <div className="text-2xl mb-2">🎡</div>
211
+ <h3 className="text-sm font-semibold mb-1">Smart Music</h3>
212
+ <p className="text-xs text-gray-400">Personalized recommendations</p>
213
+ </div>
214
+ <div className="bg-white/5 backdrop-blur-sm rounded-xl p-4 border border-white/10">
215
+ <div className="text-2xl mb-2">⭐</div>
216
+ <h3 className="text-sm font-semibold mb-1">Story Highlights</h3>
217
+ <p className="text-xs text-gray-400">Save favorite moments</p>
218
+ </div>
219
+ </div>
220
+
221
+ {/* Bottom info */}
222
+ <div className="text-center mt-8 max-w-2xl mx-auto">
223
+ <p className="text-gray-400 mb-4 text-sm">Join millions discovering their emotions through AI</p>
224
+ <div className="flex flex-wrap items-center justify-center gap-4 text-xs">
225
+ <div className="flex items-center gap-2">
226
+ <span className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></span>
227
+ <span className="text-gray-400">Real-time Processing</span>
228
+ </div>
229
+ <div className="flex items-center gap-2">
230
+ <span className="w-2 h-2 bg-blue-500 rounded-full animate-pulse"></span>
231
+ <span className="text-gray-400">Privacy Protected</span>
232
+ </div>
233
+ <div className="flex items-center gap-2">
234
+ <span className="w-2 h-2 bg-purple-500 rounded-full animate-pulse"></span>
235
+ <span className="text-gray-400">Free to Use</span>
236
+ </div>
237
+ </div>
238
+ </div>
239
+ </div>
240
+ </div>
241
+
242
+ {/* Floating elements */}
243
+ <div className="fixed top-20 right-20 text-3xl animate-bounce delay-1000 opacity-20 pointer-events-none">😊</div>
244
+ <div className="fixed bottom-32 left-20 text-2xl animate-bounce delay-2000 opacity-20 pointer-events-none">
245
+ 🎡
246
+ </div>
247
+ <div className="fixed top-1/3 right-10 text-xl animate-bounce delay-3000 opacity-20 pointer-events-none">✨</div>
248
+ <div className="fixed bottom-20 right-1/3 text-2xl animate-bounce delay-4000 opacity-20 pointer-events-none">
249
+ 🎭
250
+ </div>
251
+ </main>
252
+ )
253
+ }