Karan6124 commited on
Commit
f061065
·
1 Parent(s): ee0d064

feat: resolve blank screen, add live github stars badge, and conditional dashboard navbar navigation

Browse files
frontend/src/App.tsx CHANGED
@@ -44,6 +44,7 @@ export default function App() {
44
  // Auth State
45
  const [token, setToken] = useState<string | null>(localStorage.getItem('quantiq_jwt'));
46
  const [user, setUser] = useState<any>(null);
 
47
 
48
  // Dashboard Core State
49
  const [watchlist, setWatchlist] = useState<string[]>(['AAPL', 'TSLA', 'TCS.NS', 'RELIANCE.NS']);
@@ -238,6 +239,7 @@ export default function App() {
238
  const handleAuthSuccess = (accessToken: string) => {
239
  localStorage.setItem('quantiq_jwt', accessToken);
240
  setToken(accessToken);
 
241
  };
242
 
243
  const handleGoogleCredentialResponse = async (response: any) => {
@@ -264,6 +266,7 @@ export default function App() {
264
  setToken(null);
265
  setUser(null);
266
  setInsight(null);
 
267
  };
268
 
269
  // 6. Watchlist Operations
@@ -419,13 +422,15 @@ export default function App() {
419
  };
420
 
421
  // Auth Router rendering
422
- if (!token) {
423
  return (
424
  <LandingPage
425
  onGoogleLogin={handleGoogleCredentialResponse}
426
  googleClientId={GOOGLE_CLIENT_ID}
427
  onAuthSuccess={handleAuthSuccess}
428
  apiUrl={API_URL}
 
 
429
  />
430
  );
431
  }
@@ -451,6 +456,7 @@ export default function App() {
451
  onOpenRecharge={() => setShowRecharge(true)}
452
  onSelectPackage={handlePayment}
453
  onLogout={handleLogout}
 
454
  />
455
  );
456
  }
 
44
  // Auth State
45
  const [token, setToken] = useState<string | null>(localStorage.getItem('quantiq_jwt'));
46
  const [user, setUser] = useState<any>(null);
47
+ const [currentView, setCurrentView] = useState<'landing' | 'dashboard'>(localStorage.getItem('quantiq_jwt') ? 'dashboard' : 'landing');
48
 
49
  // Dashboard Core State
50
  const [watchlist, setWatchlist] = useState<string[]>(['AAPL', 'TSLA', 'TCS.NS', 'RELIANCE.NS']);
 
239
  const handleAuthSuccess = (accessToken: string) => {
240
  localStorage.setItem('quantiq_jwt', accessToken);
241
  setToken(accessToken);
242
+ setCurrentView('dashboard');
243
  };
244
 
245
  const handleGoogleCredentialResponse = async (response: any) => {
 
266
  setToken(null);
267
  setUser(null);
268
  setInsight(null);
269
+ setCurrentView('landing');
270
  };
271
 
272
  // 6. Watchlist Operations
 
422
  };
423
 
424
  // Auth Router rendering
425
+ if (!token || currentView === 'landing') {
426
  return (
427
  <LandingPage
428
  onGoogleLogin={handleGoogleCredentialResponse}
429
  googleClientId={GOOGLE_CLIENT_ID}
430
  onAuthSuccess={handleAuthSuccess}
431
  apiUrl={API_URL}
432
+ user={user}
433
+ onGoToDashboard={() => setCurrentView('dashboard')}
434
  />
435
  );
436
  }
 
456
  onOpenRecharge={() => setShowRecharge(true)}
457
  onSelectPackage={handlePayment}
458
  onLogout={handleLogout}
459
+ onLogoClick={() => setCurrentView('landing')}
460
  />
461
  );
462
  }
frontend/src/components/Navbar.tsx CHANGED
@@ -6,12 +6,16 @@ interface NavbarProps {
6
  user: any;
7
  onRechargeClick: () => void;
8
  onLogout: () => void;
 
9
  }
10
 
