1+ import 'package:flutter/cupertino.dart' ;
2+ import 'package:flutter/material.dart' ;
3+ import 'package:pheno_ui/interface/strapi.dart' ;
4+ import 'package:pheno_ui_tester/widgets/loading_screen.dart' ;
5+ import 'package:shared_preferences/shared_preferences.dart' ;
6+
7+ import 'category_picker.dart' ;
8+
9+ class Login extends StatefulWidget {
10+ const Login ({super .key});
11+
12+ @override
13+ LoginState createState () => LoginState ();
14+ }
15+
16+ class LoginState extends State <Login > {
17+ final TextEditingController _server = TextEditingController ();
18+ final TextEditingController _user = TextEditingController ();
19+ final TextEditingController _password = TextEditingController ();
20+ late final SharedPreferences prefs;
21+ String ? error;
22+
23+ bool _loaded = false ;
24+
25+ final ButtonStyle _buttonStyle = ButtonStyle (
26+ minimumSize: MaterialStateProperty .all (const Size (200 , 50 )),
27+ );
28+
29+ final Widget _gap = const SizedBox (height: 20 );
30+
31+ final TextStyle _textStyle = const TextStyle (
32+ color: Colors .white,
33+ fontSize: 12 ,
34+ fontWeight: FontWeight .normal,
35+ decoration: TextDecoration .none,
36+ );
37+
38+ final TextStyle _errorStyle = const TextStyle (
39+ color: Colors .orange,
40+ fontSize: 14 ,
41+ fontWeight: FontWeight .bold,
42+ decoration: TextDecoration .none,
43+ );
44+
45+ final InputDecoration _inputDecoration = const InputDecoration (
46+ enabledBorder: OutlineInputBorder (borderSide: BorderSide (color: Colors .grey)),
47+ focusedBorder: OutlineInputBorder (borderSide: BorderSide (color: Colors .white)),
48+ border: OutlineInputBorder (borderSide: BorderSide (color: Colors .white)),
49+ contentPadding: EdgeInsets .all (10 ),
50+ isDense: true ,
51+ );
52+
53+ @override
54+ void initState () {
55+ super .initState ();
56+ SharedPreferences .getInstance ().then ((prefs) async {
57+ this .prefs = prefs;
58+ _server.text = prefs.getString ('strapi_server' ) ?? '' ;
59+ _user.text = prefs.getString ('strapi_user' ) ?? '' ;
60+ String ? jwt = prefs.getString ('strapi_jwt' );
61+ if (_server.text.isNotEmpty && jwt != null && jwt.isNotEmpty) {
62+ if (! await Strapi ().loginJwt (_server.text, jwt)) {
63+ prefs.remove ('strapi_jwt' );
64+ } else {
65+ _user.text = Strapi ().user! ;
66+ prefs.setString ('strapi_user' , _user.text);
67+ }
68+ }
69+
70+ setState (() {
71+ _loaded = true ;
72+ });
73+ });
74+ }
75+
76+ Widget _buildLogin (BuildContext context) {
77+ List <Widget > children = [
78+ Text ('Server:' , style: _textStyle),
79+ SizedBox (
80+ width: 300 ,
81+ // height: 100,
82+ child: TextField (
83+ decoration: _inputDecoration,
84+ controller: _server,
85+ style: _textStyle,
86+ ),
87+ ),
88+
89+ _gap,
90+
91+ Text ('User:' , style: _textStyle),
92+ SizedBox (
93+ width: 300 ,
94+ // height: 100,
95+ child: TextField (
96+ decoration: _inputDecoration,
97+ controller: _user,
98+ style: _textStyle,
99+ ),
100+ ),
101+
102+ _gap,
103+
104+ Text ('Password:' , style: _textStyle),
105+ SizedBox (
106+ width: 300 ,
107+ // height: 100,
108+ child: TextField (
109+ decoration: _inputDecoration,
110+ controller: _password,
111+ style: _textStyle,
112+ ),
113+ ),
114+
115+ _gap,
116+
117+ ElevatedButton (
118+ style: _buttonStyle,
119+ onPressed: () async {
120+ setState (() {
121+ _loaded = false ;
122+ });
123+ try {
124+ String jwt = await Strapi ().login (Uri .parse (_server.text), _user.text, _password.text);
125+ prefs.setString ('strapi_server' , _server.text);
126+ prefs.setString ('strapi_user' , _user.text);
127+ prefs.setString ('strapi_jwt' , jwt);
128+ } catch (e) {
129+ error = e.toString ();
130+ }
131+ setState (() {
132+ _loaded = true ;
133+ });
134+ },
135+ child: const Text ('Login' ),
136+ ),
137+ ];
138+
139+ if (error != null ) {
140+ children.add (_gap);
141+ children.add (Text (error! , style: _errorStyle));
142+ }
143+
144+ return Material (
145+ color: Colors .transparent,
146+ child: Center (
147+ child: Column (
148+ mainAxisSize: MainAxisSize .min,
149+ children: children,
150+ ),
151+ ),
152+ );
153+ }
154+
155+ Widget _buildLogout (BuildContext context) {
156+ return Center (
157+ child: Column (
158+ mainAxisSize: MainAxisSize .min,
159+ children: [
160+ Text (
161+ 'Logged in\n\n Server:\n ${Strapi ().server }\n\n User:\n ${Strapi ().user }\n ' ,
162+ style: _textStyle,
163+ ),
164+
165+ _gap,
166+
167+ ElevatedButton (
168+ style: _buttonStyle,
169+ onPressed: () {
170+ setState (() {
171+ Strapi ().logout ();
172+ prefs.remove ('strapi_jwt' );
173+ });
174+ },
175+ child: const Text ('Logout' ),
176+ ),
177+
178+ _gap,
179+
180+ ElevatedButton (
181+ style: _buttonStyle,
182+ onPressed: () {
183+ Navigator .of (context).push (PageRouteBuilder (
184+ settings: const RouteSettings (name: 'category_picker' ),
185+ transitionDuration: Duration .zero,
186+ reverseTransitionDuration: Duration .zero,
187+ pageBuilder: (context, _, __) => const CategoryPicker (),
188+ ));
189+ },
190+ child: const Text ('Continue' ),
191+ ),
192+ ],
193+ ),
194+ );
195+ }
196+
197+ @override
198+ Widget build (BuildContext context) {
199+ if (! _loaded) {
200+ return loadingScreen ();
201+ }
202+ return Container (
203+ color: Colors .blueGrey,
204+ child: Strapi ().isLoggedIn ? _buildLogout (context) : _buildLogin (context),
205+ );
206+ }
207+ }
0 commit comments