1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/material.dart';
6
7import 'colors.dart';
8
9class LoginPage extends StatefulWidget {
10 const LoginPage({super.key});
11
12 @override
13 State<LoginPage> createState() => _LoginPageState();
14}
15
16class _LoginPageState extends State<LoginPage> {
17 final TextEditingController _usernameController = TextEditingController();
18 final TextEditingController _passwordController = TextEditingController();
19 static const ShapeDecoration _decoration = ShapeDecoration(
20 shape: BeveledRectangleBorder(
21 side: BorderSide(color: kShrineBrown900, width: 0.5),
22 borderRadius: BorderRadius.all(Radius.circular(7.0)),
23 ),
24 );
25
26 @override
27 Widget build(BuildContext context) {
28 return Scaffold(
29 appBar: AppBar(
30 elevation: 0.0,
31 backgroundColor: Colors.white,
32 leading: IconButton(
33 icon: const BackButtonIcon(),
34 tooltip: MaterialLocalizations.of(context).backButtonTooltip,
35 onPressed: () {
36 // The login screen is immediately displayed on top of the Shrine
37 // home screen using onGenerateRoute and so rootNavigator must be
38 // set to true in order to get out of Shrine completely.
39 Navigator.of(context, rootNavigator: true).pop();
40 },
41 ),
42 ),
43 body: SafeArea(
44 child: ListView(
45 padding: const EdgeInsets.symmetric(horizontal: 24.0),
46 children: <Widget>[
47 const SizedBox(height: 80.0),
48 Column(
49 children: <Widget>[
50 Image.asset('packages/shrine_images/diamond.png'),
51 const SizedBox(height: 16.0),
52 Text('SHRINE', style: Theme.of(context).textTheme.headlineSmall),
53 ],
54 ),
55 const SizedBox(height: 120.0),
56 PrimaryColorOverride(
57 color: kShrineBrown900,
58 child: Container(
59 decoration: _decoration,
60 child: TextField(
61 controller: _usernameController,
62 decoration: const InputDecoration(labelText: 'Username'),
63 ),
64 ),
65 ),
66 const SizedBox(height: 12.0),
67 PrimaryColorOverride(
68 color: kShrineBrown900,
69 child: Container(
70 decoration: _decoration,
71 child: TextField(
72 controller: _passwordController,
73 decoration: const InputDecoration(labelText: 'Password'),
74 ),
75 ),
76 ),
77 const SizedBox(height: 12.0),
78 OverflowBar(
79 spacing: 8,
80 alignment: MainAxisAlignment.end,
81 children: <Widget>[
82 TextButton(
83 style: TextButton.styleFrom(
84 shape: const BeveledRectangleBorder(
85 borderRadius: BorderRadius.all(Radius.circular(7.0)),
86 ),
87 ),
88 onPressed: () {
89 // The login screen is immediately displayed on top of
90 // the Shrine home screen using onGenerateRoute and so
91 // rootNavigator must be set to true in order to get out
92 // of Shrine completely.
93 Navigator.of(context, rootNavigator: true).pop();
94 },
95 child: Text('CANCEL', style: Theme.of(context).textTheme.bodySmall),
96 ),
97 ElevatedButton(
98 style: ElevatedButton.styleFrom(
99 elevation: 8.0,
100 shape: const BeveledRectangleBorder(
101 borderRadius: BorderRadius.all(Radius.circular(7.0)),
102 ),
103 ),
104 onPressed: () {
105 Navigator.pop(context);
106 },
107 child: Text('NEXT', style: Theme.of(context).textTheme.bodySmall),
108 ),
109 ],
110 ),
111 ],
112 ),
113 ),
114 );
115 }
116}
117
118class PrimaryColorOverride extends StatelessWidget {
119 const PrimaryColorOverride({super.key, this.color, this.child});
120
121 final Color? color;
122 final Widget? child;
123
124 @override
125 Widget build(BuildContext context) {
126 return Theme(data: Theme.of(context).copyWith(primaryColor: color), child: child!);
127 }
128}
129

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com