11
- export default function Navbar({ user, onRechargeClick, onLogout }: NavbarProps) {
12
  return (
13
  <header className="dashboard-header">
14
- <div className="header-left">
 
 
 
15
  <Logo size={32} />
16
  <span className="logo-text">QuantIQ</span>
17
  </div>
 
6
  user: any;
7
  onRechargeClick: () => void;
8
  onLogout: () => void;
9
+ onLogoClick?: () => void;
10
  }
11
 
12
+ export default function Navbar({ user, onRechargeClick, onLogout, onLogoClick }: NavbarProps) {
13
  return (
14
  <header className="dashboard-header">
15
+ <div
16
+ className={`header-left ${onLogoClick ? 'cursor-pointer hover:opacity-85 active:scale-[0.98]' : ''} transition-all`}
17
+ onClick={onLogoClick}
18
+ >
19
  <Logo size={32} />
20
  <span className="logo-text">QuantIQ</span>
21
  </div>
frontend/src/pages/Dashboard.tsx CHANGED
@@ -26,6 +26,7 @@ interface DashboardProps {
26
  onOpenRecharge: () => void;
27
  onSelectPackage: (amountInRupees: number) => Promise<void>;
28
  onLogout: () => void;
 
29
  }
30
 
31
  export default function Dashboard({
@@ -48,6 +49,7 @@ export default function Dashboard({
48
  onOpenRecharge,
49
  onSelectPackage,
50
  onLogout,
 
51
  }: DashboardProps) {
52
  return (
53
  <div className="app-container animate-fade">
@@ -56,6 +58,7 @@ export default function Dashboard({
56
  user={user}
57
  onRechargeClick={onOpenRecharge}
58
  onLogout={onLogout}
 
59
  />
60
 
61
  {/* Main Grid Content */}
 
26
  onOpenRecharge: () => void;
27
  onSelectPackage: (amountInRupees: number) => Promise<void>;
28
  onLogout: () => void;
29
+ onLogoClick?: () => void;
30
  }
31
 
32
  export default function Dashboard({
 
49
  onOpenRecharge,
50
  onSelectPackage,
51
  onLogout,
52
+ onLogoClick,
53
  }: DashboardProps) {
54
  return (
55
  <div className="app-container animate-fade">
 
58
  user={user}
59
  onRechargeClick={onOpenRecharge}
60
  onLogout={onLogout}
61
+ onLogoClick={onLogoClick}
62
  />
63
 
64
  {/* Main Grid Content */}
frontend/src/pages/LandingPage.tsx CHANGED
@@ -1,18 +1,41 @@
1
- import { useEffect, useRef, useState } from 'react';
2
- import Logo from '../components/Logo';
3
  import { Button } from '../components/ui/button';
4
  import { X, ArrowRight, Eye, EyeOff, Lock, Mail, User, Globe } from 'lucide-react';
 
 
5
 
6
  interface LandingPageProps {
7
  onGoogleLogin: (response: any) => Promise<void>;
8
  googleClientId: string;
9
  onAuthSuccess: (token: string) => void;
10
  apiUrl: string;
 
 
11
  }
12
 
13
  type AuthMode = 'signin' | 'signup';
14
 
15
- export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSuccess, apiUrl }: LandingPageProps) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  const [showAuthModal, setShowAuthModal] = useState(false);
17
  const [showReachUs, setShowReachUs] = useState(false);
18
  const [authMode, setAuthMode] = useState<AuthMode>('signin');
@@ -30,9 +53,33 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
30
  const [loading, setLoading] = useState(false);
31
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
32
  const [successMsg, setSuccessMsg] = useState<string | null>(null);
 
33
 
34
  const googleButtonRef = useRef<HTMLDivElement>(null);
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  useEffect(() => {
37
  // Append Google Identity Services SDK script
38
  const script = document.createElement('script');
@@ -260,13 +307,43 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
260
  </div>
261
  </nav>
262
 
263
- {/* CTA Trigger */}
264
- <Button
265
- onClick={() => { setAuthMode('signin'); setShowAuthModal(true); }}
266
- className="liquid-glass rounded-full px-6 py-2.5 text-sm text-foreground hover:scale-[1.03] transition-transform duration-200 cursor-pointer shadow-md"
267
- >
268
- Unlock Alpha
269
- </Button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  </div>
271
  </header>
272
 
@@ -292,13 +369,23 @@ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSucce
292
  </p>
293
 
294
  {/* Large Hero CTA */}
295
- <button
296
- onClick={() => { setAuthMode('signin'); setShowAuthModal(true); }}
297
- className="liquid-glass rounded-full px-14 py-5 text-base text-foreground mt-12 hover:scale-[1.03] cursor-pointer transition-transform duration-200 animate-fade-rise-delay-2 shadow-lg"
298
- >
299
- Unlock Alpha
300
- </button>
 
 
 
 
 
 
 
 
 
301
  </div>
 
302
  </section>
303
 
304
  {/* THE QUANTIQ STACK INFO SECTION */}
 
1
+ import { useState, useEffect, useRef } from 'react';
 
2
  import { Button } from '../components/ui/button';
3
  import { X, ArrowRight, Eye, EyeOff, Lock, Mail, User, Globe } from 'lucide-react';
4
+ import Logo from '../components/Logo';
5
+
6
 
7
  interface LandingPageProps {
8
  onGoogleLogin: (response: any) => Promise<void>;
9
  googleClientId: string;
10
  onAuthSuccess: (token: string) => void;
11
  apiUrl: string;
12
+ user?: any;
13
+ onGoToDashboard?: () => void;
14
  }
15
 
16
  type AuthMode = 'signin' | 'signup';
17
 
18
+ function GithubIcon({ size = 14, className = "" }) {
19
+ return (
20
+ <svg
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ width={size}
23
+ height={size}
24
+ viewBox="0 0 24 24"
25
+ fill="none"
26
+ stroke="currentColor"
27
+ strokeWidth="2"
28
+ strokeLinecap="round"
29
+ strokeLinejoin="round"
30
+ className={className}
31
+ >
32
+ <path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
33
+ <path d="M9 18c-4.51 2-5-2-7-2" />
34
+ </svg>
35
+ );
36
+ }
37
+
38
+ export default function LandingPage({ onGoogleLogin, googleClientId, onAuthSuccess, apiUrl, user, onGoToDashboard }: LandingPageProps) {
39
  const [showAuthModal, setShowAuthModal] = useState(false);
40
  const [showReachUs, setShowReachUs] = useState(false);
41
  const [authMode, setAuthMode] = useState<AuthMode>('signin');
 
53
  const [loading, setLoading] = useState(false);
54
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
55
  const [successMsg, setSuccessMsg] = useState<string | null>(null);
56
+ const [githubStars, setGithubStars] = useState<string | null>(null);
57
 
58
  const googleButtonRef = useRef<HTMLDivElement>(null);
59
 
60
+ // Fetch actual GitHub stargazers count for the repository
61
+ useEffect(() => {
62
+ fetch('https://api.github.com/repos/Edge-Explorer/QuantIQ')
63
+ .then(res => {
64
+ if (!res.ok) throw new Error();
65
+ return res.json();
66
+ })
67
+ .then(data => {
68
+ const count = data.stargazers_count;
69
+ if (typeof count === 'number') {
70
+ if (count >= 1000) {
71
+ setGithubStars(`${(count / 1000).toFixed(1)}K`);
72
+ } else {
73
+ setGithubStars(count.toString());
74
+ }
75
+ }
76
+ })
77
+ .catch(() => {
78
+ // Fallback default
79
+ setGithubStars('Star');
80
+ });
81
+ }, []);
82
+
83
  useEffect(() => {
84
  // Append Google Identity Services SDK script
85
  const script = document.createElement('script');
 
307
  </div>
308
  </nav>
309
 
310
+ {/* CTA Trigger and Github Badge */}
311
+ <div className="flex items-center gap-4">
312
+ <a
313
+ href="https://github.com/Edge-Explorer/QuantIQ"
314
+ target="_blank"
315
+ rel="noopener noreferrer"
316
+ className="flex items-center gap-2 px-3 py-1.5 text-sm text-foreground/90 hover:text-foreground transition-colors duration-200"
317
+ >
318
+ <GithubIcon size={18} className="text-foreground" />
319
+ <span className="font-medium tracking-tight text-white/95">{githubStars !== null ? githubStars : 'Star'}</span>
320
+ </a>
321
+
322
+ {user ? (
323
+ <div className="flex items-center gap-3">
324
+ <button
325
+ onClick={onGoToDashboard}
326
+ className="bg-[#046A38] text-white hover:bg-[#03522b] transition-all duration-200 px-5 py-2 text-sm font-semibold rounded-[4px] cursor-pointer shadow-md"
327
+ >
328
+ Dashboard
329
+ </button>
330
+ {user.pictureUrl && (
331
+ <img
332
+ src={user.pictureUrl}
333
+ alt="Profile"
334
+ className="w-9 h-9 rounded-full object-cover border border-white/10"
335
+ />
336
+ )}
337
+ </div>
338
+ ) : (
339
+ <Button
340
+ onClick={() => { setAuthMode('signin'); setShowAuthModal(true); }}
341
+ className="liquid-glass rounded-full px-6 py-2.5 text-sm text-foreground hover:scale-[1.03] transition-transform duration-200 cursor-pointer shadow-md"
342
+ >
343
+ Unlock Alpha
344
+ </Button>
345
+ )}
346
+ </div>
347
  </div>
348
  </header>
349
 
 
369
  </p>
370
 
371
  {/* Large Hero CTA */}
372
+ {user ? (
373
+ <button
374
+ onClick={onGoToDashboard}
375
+ className="bg-[#046A38] text-white hover:bg-[#03522b] rounded-full px-14 py-5 text-base mt-12 hover:scale-[1.03] cursor-pointer transition-transform duration-200 animate-fade-rise-delay-2 shadow-lg font-semibold"
376
+ >
377
+ Go to Dashboard
378
+ </button>
379
+ ) : (
380
+ <button
381
+ onClick={() => { setAuthMode('signin'); setShowAuthModal(true); }}
382
+ className="liquid-glass rounded-full px-14 py-5 text-base text-foreground mt-12 hover:scale-[1.03] cursor-pointer transition-transform duration-200 animate-fade-rise-delay-2 shadow-lg"
383
+ >
384
+ Unlock Alpha
385
+ </button>
386
+ )}
387
  </div>
388
+
389
  </section>
390
 
391
  {/* THE QUANTIQ STACK INFO SECTION */}