diff --git a/lib/main.dart b/lib/main.dart index ac54169..36f676d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,26 +1,29 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; -import 'package:tuuli_app/api/api_client.dart'; +import 'package:tuuli_app/api_controller.dart'; import 'package:tuuli_app/pages/checkup_page.dart'; import 'package:tuuli_app/pages/home_page.dart'; +import 'package:tuuli_app/pages/home_panels/tables_list_panel.dart'; +import 'package:tuuli_app/pages/home_panels/users_list_panel.dart'; import 'package:tuuli_app/pages/login_page.dart'; import 'package:tuuli_app/pages/not_found_page.dart'; void main() async { await GetStorage.init(); - Get.put( - ApiClient.fromString("http://127.0.0.1:8000"), - permanent: true, - builder: () { - final client = ApiClient.fromString("http://127.0.0.1:8000"); - final accessToken = GetStorage().read("accessToken"); - if (accessToken != null) { - client.setAccessToken(accessToken); - } - return client; - }, + Get.put(ApiController(), permanent: true); + Get.lazyPut( + () => CheckupPageController(), + fenix: true, + ); + Get.lazyPut( + () => LoginPageController(), + fenix: true, + ); + Get.lazyPut( + () => HomePageController(), + fenix: true, ); runApp(const MainApp()); diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index 98a0f67..ebdfc94 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -3,9 +3,139 @@ import 'dart:async'; import 'package:animated_background/animated_background.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:get_storage/get_storage.dart'; -import 'package:tuuli_app/api/api_client.dart'; +import 'package:tuuli_api/tuuli_api.dart'; +import 'package:tuuli_app/api_controller.dart'; +class LoginPageController extends GetxController + with GetSingleTickerProviderStateMixin { + final _login = "".obs; + String get login => _login.value; + set login(String value) => _login.value = value; + + final _password = "".obs; + String get password => _password.value; + set password(String value) => _password.value = value; + + final _submitted = false.obs; + bool get submitted => _submitted.value; + set submitted(bool value) => _submitted.value = value; + + bool get isFormValid => login.isNotEmpty && password.isNotEmpty; + + Future submitForm() async { + submitted = true; + if (isFormValid) { + final amb = AuthModelBuilder() + ..username = login + ..password = password; + + try { + final resp = await ApiController.to.apiClient + .getAccessTokenApiGetAccessTokenPost(authModel: amb.build()); + + final respData = resp.data; + if (resp.statusCode == 200 && respData != null) { + final accessToken = respData.accessToken; + Get.find().token = accessToken; + Get.offAllNamed("/home"); + } else { + Get.snackbar( + "Login failed", + resp.statusMessage ?? "Unknown error", + ); + } + } catch (e) { + Get.snackbar( + "Login failed", + "$e", + ); + } + } + submitted = false; + } +} + +class LoginPage extends GetView { + const LoginPage({super.key}); + + @override + Widget build(BuildContext context) { + final screenSize = Get.mediaQuery.size; + final formWidth = screenSize.width <= 600 ? screenSize.width : 300.0; + return Scaffold( + body: Stack( + children: [ + AnimatedBackground( + behaviour: RandomParticleBehaviour(), + vsync: controller, + child: const SizedBox.square( + dimension: 0, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + LimitedBox( + maxWidth: formWidth, + child: Obx( + () => Container( + color: Colors.black.withAlpha(100), + padding: const EdgeInsets.all(16), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + TextFormField( + enabled: !controller.submitted, + decoration: const InputDecoration( + labelText: 'Login', + hintText: 'Enter your login', + ), + onChanged: (value) => controller.login = value, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your Login'; + } + return null; + }, + ), + TextFormField( + obscureText: true, + enabled: !controller.submitted, + decoration: const InputDecoration( + labelText: 'Password', + hintText: 'Enter your password', + ), + onChanged: (value) => controller.password = value, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your password'; + } + return null; + }, + ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: controller.submitted + ? null + : () => controller.submitForm(), + child: const Text('Login'), + ), + ], + ), + ), + ), + ), + ], + ), + ], + ), + ); + } +} +/* class LoginPage extends StatefulWidget { const LoginPage({super.key}); @@ -19,7 +149,7 @@ class _LoginPageState extends State with TickerProviderStateMixin { final apiClient = Get.find(); var submitted = false; - final loginController = TextEditingController(); + final loginPageController = TextEditingController(); final passwordController = TextEditingController(); @override @@ -53,7 +183,7 @@ class _LoginPageState extends State with TickerProviderStateMixin { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextFormField( - controller: loginController, + controller: loginPageController, enabled: !submitted, decoration: const InputDecoration( labelText: 'Login', @@ -113,7 +243,7 @@ class _LoginPageState extends State with TickerProviderStateMixin { ); final response = await apiClient.login( - loginController.text.trim(), + loginPageController.text.trim(), passwordController.text.trim(), ); response.unfold((data) { @@ -148,3 +278,4 @@ class _LoginPageState extends State with TickerProviderStateMixin { }); } } +*/ \ No newline at end of file