diff --git a/src/app/api/auth/oidc/callback/route.ts b/src/app/api/auth/oidc/callback/route.ts index 0655346..cb35623 100644 --- a/src/app/api/auth/oidc/callback/route.ts +++ b/src/app/api/auth/oidc/callback/route.ts @@ -75,6 +75,7 @@ export async function GET(request: Request) { if (error instanceof Error && 'cause' in error) { console.error('OIDC error cause:', error.cause); } + return NextResponse.redirect(`${origin}/login?error=oidc_failed`); } } diff --git a/src/app/login/login-form.tsx b/src/app/login/login-form.tsx index 6ed9af8..8590429 100644 --- a/src/app/login/login-form.tsx +++ b/src/app/login/login-form.tsx @@ -6,7 +6,7 @@ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; -import { Database, ExternalLink, Lock, Mail, ShieldCheck, UserCheck } from 'lucide-react'; +import { Database, ExternalLink, Lock, Mail, ShieldCheck, UserCheck, Zap, Globe, Shield, Layers } from 'lucide-react'; import { toast } from 'sonner'; import { Badge } from '@/components/ui/badge'; @@ -53,141 +53,277 @@ function LoginFormInner({ authProvider }: { authProvider: string }) { } }; + const features = [ + { icon: Globe, title: '7+ Database Engines', desc: 'PostgreSQL, MySQL, MongoDB, Oracle, SQL Server' }, + { icon: Zap, title: 'AI-Native Queries', desc: 'Natural language to SQL with multi-model LLM support' }, + { icon: Shield, title: 'Zero Install', desc: 'Browser-based — deploy anywhere with Docker in seconds' }, + { icon: Layers, title: 'Real-Time Monitoring', desc: 'Live metrics, schema explorer, and visual ERD diagrams' }, + ]; + return ( -
- - -
-
-
-
- -
+
+ {/* Left Panel - Branding (hidden on mobile) */} +
+ {/* Base background matching app zinc-950 */} +
+
+ + {/* Dot grid pattern */} +
+ + {/* Ambient glow orbs — blue accent family */} +
+
+ + {/* Right edge separator */} +
+ + {/* Content */} +
+ {/* Top: Logo */} +
+
+
+ LibreDB Studio
-
- LibreDB Studio - - Secure database administration and management portal - -
- - - - {isOIDC ? ( - <> - {oidcError && ( -
- Authentication failed. Please try again. -
- )} - - - ) : ( - <> -
-
- -
- - setEmail(e.target.value)} - required - /> + + {/* Middle: Hero text + Features */} +
+
+

+ The open-source SQL IDE for + cloud-native teams +

+

+ Query, explore, and manage all your databases from a single AI-powered interface. Zero install — deploy with Docker in seconds. +

+
+ +
+ {features.map((feature) => ( +
+
+
-
-
- -
- - setPassword(e.target.value)} - required - /> +
+

{feature.title}

+

{feature.desc}

-
+ + {/* Bottom: DB badges */} +
+

Supported Databases

+
+ {['PostgreSQL', 'MySQL', 'MongoDB', 'Oracle', 'SQL Server'].map((db) => ( + - {isLoading ? 'Authenticating...' : 'Sign In'} - - + {db} + + ))} +
+
+
+
-
-
- -
-
- Quick Access for Demo -
+ {/* Right Panel - Login Form */} +
+
+ {/* Mobile branding (visible only on mobile) */} +
+
+
+
+
+
+
+

LibreDB Studio

+

Open-source SQL IDE for cloud-native teams

+
+
-
- - - + +
+
+ + Encrypted +
+
+ + OIDC Protected +
- - user@libredb.org - - -
- - )} - - - -

- Enterprise-grade security powered by LibreDB Studio Engine -

- - v{process.env.NEXT_PUBLIC_APP_VERSION} - -
- + + ) : ( + <> +
+
+ +
+ + setEmail(e.target.value)} + required + /> +
+
+
+ +
+ + setPassword(e.target.value)} + required + /> +
+
+ +
+ +
+
+ +
+
+ Quick Access for Demo +
+
+ +
+ + + +
+ + )} + + + +

+ Enterprise-grade security powered by LibreDB Studio Engine +

+ + v{process.env.NEXT_PUBLIC_APP_VERSION} + +
+ + + {/* Mobile feature pills */} +
+ {['PostgreSQL', 'MySQL', 'MongoDB', 'Oracle', 'SQL Server'].map((db) => ( + + {db} + + ))} +
+
+
); } diff --git a/tests/components/LoginPage.test.tsx b/tests/components/LoginPage.test.tsx index 5606932..c948baa 100644 --- a/tests/components/LoginPage.test.tsx +++ b/tests/components/LoginPage.test.tsx @@ -47,8 +47,8 @@ describe('LoginPage', () => { }); test('renders LibreDB Studio title', () => { - const { getByText } = renderLogin(); - expect(getByText('LibreDB Studio')).not.toBeNull(); + const { getAllByText } = renderLogin(); + expect(getAllByText('LibreDB Studio').length).toBeGreaterThanOrEqual(1); }); test('renders quick access Admin and User buttons', () => {