Commit b3ee6e80 authored by 张宏's avatar 张宏

33333333333333

parent 257f328c
......@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:laki_icu_app/models/bo/bluetooth_read_model.dart';
import 'package:laki_icu_app/utils/event_bus.dart';
import 'package:laki_icu_app/utils/logger.dart';
import 'package:laki_icu_app/utils/storage/storage_service.dart';
import 'bluetooth_read_event.dart';
......@@ -38,6 +39,7 @@ class BluetoothReadBloc extends Bloc<BluetoothReadEvent, BluetoothReadState> {
emit(state.copyWith(isLoading: true, clearError: true));
try {
final info = await _storageService.getBluetoothReadInfo();
Log.warn('**************sn************: ${info.sn}');
emit(state.copyWith(info: info, isLoading: false, clearError: true));
} catch (e) {
emit(state.copyWith(isLoading: false, error: e.toString()));
......
......@@ -15,7 +15,6 @@ import 'package:laki_icu_app/services/auth_service.dart';
import 'package:laki_icu_app/utils/http/dio_request.dart';
import 'package:laki_icu_app/utils/event_bus.dart';
import 'package:laki_icu_app/utils/storage/storage_service.dart';
import 'package:laki_icu_app/utils/toast_utils.dart';
import 'package:laki_icu_app/routes/app_router.gr.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
......@@ -129,19 +128,23 @@ class _MyAppState extends State<MyApp> {
}
}
/// 静默登录:使用预设账号自动登录
Future<void> _performSilentLogin() async {
/// 静默登录核心逻辑:使用预设账号自动登录
Future<void> _silentLogin() async {
try {
await _authService.login('13800000001', '111111');
// 登录成功,获取用户信息
_authBloc.add(const AuthFetchUserInfo());
} catch (e) {
// 静默登录失败,不做任何处理,初始化结束
} finally {
_endInitializing();
// 静默登录失败,不做任何处理
}
}
/// 启动时的静默登录,登录完成后结束初始化状态
Future<void> _performSilentLogin() async {
await _silentLogin();
_endInitializing();
}
void _endInitializing() {
if (mounted) {
setState(() {
......@@ -188,18 +191,17 @@ class _MyAppState extends State<MyApp> {
],
child: MultiBlocListener(
listeners: [
// AuthBloc 监听器 - 处理登录/登出/Token 过期
// AuthBloc 监听器 - 处理登录/Token 过期/登出
BlocListener<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthSuccess) {
_appRouter.replaceAll([const DefaultLayoutRoute()]);
}
if (state is AuthTokenExpired) {
showToast('登录已过期,请重新登录');
_appRouter.replaceAll([LoginRoute()]);
_silentLogin();
}
if (state is AuthLoggedOut) {
_appRouter.replaceAll([LoginRoute()]);
_silentLogin();
}
},
),
......
// ignore_for_file: unused_import
import 'package:auto_route/auto_route.dart';
import 'package:laki_icu_app/views/login/login_view.dart';
import 'package:laki_icu_app/views/layout/default_view.dart';
import 'package:laki_icu_app/views/monitoring/index/monitoring_index_view.dart';
import 'package:laki_icu_app/views/monitoring/device_control/device_control_index_view.dart';
......@@ -21,8 +20,6 @@ class AppRouter extends $AppRouter {
@override
List<AutoRoute> get routes => [
// LoginRoute / LoginView(登录页)
AutoRoute(page: LoginRoute.page),
// DefaultLayoutRoute / DefaultLayoutView(主框架 Shell)
AutoRoute(
page: DefaultLayoutRoute.page,
......
......@@ -9,22 +9,20 @@
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:auto_route/auto_route.dart' as _i11;
import 'package:flutter/material.dart' as _i12;
import 'package:laki_icu_app/views/blood_pressure/blood_pressure_index_view.dart'
as _i1;
import 'package:laki_icu_app/views/ecg_system/ecg_system_index_view.dart'
as _i4;
import 'package:laki_icu_app/views/layout/default_view.dart' as _i2;
import 'package:laki_icu_app/views/login/login_view.dart' as _i5;
import 'package:laki_icu_app/views/monitoring/device_control/device_control_index_view.dart'
as _i3;
import 'package:laki_icu_app/views/monitoring/index/monitoring_index_view.dart'
as _i6;
import 'package:laki_icu_app/views/record/record_index_view.dart' as _i7;
import 'package:laki_icu_app/views/settings/settings_index_view.dart' as _i8;
import 'package:laki_icu_app/views/tsaas/tsaas_index_view.dart' as _i9;
as _i5;
import 'package:laki_icu_app/views/record/record_index_view.dart' as _i6;
import 'package:laki_icu_app/views/settings/settings_index_view.dart' as _i7;
import 'package:laki_icu_app/views/tsaas/tsaas_index_view.dart' as _i8;
import 'package:laki_icu_app/views/vital_signs/vital_signs_index_view.dart'
as _i10;
as _i9;
abstract class $AppRouter extends _i11.RootStackRouter {
$AppRouter({super.navigatorKey});
......@@ -55,42 +53,34 @@ abstract class $AppRouter extends _i11.RootStackRouter {
child: const _i4.EcgSystemIndexView(),
);
},
LoginRoute.name: (routeData) {
final args = routeData.argsAs<LoginRouteArgs>(
orElse: () => const LoginRouteArgs());
return _i11.AutoRoutePage<dynamic>(
routeData: routeData,
child: _i5.LoginView(key: args.key),
);
},
MonitoringIndexRoute.name: (routeData) {
return _i11.AutoRoutePage<dynamic>(
routeData: routeData,
child: const _i6.MonitoringIndexView(),
child: const _i5.MonitoringIndexView(),
);
},
RecordIndexRoute.name: (routeData) {
return _i11.AutoRoutePage<dynamic>(
routeData: routeData,
child: const _i7.RecordIndexView(),
child: const _i6.RecordIndexView(),
);
},
SettingsIndexRoute.name: (routeData) {
return _i11.AutoRoutePage<dynamic>(
routeData: routeData,
child: const _i8.SettingsIndexView(),
child: const _i7.SettingsIndexView(),
);
},
TsaasIndexRoute.name: (routeData) {
return _i11.AutoRoutePage<dynamic>(
routeData: routeData,
child: const _i9.TsaasIndexView(),
child: const _i8.TsaasIndexView(),
);
},
VitalSignsIndexRoute.name: (routeData) {
return _i11.AutoRoutePage<dynamic>(
routeData: routeData,
child: const _i10.VitalSignsIndexView(),
child: const _i9.VitalSignsIndexView(),
);
},
};
......@@ -153,36 +143,7 @@ class EcgSystemIndexRoute extends _i11.PageRouteInfo<void> {
}
/// generated route for
/// [_i5.LoginView]
class LoginRoute extends _i11.PageRouteInfo<LoginRouteArgs> {
LoginRoute({
_i12.Key? key,
List<_i11.PageRouteInfo>? children,
}) : super(
LoginRoute.name,
args: LoginRouteArgs(key: key),
initialChildren: children,
);
static const String name = 'LoginRoute';
static const _i11.PageInfo<LoginRouteArgs> page =
_i11.PageInfo<LoginRouteArgs>(name);
}
class LoginRouteArgs {
const LoginRouteArgs({this.key});
final _i12.Key? key;
@override
String toString() {
return 'LoginRouteArgs{key: $key}';
}
}
/// generated route for
/// [_i6.MonitoringIndexView]
/// [_i5.MonitoringIndexView]
class MonitoringIndexRoute extends _i11.PageRouteInfo<void> {
const MonitoringIndexRoute({List<_i11.PageRouteInfo>? children})
: super(
......@@ -196,7 +157,7 @@ class MonitoringIndexRoute extends _i11.PageRouteInfo<void> {
}
/// generated route for
/// [_i7.RecordIndexView]
/// [_i6.RecordIndexView]
class RecordIndexRoute extends _i11.PageRouteInfo<void> {
const RecordIndexRoute({List<_i11.PageRouteInfo>? children})
: super(
......@@ -210,7 +171,7 @@ class RecordIndexRoute extends _i11.PageRouteInfo<void> {
}
/// generated route for
/// [_i8.SettingsIndexView]
/// [_i7.SettingsIndexView]
class SettingsIndexRoute extends _i11.PageRouteInfo<void> {
const SettingsIndexRoute({List<_i11.PageRouteInfo>? children})
: super(
......@@ -224,7 +185,7 @@ class SettingsIndexRoute extends _i11.PageRouteInfo<void> {
}
/// generated route for
/// [_i9.TsaasIndexView]
/// [_i8.TsaasIndexView]
class TsaasIndexRoute extends _i11.PageRouteInfo<void> {
const TsaasIndexRoute({List<_i11.PageRouteInfo>? children})
: super(
......@@ -238,7 +199,7 @@ class TsaasIndexRoute extends _i11.PageRouteInfo<void> {
}
/// generated route for
/// [_i10.VitalSignsIndexView]
/// [_i9.VitalSignsIndexView]
class VitalSignsIndexRoute extends _i11.PageRouteInfo<void> {
const VitalSignsIndexRoute({List<_i11.PageRouteInfo>? children})
: super(
......
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../../blocs/bluetooth_read/bluetooth_read_bloc.dart';
import '../../../blocs/bluetooth_read/bluetooth_read_state.dart';
class MonitoringTopStatusBar extends StatelessWidget {
const MonitoringTopStatusBar({super.key});
......@@ -39,6 +43,20 @@ class MonitoringTopStatusBar extends StatelessWidget {
fontSize: 25.sp,
),
),
SizedBox(width: 32.w),
BlocBuilder<BluetoothReadBloc, BluetoothReadState>(
builder: (context, state) {
final sn = state.info.sn;
return Text(
'sn:${sn ?? ''}',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
);
},
),
],
),
);
......
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:laki_icu_app/blocs/auth/auth_bloc.dart';
import 'package:laki_icu_app/blocs/auth/auth_event.dart';
import 'package:laki_icu_app/blocs/auth/auth_state.dart';
import 'package:laki_icu_app/utils/storage/storage_service.dart';
import 'package:laki_icu_app/views/login/cubit/login_state.dart';
class LoginCubit extends Cubit<LoginState> {
final AuthBloc authBloc;
final StorageService storageService;
StreamSubscription<AuthState>? _authSub;
LoginCubit({
required this.authBloc,
required this.storageService,
}) : super(const LoginState()) {
_listenAuthState();
}
void _listenAuthState() {
_authSub = authBloc.stream.listen((authState) {
if (isClosed) return;
if (authState is AuthFailure) {
emit(state.copyWith(isLoading: false, error: authState.error));
} else if (authState is AuthLoading) {
emit(state.copyWith(isLoading: true, error: null));
} else if (authState is AuthSuccess) {
emit(state.copyWith(isLoading: false, error: null));
}
});
}
void toggleRememberPassword(bool value) {
emit(state.copyWith(rememberPassword: value));
}
void login({
required String phone,
required String smsCode,
bool rememberPassword = false,
}) {
if (rememberPassword) {
storageService.saveRememberCredentials(
phone: phone,
smsCode: smsCode,
);
} else {
storageService.clearRememberCredentials();
}
authBloc.add(AuthLoginRequested(
phone: phone,
smsCode: smsCode,
));
}
Future<void> loadRememberCredentials() async {
final credentials = await storageService.getRememberCredentials();
if (isClosed) return;
if (credentials['phone'] != null) {
emit(state.copyWith(
rememberPassword: true,
savedPhone: credentials['phone'],
savedSmsCode: credentials['smsCode'],
));
}
}
void forgotPwd() {
// TODO: 跳转到忘记密码页面
}
@override
Future<void> close() {
_authSub?.cancel();
return super.close();
}
}
import 'package:equatable/equatable.dart';
class LoginState extends Equatable {
final bool rememberPassword;
final bool isLoading;
final String? error;
final String? savedPhone;
final String? savedSmsCode;
const LoginState({
this.rememberPassword = false,
this.isLoading = false,
this.error,
this.savedPhone,
this.savedSmsCode,
});
LoginState copyWith({
bool? rememberPassword,
bool? isLoading,
String? error,
String? savedPhone,
String? savedSmsCode,
}) {
return LoginState(
rememberPassword: rememberPassword ?? this.rememberPassword,
isLoading: isLoading ?? this.isLoading,
error: error,
savedPhone: savedPhone ?? this.savedPhone,
savedSmsCode: savedSmsCode ?? this.savedSmsCode,
);
}
@override
List<Object?> get props => [
rememberPassword,
isLoading,
error,
savedPhone,
savedSmsCode,
];
}
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:laki_icu_app/blocs/auth/auth_bloc.dart';
import 'package:laki_icu_app/blocs/auth/auth_state.dart';
import 'package:laki_icu_app/utils/storage/storage_service.dart';
import 'package:laki_icu_app/views/login/cubit/login_cubit.dart';
import 'package:laki_icu_app/views/login/cubit/login_state.dart';
import 'package:laki_icu_app/views/login/widget/btn_login.dart';
import 'package:laki_icu_app/views/login/widget/password_field.dart';
import 'package:laki_icu_app/views/login/widget/remember_password_row.dart';
import 'package:laki_icu_app/views/login/widget/username_field.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@RoutePage()
class LoginView extends StatelessWidget {
LoginView({super.key});
final _frmGlobalKey = GlobalKey<FormState>();
final _txtPhoneController = TextEditingController();
final _txtSmsCodeController = TextEditingController();
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
),
);
return BlocProvider(
create: (_) {
final cubit = LoginCubit(
authBloc: context.read<AuthBloc>(),
storageService: StorageService(),
);
cubit.loadRememberCredentials();
return cubit;
},
child: AnnotatedRegion<SystemUiOverlayStyle>(
value: const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
),
child: Scaffold(
backgroundColor: const Color(0xFFF5F7FA),
resizeToAvoidBottomInset: true,
body: SafeArea(
top: false,
child: Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.only(left: 50.w, right: 50.w),
decoration: const BoxDecoration(
color: Color(0xFFF5F7FA),
),
child: SingleChildScrollView(
child: BlocBuilder<LoginCubit, LoginState>(
builder: (context, state) {
final cubit = context.read<LoginCubit>();
if (state.savedPhone != null) {
_txtPhoneController.text = state.savedPhone!;
}
if (state.savedSmsCode != null) {
_txtSmsCodeController.text = state.savedSmsCode!;
}
return Column(
children: [
SizedBox(height: 150.h),
Container(
margin: EdgeInsets.only(bottom: 80.h),
child: Column(
children: [
Container(
width: 160.w,
height: 160.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40.w),
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF00C6FF),
Color(0xFF0072FF),
],
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(40.w),
child: Image.asset(
'lib/assets/login/logo@2x.png',
fit: BoxFit.cover,
),
),
),
SizedBox(height: 40.h),
const Text(
'Laki icu 智能仓',
style: TextStyle(
color: Color(0xFF333333),
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10.h),
const Text(
'Intelligent Hotel Management System',
style: TextStyle(
color: Color(0xFF999999),
fontSize: 14,
),
),
],
),
),
Form(
key: _frmGlobalKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
UsernameField(
controller: _txtPhoneController,
),
SizedBox(height: 20.h),
PasswordField(
controller: _txtSmsCodeController,
),
SizedBox(height: 30.h),
RememberPasswordRow(
value: state.rememberPassword,
onChanged: (val) {
cubit.toggleRememberPassword(val ?? false);
},
onForgotPassword: cubit.forgotPwd,
),
SizedBox(height: 10.h),
BlocConsumer<AuthBloc, AuthState>(
listener: (context, authState) {
if (authState is AuthFailure) {
Fluttertoast.showToast(
msg: authState.error,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
}
},
builder: (context, authState) {
return BtnLogin(
isLoading: authState is AuthLoading,
onPressed: () {
if (_frmGlobalKey.currentState!
.validate()) {
cubit.login(
phone: _txtPhoneController.text
.trim(),
smsCode:
_txtSmsCodeController.text.trim(),
rememberPassword:
state.rememberPassword,
);
}
},
);
},
),
],
),
),
],
);
},
),
),
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class BtnLogin extends StatelessWidget {
final bool isLoading;
final VoidCallback onPressed;
const BtnLogin({
super.key,
required this.isLoading,
required this.onPressed,
});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 104.h,
decoration: BoxDecoration(
color: Color.fromRGBO(73, 149, 234, 1),
borderRadius: BorderRadius.circular(40.w),
),
child: ElevatedButton(
onPressed: isLoading ? null : onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
elevation: 0,
),
child: isLoading
? SizedBox(
width: 40.w,
height: 40.w,
child: CircularProgressIndicator(
strokeWidth: 3.w,
color: Colors.white,
),
)
: Text(
"登录",
style: TextStyle(
color: Colors.white,
fontSize: 40.sp,
fontWeight: FontWeight.bold,
),
),
),
);
}
}
import 'package:flutter/material.dart';
class BtnReset extends StatelessWidget {
final VoidCallback onPressed;
const BtnReset({
super.key,
required this.onPressed,
});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 50,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(20),
),
child: TextButton(
onPressed: onPressed,
child: const Text(
"重置",
style: TextStyle(color: Colors.white),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class PasswordField extends StatefulWidget {
final TextEditingController controller;
const PasswordField({
super.key,
required this.controller,
});
@override
State<PasswordField> createState() => _PasswordFieldState();
}
class _PasswordFieldState extends State<PasswordField> {
bool _obscureText = true;
void _toggleVisibility() {
setState(() {
_obscureText = !_obscureText;
});
}
@override
Widget build(BuildContext context) {
return TextFormField(
controller: widget.controller,
obscureText: _obscureText,
style: TextStyle(color: Color(0xFF333333), fontSize: 28.sp),
validator: (val) {
if (val == null || val.isEmpty) {
return "密码不能为空";
}
return null;
},
decoration: InputDecoration(
filled: true,
hintText: "password",
hintStyle: TextStyle(color: Color(0xFF999999), fontSize: 28.sp),
prefixIcon: Icon(Icons.lock, color: Color(0xFF999999), size: 40.w),
prefixIconConstraints: BoxConstraints(minWidth: 80.w, minHeight: 80.w),
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility_off : Icons.visibility,
color: Color(0xFF999999),
size: 40.w,
),
onPressed: _toggleVisibility,
),
suffixIconConstraints: BoxConstraints(minWidth: 80.w, minHeight: 80.w),
contentPadding: EdgeInsets.symmetric(vertical: 20.h, horizontal: 24.w),
helperText: " ",
helperStyle: TextStyle(height: 1, fontSize: 24.sp),
errorStyle: TextStyle(color: Colors.red, fontSize: 24.sp, height: 1),
errorMaxLines: 1,
fillColor: Colors.white,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Color(0xFFF5F7FA), width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Color(0xFFF5F7FA), width: 1),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Colors.red, width: 1),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Colors.red, width: 1.5),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class RememberPasswordRow extends StatelessWidget {
final bool value;
final ValueChanged<bool?> onChanged;
final VoidCallback onForgotPassword;
const RememberPasswordRow({
super.key,
required this.value,
required this.onChanged,
required this.onForgotPassword,
});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
alignment: Alignment.center,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 40.w,
height: 40.w,
child: Transform.scale(
scale: 0.8,
child: Checkbox(
value: value,
onChanged: onChanged,
activeColor: Color(0xFF4A90E2),
checkColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.w),
),
side: BorderSide(color: Color(0xFF4A90E2)),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
),
),
SizedBox(width: 10.w),
Text(
'记住密码',
style: TextStyle(
color: Color(0xFF0A0D14),
fontSize: 24.sp,
),
),
],
),
),
GestureDetector(
onTap: onForgotPassword,
child: Text(
'忘记密码?',
style: TextStyle(
color: Color(0xFF0A0D14),
fontSize: 24.sp,
),
),
),
],
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class UsernameField extends StatelessWidget {
final TextEditingController controller;
const UsernameField({
super.key,
required this.controller,
});
@override
Widget build(BuildContext context) {
return TextFormField(
controller: controller,
style: TextStyle(color: Color(0xFF333333), fontSize: 28.sp),
validator: (val) {
if (val == null || val.isEmpty) {
return "用户名不能为空哦";
}
return null;
},
decoration: InputDecoration(
filled: true,
hintText: "admin",
hintStyle: TextStyle(color: Color(0xFF999999), fontSize: 28.sp),
prefixIcon: Icon(Icons.person, color: Color(0xFF999999), size: 40.w),
prefixIconConstraints: BoxConstraints(minWidth: 80.w, minHeight: 80.w),
contentPadding: EdgeInsets.symmetric(vertical: 20.h, horizontal: 24.w),
helperText: " ",
helperStyle: TextStyle(height: 1, fontSize: 24.sp),
errorStyle: TextStyle(color: Colors.red, fontSize: 24.sp, height: 1),
errorMaxLines: 1,
fillColor: Colors.white,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Color(0xFFF5F7FA), width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Color(0xFFF5F7FA), width: 1),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Colors.red, width: 1),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(24.w),
borderSide: BorderSide(color: Colors.red, width: 1),
),
),
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment