From 9219a046147940daecb6fe73d7985529d7d4b8c6 Mon Sep 17 00:00:00 2001 From: tk Date: Sat, 16 Aug 2025 22:28:51 +0200 Subject: [PATCH] add auth skeleton --- .../lib/helper/auth_service.dart | 30 +++++++++++ .../lib/helper/go_router.dart | 28 +++++++++-- .../wien_talks_flutter/lib/login_page.dart | 50 +++++++++++++++++++ 3 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 wien_talks/wien_talks_flutter/lib/helper/auth_service.dart create mode 100644 wien_talks/wien_talks_flutter/lib/login_page.dart diff --git a/wien_talks/wien_talks_flutter/lib/helper/auth_service.dart b/wien_talks/wien_talks_flutter/lib/helper/auth_service.dart new file mode 100644 index 0000000..0445f78 --- /dev/null +++ b/wien_talks/wien_talks_flutter/lib/helper/auth_service.dart @@ -0,0 +1,30 @@ +import 'package:google_sign_in/google_sign_in.dart'; + +class AuthService { + static final _google = GoogleSignIn.instance; + + static AuthService? _instance; + + AuthService._() { + _google.initialize(); + } + factory AuthService() { + if (_instance != null) return _instance!; + _instance = AuthService._(); + + return _instance!; + } + + static Stream get onUserChanged => + _google.authenticationEvents; + + static Future signIn() async { + try { + return await _google.authenticate(); + } catch (_) { + return null; + } + } + + static Future signOut() => _google.disconnect(); +} diff --git a/wien_talks/wien_talks_flutter/lib/helper/go_router.dart b/wien_talks/wien_talks_flutter/lib/helper/go_router.dart index bdc24c1..bca0dc4 100644 --- a/wien_talks/wien_talks_flutter/lib/helper/go_router.dart +++ b/wien_talks/wien_talks_flutter/lib/helper/go_router.dart @@ -1,13 +1,31 @@ +import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:wien_talks_flutter/create_event_screen.dart'; -import 'package:wien_talks_flutter/home_screen.dart'; +import 'package:wien_talks_flutter/helper/auth_service.dart'; +import 'package:wien_talks_flutter/login_page.dart'; +import 'package:wien_talks_flutter/news_screen.dart'; final router = GoRouter( + redirect: (context, state) { + final loggedIn = AuthService.user != null; + final atLogin = state.matchedLocation == '/login'; + if (!loggedIn && !atLogin) return '/login'; + if (loggedIn && atLogin) return '/'; + return null; + }, + refreshListenable: AuthChangeNotifier(), routes: [ + GoRoute(path: '/login', builder: (c, s) => const LoginScreen()), + GoRoute(path: '/', builder: (c, s) => NewsScreen()), GoRoute( - path: '/', - builder: (context, state) => HomeScreen(), - ), - GoRoute(path: '/create_event', name: 'create_event', builder: (context, state) => CreateEventScreen()), + path: '/create_event', + name: 'create_event', + builder: (c, s) => CreateEventScreen()), ], ); + +class AuthChangeNotifier extends ChangeNotifier { + AuthChangeNotifier() { + AuthService.onUserChanged.listen((_) => notifyListeners()); + } +} diff --git a/wien_talks/wien_talks_flutter/lib/login_page.dart b/wien_talks/wien_talks_flutter/lib/login_page.dart new file mode 100644 index 0000000..1eff639 --- /dev/null +++ b/wien_talks/wien_talks_flutter/lib/login_page.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:wien_talks_flutter/helper/auth_service.dart'; + +class LoginScreen extends StatelessWidget { + const LoginScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Color(0xff2193b0), Color(0xff6dd5ed)], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + alignment: Alignment.center, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text('Wien Talks', + style: GoogleFonts.poppins( + fontSize: 42, + fontWeight: FontWeight.bold, + color: Colors.white)), + const SizedBox(height: 60), + FilledButton.icon( + onPressed: () async => await AuthService.signIn(), + style: FilledButton.styleFrom( + backgroundColor: Colors.white, + foregroundColor: Colors.black87, + padding: + const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30)), + elevation: 6, + ), + icon: Icon( + Icons.lock, + ), + label: const Text('Sign in with Google'), + ), + ], + ), + ), + ); + } +}