[ui] UI theme should match repertory blue #61
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				BlockStorage/repertory/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	BlockStorage/repertory/pipeline/head This commit looks good
				
			This commit is contained in:
		| @@ -18,99 +18,174 @@ class _AuthScreenState extends State<AuthScreen> { | ||||
|  | ||||
|   @override | ||||
|   Widget build(context) { | ||||
|     return Scaffold( | ||||
|       appBar: AppBar( | ||||
|         backgroundColor: Theme.of(context).colorScheme.inversePrimary, | ||||
|         title: Text(widget.title), | ||||
|     final scheme = Theme.of(context).colorScheme; | ||||
|  | ||||
|     InputDecoration decoration(String label, IconData icon) => InputDecoration( | ||||
|       labelText: label, | ||||
|       prefixIcon: Icon(icon), | ||||
|       filled: true, | ||||
|       fillColor: scheme.surfaceContainerLow.withValues(alpha: 0.65), | ||||
|       border: OutlineInputBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|         borderSide: BorderSide.none, | ||||
|       ), | ||||
|       body: Consumer<Auth>( | ||||
|         builder: (context, auth, _) { | ||||
|           if (auth.authenticated) { | ||||
|             Future.delayed(Duration(milliseconds: 1), () { | ||||
|               if (constants.navigatorKey.currentContext == null) { | ||||
|                 return; | ||||
|               } | ||||
|       focusedBorder: OutlineInputBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|         borderSide: BorderSide(color: scheme.primary, width: 2), | ||||
|       ), | ||||
|       contentPadding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14), | ||||
|     ); | ||||
|  | ||||
|               Navigator.of( | ||||
|                 constants.navigatorKey.currentContext!, | ||||
|               ).pushNamedAndRemoveUntil('/', (Route<dynamic> route) => false); | ||||
|             }); | ||||
|             return SizedBox.shrink(); | ||||
|           } | ||||
|     VoidCallback? createLoginHandler(Auth auth) { | ||||
|       if (!_enabled) return null; | ||||
|       return () async { | ||||
|         setState(() => _enabled = false); | ||||
|         await auth.authenticate(_userController.text, _passwordController.text); | ||||
|         setState(() => _enabled = true); | ||||
|       }; | ||||
|     } | ||||
|  | ||||
|           createLoginHandler() { | ||||
|             return _enabled | ||||
|                 ? () async { | ||||
|                   setState(() => _enabled = false); | ||||
|                   await auth.authenticate( | ||||
|                     _userController.text, | ||||
|                     _passwordController.text, | ||||
|                   ); | ||||
|                   setState(() => _enabled = true); | ||||
|     return Scaffold( | ||||
|       appBar: AppBar(title: Text(widget.title), scrolledUnderElevation: 0), | ||||
|       body: Container( | ||||
|         width: double.infinity, | ||||
|         height: double.infinity, | ||||
|         decoration: const BoxDecoration( | ||||
|           gradient: LinearGradient( | ||||
|             begin: Alignment.topLeft, | ||||
|             end: Alignment.bottomRight, | ||||
|             colors: [Color(0xFF1050A0), Color(0xFF202124)], | ||||
|           ), | ||||
|         ), | ||||
|         child: Consumer<Auth>( | ||||
|           builder: (context, auth, _) { | ||||
|             if (auth.authenticated) { | ||||
|               Future.delayed(Duration(milliseconds: 1), () { | ||||
|                 if (constants.navigatorKey.currentContext == null) { | ||||
|                   return; | ||||
|                 } | ||||
|                 : null; | ||||
|           } | ||||
|  | ||||
|           return Center( | ||||
|             child: Card( | ||||
|               child: Padding( | ||||
|                 padding: const EdgeInsets.all(constants.padding), | ||||
|                 child: SizedBox( | ||||
|                   width: constants.logonWidth, | ||||
|                   child: Column( | ||||
|                     mainAxisSize: MainAxisSize.min, | ||||
|                     mainAxisAlignment: MainAxisAlignment.start, | ||||
|                     crossAxisAlignment: CrossAxisAlignment.stretch, | ||||
|                     children: [ | ||||
|                       Text( | ||||
|                         constants.appLogonTitle, | ||||
|                         textAlign: TextAlign.center, | ||||
|                         style: Theme.of(context).textTheme.titleLarge, | ||||
|                       ), | ||||
|                       const SizedBox(height: constants.padding), | ||||
|                       TextField( | ||||
|                         autofocus: true, | ||||
|                         decoration: InputDecoration(labelText: 'Username'), | ||||
|                         controller: _userController, | ||||
|                         textInputAction: TextInputAction.next, | ||||
|                       ), | ||||
|                       const SizedBox(height: constants.padding), | ||||
|                       TextField( | ||||
|                         obscureText: true, | ||||
|                         decoration: InputDecoration(labelText: 'Password'), | ||||
|                         controller: _passwordController, | ||||
|                         textInputAction: TextInputAction.go, | ||||
|                         onSubmitted: (_) { | ||||
|                           final handler = createLoginHandler(); | ||||
|                           if (handler == null) { | ||||
|                             return; | ||||
|                           } | ||||
|                 Navigator.of( | ||||
|                   constants.navigatorKey.currentContext!, | ||||
|                 ).pushNamedAndRemoveUntil('/', (Route<dynamic> route) => false); | ||||
|               }); | ||||
|  | ||||
|                           handler(); | ||||
|                         }, | ||||
|               return const SizedBox.shrink(); | ||||
|             } | ||||
|  | ||||
|             return Center( | ||||
|               child: AnimatedScale( | ||||
|                 scale: 1.0, | ||||
|                 duration: const Duration(milliseconds: 250), | ||||
|                 curve: Curves.easeOutCubic, | ||||
|                 child: AnimatedOpacity( | ||||
|                   opacity: 1.0, | ||||
|                   duration: const Duration(milliseconds: 250), | ||||
|                   child: ConstrainedBox( | ||||
|                     constraints: const BoxConstraints( | ||||
|                       maxWidth: 420, | ||||
|                       minWidth: 300, | ||||
|                     ), | ||||
|                     child: Card( | ||||
|                       elevation: 12, | ||||
|                       color: scheme.surface, | ||||
|                       shape: RoundedRectangleBorder( | ||||
|                         borderRadius: BorderRadius.circular(18), | ||||
|                       ), | ||||
|                       const SizedBox(height: constants.padding), | ||||
|                       ElevatedButton( | ||||
|                         onPressed: createLoginHandler(), | ||||
|                         child: const Text('Login'), | ||||
|                       child: Padding( | ||||
|                         padding: const EdgeInsets.all(constants.padding), | ||||
|                         child: Column( | ||||
|                           mainAxisSize: MainAxisSize.min, | ||||
|                           crossAxisAlignment: CrossAxisAlignment.stretch, | ||||
|                           children: [ | ||||
|                             Align( | ||||
|                               alignment: Alignment.center, | ||||
|                               child: CircleAvatar( | ||||
|                                 radius: 28, | ||||
|                                 backgroundColor: scheme.primary.withValues( | ||||
|                                   alpha: 0.18, | ||||
|                                 ), | ||||
|                                 child: Icon( | ||||
|                                   Icons.folder, | ||||
|                                   color: scheme.primary, | ||||
|                                   size: 28, | ||||
|                                 ), | ||||
|                               ), | ||||
|                             ), | ||||
|                             const SizedBox(height: 14), | ||||
|                             Text( | ||||
|                               constants.appLogonTitle, | ||||
|                               textAlign: TextAlign.center, | ||||
|                               style: Theme.of(context).textTheme.headlineSmall | ||||
|                                   ?.copyWith(fontWeight: FontWeight.w600), | ||||
|                             ), | ||||
|                             const SizedBox(height: 6), | ||||
|                             Text( | ||||
|                               "Secure access to your mounts", | ||||
|                               textAlign: TextAlign.center, | ||||
|                               style: Theme.of(context).textTheme.bodyMedium | ||||
|                                   ?.copyWith( | ||||
|                                     color: scheme.onSurface.withValues( | ||||
|                                       alpha: 0.7, | ||||
|                                     ), | ||||
|                                   ), | ||||
|                             ), | ||||
|                             const SizedBox(height: 20), | ||||
|                             TextField( | ||||
|                               autofocus: true, | ||||
|                               controller: _userController, | ||||
|                               textInputAction: TextInputAction.next, | ||||
|                               decoration: decoration('Username', Icons.person), | ||||
|                             ), | ||||
|                             const SizedBox(height: constants.padding), | ||||
|                             TextField( | ||||
|                               controller: _passwordController, | ||||
|                               obscureText: true, | ||||
|                               textInputAction: TextInputAction.go, | ||||
|                               onSubmitted: (_) { | ||||
|                                 final handler = createLoginHandler(auth); | ||||
|                                 handler?.call(); | ||||
|                               }, | ||||
|                               decoration: decoration('Password', Icons.lock), | ||||
|                             ), | ||||
|                             const SizedBox(height: constants.padding), | ||||
|                             SizedBox( | ||||
|                               height: 44, | ||||
|                               child: ElevatedButton( | ||||
|                                 onPressed: createLoginHandler(auth), | ||||
|                                 style: ElevatedButton.styleFrom( | ||||
|                                   shape: RoundedRectangleBorder( | ||||
|                                     borderRadius: BorderRadius.circular(12), | ||||
|                                   ), | ||||
|                                 ), | ||||
|                                 child: _enabled | ||||
|                                     ? const Text('Login') | ||||
|                                     : const SizedBox( | ||||
|                                         height: 20, | ||||
|                                         width: 20, | ||||
|                                         child: CircularProgressIndicator( | ||||
|                                           strokeWidth: 2.4, | ||||
|                                         ), | ||||
|                                       ), | ||||
|                               ), | ||||
|                             ), | ||||
|                           ], | ||||
|                         ), | ||||
|                       ), | ||||
|                     ], | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|               ), | ||||
|             ), | ||||
|           ); | ||||
|         }, | ||||
|             ); | ||||
|           }, | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void setState(VoidCallback fn) { | ||||
|     if (!mounted) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     if (!mounted) return; | ||||
|     super.setState(fn); | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user