tuuli_app/lib/pages/login_page.dart

150 lines
4.8 KiB
Dart

import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tuuli_api/tuuli_api.dart';
import 'package:tuuli_app/api_controller.dart';
class LoginPageController extends GetxController {
final _username = "".obs;
String get username => _username.value;
set username(String value) => _username.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 => username.isNotEmpty && password.isNotEmpty;
Future<void> submitForm() async {
submitted = true;
if (isFormValid) {
try {
final resp = await ApiController.to.apiClient.getAccessToken(
authModel: AuthModel(
username: username,
password: password,
),
);
final respData = resp.data;
if (resp.statusCode == 200 && respData != null) {
final accessToken = respData.accessToken;
Get.find<ApiController>().token = accessToken;
WidgetsBinding.instance.addPostFrameCallback((_) {
Get.offAllNamed("/home");
});
} else {
Get.snackbar(
"Login failed",
resp.statusMessage ?? "Unknown error",
);
}
} on DioError catch (e) {
final errorData = e.response?.data;
if (errorData != null) {
final error = errorData["error"];
if (error != null) {
Get.snackbar(
"Login failed",
"$error",
);
}
} else {
Get.snackbar(
"Login failed",
"$e",
);
}
} catch (e) {
Get.snackbar(
"Login failed",
"$e",
);
}
}
submitted = false;
}
}
class LoginPage extends GetView<LoginPageController> {
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: [
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 username',
),
onChanged: (value) => controller.username = 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'),
),
],
),
),
),
),
],
),
],
),
);
}
}