Files
GroundedHelper/frontend/lib/Grounded/see/login/LoginState.dart
alvocool d3431ca5de Switch to Inter, round the corners softly and make the nav switch tabs
Inter replaces General Sans (Inter Display for titles and big numbers).
Corners come back from before the squaring commit, scaled to a soft set
(16 cards, 14 buttons, 12 rows, 8 chips) and applied to the screens built
since. The nav is now a cluster of round frosted buttons that switches
Today, Routines, Goals, Groups and Progress in place inside Home: no
pushed pages, no back arrows, and Android back returns to Today.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
2026-11-09 07:08:46 +03:00

188 lines
5.8 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../about/external/initial/LoginData.dart';
import '../../about/internal/application/NavigatorType.dart';
import '../../about/internal/application/TextType.dart';
import '../../about/internal/application/UserDetails.dart';
import '../../configs/Navigator.dart';
import '../../designs/Responsive.dart';
import '../../designs/buttons/Buttons.dart';
import '../../designs/input/InputFields.dart';
import '../../designs/text/Text.dart';
import '../../utils/Colors.dart';
import '../../utils/Validators.dart';
import '../home/Home.dart';
import 'ConnectLogin.dart';
import 'Login.dart';
import 'ViewLogin.dart';
class LoginState extends State<Login> implements ConnectLogin {
ViewLogin? _model;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _username = TextEditingController();
final TextEditingController _password = TextEditingController();
bool _obscured = true;
@override
Widget build(BuildContext context) {
return ViewModelBuilder<ViewLogin>.reactive(
viewModelBuilder: () => ViewLogin(context, this),
onViewModelReady: (viewModel) {
_model = viewModel;
_initiate();
},
builder: (context, viewModel, child) => Scaffold(
backgroundColor: colorPrimaryDark,
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Responsive(
mobile: _mobileView(constraints),
tablet: _mobileView(constraints),
desktop: _mobileView(constraints),
);
},
),
),
);
}
void _initiate() {}
void _onToggleObscured() {
setState(() {
_obscured = !_obscured;
});
}
void _onSignIn() {
if (_formKey.currentState?.validate() != true) {
return;
}
_model?.login(LoginData(
username: _username.text.trim(),
password: _password.text,
));
}
Widget _mobileView(BoxConstraints constraints) {
return Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SafeArea(
bottom: false,
child: Padding(
padding: const EdgeInsets.fromLTRB(28, 24, 28, 32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
text("GROUNDED", 10, TextType.Bold,
color: colorWhite.withValues(alpha: 0.45),
letterSpacing: 2.0),
const SizedBox(height: 22),
text("Welcome back.", 36, TextType.Light,
color: colorWhite, height: 1.1),
const SizedBox(height: 10),
text(
"Your record has been waiting exactly where you left it.",
14,
TextType.Regular,
color: colorWhite.withValues(alpha: 0.55),
height: 1.5,
),
],
),
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
color: colorPrimaryLight,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
clipBehavior: Clip.antiAlias,
child: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(24, 32, 24, 32),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
inputField(
"Username",
_username,
hint: "The one you signed up with",
validator: Validators.username,
keyboard: TextInputType.emailAddress,
icon: CupertinoIcons.person,
),
const SizedBox(height: 20),
inputField(
"Password",
_password,
hint: "Your password",
validator: Validators.password,
obscure: _obscured,
icon: CupertinoIcons.lock,
),
const SizedBox(height: 8),
Align(
alignment: Alignment.centerRight,
child: textButton(
_obscured ? "Show password" : "Hide password",
_onToggleObscured,
textSize: 12,
),
),
const SizedBox(height: 20),
roundedCornerButton(
"Sign in",
_onSignIn,
icon: CupertinoIcons.arrow_right,
),
const SizedBox(height: 24),
Center(
child: text(
"Nothing here judges you for being away.",
12,
TextType.Regular,
color: colorGrey2,
align: TextAlign.center,
),
),
],
),
),
),
),
),
],
);
}
@override
void onLoggedIn(UserDetails details) {
GroundedNavigation()
.navigateToPage(NavigatorType.makeNewMain, const Home(), context);
}
@override
void dispose() {
_username.dispose();
_password.dispose();
super.dispose();
}
}