mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-16 01:56:19 +00:00
Redesigned Splash Screen and Login Screen
This commit is contained in:
@ -1,19 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
|
||||||
import 'package:syncrow_app/features/auth/view/widgets/auth_view_body.dart';
|
|
||||||
|
|
||||||
class AuthView extends StatelessWidget {
|
|
||||||
const AuthView({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocBuilder<AuthCubit, AuthState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return const Scaffold(
|
|
||||||
body: AuthViewBody(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
|
||||||
import 'package:syncrow_app/features/shared_widgets/syncrow_logo.dart';
|
|
||||||
|
|
||||||
import '../../../../navigation/routing_constants.dart';
|
|
||||||
|
|
||||||
class AuthViewBody extends StatelessWidget {
|
|
||||||
const AuthViewBody({
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 40.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
const Expanded(child: SizedBox()),
|
|
||||||
const SyncrowLogo(),
|
|
||||||
const Expanded(flex: 2, child: SizedBox()),
|
|
||||||
DefaultButton(
|
|
||||||
text: 'Login',
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pushNamed(context, Routes.authLogin);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
const DefaultButton(
|
|
||||||
text: 'Sign Up',
|
|
||||||
isSecondary: true,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,39 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||||
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
|
class DontHaveAnAccount extends StatelessWidget {
|
||||||
|
const DontHaveAnAccount({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 30),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
BodyLarge(
|
||||||
|
text: "Don't have an account?",
|
||||||
|
style: context.displaySmall.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pushNamed(context, Routes.authSignUp);
|
||||||
|
},
|
||||||
|
child: BodyLarge(
|
||||||
|
text: "Sign Up",
|
||||||
|
style: context.displaySmall.copyWith(
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontsManager.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
29
lib/features/auth/view/widgets/login/forget_password.dart
Normal file
29
lib/features/auth/view/widgets/login/forget_password.dart
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
|
||||||
|
class ForgetPassword extends StatelessWidget {
|
||||||
|
const ForgetPassword({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
const Spacer(),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
//TODO Navigate to forgot password
|
||||||
|
},
|
||||||
|
child: BodyMedium(
|
||||||
|
text: "Forgot Password?",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -17,23 +17,19 @@ class LoginButton extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
enabled: AuthCubit.get(context).agreeToTerms,
|
isDone: state is AuthSuccess,
|
||||||
text: state is AuthLoading
|
isLoading: state is AuthLoading,
|
||||||
? null
|
customButtonStyle: ButtonStyle(
|
||||||
: state is AuthSuccess
|
backgroundColor: MaterialStateProperty.all(
|
||||||
? null
|
Colors.black.withOpacity(.25),
|
||||||
: "Login",
|
),
|
||||||
child: state is AuthSuccess
|
foregroundColor: MaterialStateProperty.all(
|
||||||
? const Icon(
|
Colors.white,
|
||||||
Icons.check_circle_outline,
|
),
|
||||||
color: Colors.white,
|
),
|
||||||
)
|
child: const Text(
|
||||||
: const SizedBox.square(
|
'Login',
|
||||||
dimension: 20,
|
),
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (AuthCubit.get(context).formKey.currentState!.validate()) {
|
if (AuthCubit.get(context).formKey.currentState!.validate()) {
|
||||||
AuthCubit.get(context).login();
|
AuthCubit.get(context).login();
|
||||||
|
38
lib/features/auth/view/widgets/login/login_divider.dart
Normal file
38
lib/features/auth/view/widgets/login/login_divider.dart
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
|
||||||
|
class LoginDivider extends StatelessWidget {
|
||||||
|
const LoginDivider({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return const Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 20),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Divider(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
child: BodyMedium(
|
||||||
|
text: "or Sign in with",
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Divider(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/styles_manager.dart';
|
||||||
|
|
||||||
class LoginForm extends StatelessWidget {
|
class LoginForm extends StatelessWidget {
|
||||||
const LoginForm({
|
const LoginForm({
|
||||||
@ -14,77 +15,64 @@ class LoginForm extends StatelessWidget {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return Form(
|
return Form(
|
||||||
key: AuthCubit.get(context).formKey,
|
key: AuthCubit.get(context).formKey,
|
||||||
child: Column(
|
child: SingleChildScrollView(
|
||||||
children: [
|
child: Column(
|
||||||
TextFormField(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
controller: AuthCubit.get(context).emailController,
|
children: [
|
||||||
validator: (value) {
|
const BodyMedium(
|
||||||
if (value != null) {
|
text: "Email",
|
||||||
if (value.isEmpty) {
|
fontColor: Colors.white,
|
||||||
return 'Please enter your email';
|
|
||||||
}
|
|
||||||
//Regex for email validation
|
|
||||||
if (!RegExp(
|
|
||||||
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$')
|
|
||||||
.hasMatch(value)) {
|
|
||||||
return 'Please enter a valid email';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
onTapOutside: (event) {
|
|
||||||
AuthCubit.get(context).formKey.currentState!.validate();
|
|
||||||
},
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'Email',
|
|
||||||
enabledBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide.none,
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
filled: true,
|
|
||||||
fillColor: ColorsManager.backgroundColor.withAlpha(100),
|
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
|
||||||
contentPadding: const EdgeInsets.all(10),
|
|
||||||
),
|
),
|
||||||
),
|
TextFormField(
|
||||||
const SizedBox(height: 10),
|
controller: AuthCubit.get(context).emailController,
|
||||||
TextFormField(
|
validator: (value) {
|
||||||
controller: AuthCubit.get(context).passwordController,
|
if (value != null) {
|
||||||
validator: (value) {
|
if (value.isEmpty) {
|
||||||
if (value != null) {
|
return 'Please enter your email';
|
||||||
if (value.isEmpty) {
|
}
|
||||||
return 'Please enter your password';
|
//Regex for email validation
|
||||||
|
if (!RegExp(
|
||||||
|
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$')
|
||||||
|
.hasMatch(value)) {
|
||||||
|
return 'Please enter a valid email';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return null;
|
||||||
return null;
|
},
|
||||||
},
|
onTapOutside: (event) {
|
||||||
onTapOutside: (event) {
|
AuthCubit.get(context).formKey.currentState!.validate();
|
||||||
AuthCubit.get(context).formKey.currentState!.validate();
|
},
|
||||||
},
|
decoration: defaultInputDecoration(context,
|
||||||
obscureText: !AuthCubit.get(context).isPasswordVisible,
|
hint: "Example@email.com"),
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'Password',
|
|
||||||
enabledBorder: OutlineInputBorder(
|
|
||||||
borderSide: BorderSide.none,
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
AuthCubit.get(context).isPasswordVisible
|
|
||||||
? Icons.visibility
|
|
||||||
: Icons.visibility_off,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
AuthCubit.get(context).changePasswordVisibility();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
filled: true,
|
|
||||||
fillColor: ColorsManager.backgroundColor.withAlpha(100),
|
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
|
||||||
contentPadding: const EdgeInsets.all(10),
|
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 10),
|
||||||
],
|
const BodyMedium(
|
||||||
|
text: "Password",
|
||||||
|
fontColor: Colors.white,
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
controller: AuthCubit.get(context).passwordController,
|
||||||
|
validator: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
if (value.isNotEmpty) {
|
||||||
|
if (value.length < 6) {
|
||||||
|
return 'Password must be at least 8 characters';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 'Please enter your password';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
onTapOutside: (event) {
|
||||||
|
AuthCubit.get(context).formKey.currentState!.validate();
|
||||||
|
},
|
||||||
|
obscureText: !AuthCubit.get(context).isPasswordVisible,
|
||||||
|
decoration: defaultInputDecoration(context,
|
||||||
|
hint: "At least 8 characters"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||||
|
import 'package:syncrow_app/features/auth/view/widgets/login/dont_have_an_account.dart';
|
||||||
|
import 'package:syncrow_app/features/auth/view/widgets/login/forget_password.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/widgets/login/login_button.dart';
|
import 'package:syncrow_app/features/auth/view/widgets/login/login_button.dart';
|
||||||
|
import 'package:syncrow_app/features/auth/view/widgets/login/login_divider.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/widgets/login/login_form.dart';
|
import 'package:syncrow_app/features/auth/view/widgets/login/login_form.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/widgets/login/login_user_agreement.dart';
|
import 'package:syncrow_app/features/auth/view/widgets/login/login_with_google_facebook.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||||
|
|
||||||
class LoginView extends StatelessWidget {
|
class LoginView extends StatelessWidget {
|
||||||
const LoginView({super.key});
|
const LoginView({super.key});
|
||||||
@ -29,28 +36,79 @@ class LoginView extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(),
|
body: Stack(
|
||||||
body: const Padding(
|
children: [
|
||||||
padding: EdgeInsets.symmetric(
|
Container(
|
||||||
horizontal: Constants.defaultPadding,
|
width: MediaQuery.sizeOf(context).width,
|
||||||
),
|
height: MediaQuery.sizeOf(context).height,
|
||||||
child: Column(
|
decoration: const BoxDecoration(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
image: DecorationImage(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
image: AssetImage(
|
||||||
children: [
|
Assets.imagesBackground,
|
||||||
TitleMedium(
|
),
|
||||||
text: 'Login',
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
),
|
||||||
height: 10,
|
Container(
|
||||||
|
width: MediaQuery.sizeOf(context).width,
|
||||||
|
height: MediaQuery.sizeOf(context).height,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(Assets.imagesVector),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.9,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
LoginForm(),
|
),
|
||||||
SizedBox(height: 10),
|
Padding(
|
||||||
LoginUserAgreement(),
|
padding: const EdgeInsets.symmetric(
|
||||||
SizedBox(height: 10),
|
horizontal: Constants.defaultPadding,
|
||||||
LoginButton(),
|
),
|
||||||
],
|
child: SingleChildScrollView(
|
||||||
),
|
child: SizedBox(
|
||||||
|
width: MediaQuery.sizeOf(context).width,
|
||||||
|
height: MediaQuery.sizeOf(context).height,
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.imagesLogo,
|
||||||
|
width: 160,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 40,
|
||||||
|
),
|
||||||
|
TitleMedium(
|
||||||
|
text: 'Login',
|
||||||
|
style: context.titleMedium.copyWith(
|
||||||
|
fontWeight: FontsManager.extraBold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
const LoginForm(),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
// const LoginUserAgreement(),
|
||||||
|
const ForgetPassword(),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
const LoginButton(),
|
||||||
|
const LoginDivider(),
|
||||||
|
const LoginWithGoogleFacebook(),
|
||||||
|
const DontHaveAnAccount(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||||
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
|
||||||
|
class LoginWithGoogleFacebook extends StatelessWidget {
|
||||||
|
const LoginWithGoogleFacebook({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: DefaultContainer(
|
||||||
|
child: SizedBox.square(
|
||||||
|
dimension: 24,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(Assets.iconsGoogle),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
BodyMedium(
|
||||||
|
text: "Google",
|
||||||
|
style: context.bodyMedium.copyWith(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: DefaultContainer(
|
||||||
|
child: SizedBox.square(
|
||||||
|
dimension: 24,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(Assets.iconsFacebook),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
BodyMedium(
|
||||||
|
text: "Facebook",
|
||||||
|
style: context.bodyMedium.copyWith(color: Colors.black),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,9 @@ class NoDevicesView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
const DefaultButton(
|
const DefaultButton(
|
||||||
text: 'Add Device',
|
child: Text(
|
||||||
|
'Add Device',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -29,7 +29,9 @@ class SceneViewNoScenes extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
const DefaultButton(
|
const DefaultButton(
|
||||||
text: 'Create Scene',
|
child: Text(
|
||||||
|
'Add a scene',
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class DefaultButton extends StatelessWidget {
|
class DefaultButton extends StatelessWidget {
|
||||||
@ -6,46 +7,84 @@ class DefaultButton extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
this.enabled = true,
|
this.enabled = true,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
this.child,
|
required this.child,
|
||||||
this.isSecondary = false,
|
this.isSecondary = false,
|
||||||
this.text,
|
this.isLoading = false,
|
||||||
|
this.isDone = false,
|
||||||
|
this.customTextStyle,
|
||||||
|
this.customButtonStyle,
|
||||||
});
|
});
|
||||||
|
|
||||||
final void Function()? onPressed;
|
final void Function()? onPressed;
|
||||||
final Widget? child;
|
final Widget child;
|
||||||
|
|
||||||
final String? text;
|
|
||||||
final bool isSecondary;
|
final bool isSecondary;
|
||||||
|
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
|
|
||||||
|
final bool isDone;
|
||||||
|
final bool isLoading;
|
||||||
|
|
||||||
|
final TextStyle? customTextStyle;
|
||||||
|
|
||||||
|
final ButtonStyle? customButtonStyle;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
onPressed: enabled ? onPressed : null,
|
onPressed: enabled ? onPressed : null,
|
||||||
style: isSecondary
|
style: isSecondary
|
||||||
? null
|
? null
|
||||||
: ButtonStyle(
|
: customButtonStyle ??
|
||||||
backgroundColor: MaterialStateProperty.all(
|
ButtonStyle(
|
||||||
enabled ? ColorsManager.primaryColor : Colors.grey),
|
textStyle: MaterialStateProperty.all(
|
||||||
shape: MaterialStateProperty.all(
|
customTextStyle ??
|
||||||
RoundedRectangleBorder(
|
context.bodyMedium.copyWith(
|
||||||
borderRadius: BorderRadius.circular(8),
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
foregroundColor: MaterialStateProperty.all(
|
||||||
|
isSecondary
|
||||||
|
? Colors.black
|
||||||
|
: enabled
|
||||||
|
? Colors.white
|
||||||
|
: Colors.black,
|
||||||
|
),
|
||||||
|
backgroundColor: MaterialStateProperty.all(
|
||||||
|
enabled ? ColorsManager.primaryColor : Colors.grey),
|
||||||
|
shape: MaterialStateProperty.all(
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
fixedSize: MaterialStateProperty.all(
|
||||||
|
const Size.fromHeight(50),
|
||||||
|
),
|
||||||
|
padding: MaterialStateProperty.all(
|
||||||
|
const EdgeInsets.all(10),
|
||||||
|
),
|
||||||
|
minimumSize: MaterialStateProperty.all(
|
||||||
|
const Size.fromHeight(50),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
child: SizedBox(
|
||||||
child: text != null
|
height: 50,
|
||||||
? Text(
|
child: Center(
|
||||||
text!,
|
child: isLoading
|
||||||
style: TextStyle(
|
? const SizedBox.square(
|
||||||
color: isSecondary
|
dimension: 24,
|
||||||
? Colors.black
|
child: CircularProgressIndicator(
|
||||||
: enabled
|
color: Colors.white,
|
||||||
? Colors.white
|
),
|
||||||
: Colors.black,
|
)
|
||||||
),
|
: isDone
|
||||||
)
|
? const Icon(
|
||||||
: child,
|
Icons.check_circle_outline,
|
||||||
|
color: Colors.white,
|
||||||
|
)
|
||||||
|
: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_app/features/splash/view/widgets/user_agreement_dialog.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||||
|
|
||||||
@ -10,25 +10,46 @@ class SplashView extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
//TODO remove this delay
|
//TODO remove this delay
|
||||||
Future.delayed(
|
Future.delayed(
|
||||||
const Duration(seconds: 3),
|
const Duration(seconds: 5),
|
||||||
() {
|
() {
|
||||||
Navigator.popAndPushNamed(
|
Navigator.popAndPushNamed(
|
||||||
context,
|
context,
|
||||||
Routes.authRoute,
|
Routes.authLogin,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: Stack(
|
||||||
child: InkWell(
|
alignment: Alignment.center,
|
||||||
//TODO check if user agreement is accepted
|
children: [
|
||||||
onTap: () {
|
Container(
|
||||||
showDialog(
|
width: MediaQuery.sizeOf(context).width,
|
||||||
context: context,
|
height: MediaQuery.sizeOf(context).height,
|
||||||
builder: (context) => const UserAgreementDialog(),
|
decoration: const BoxDecoration(
|
||||||
);
|
image: DecorationImage(
|
||||||
},
|
image: AssetImage(
|
||||||
child: Image.asset(Assets.imagesBlackLogo)),
|
Assets.imagesBackground,
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.sizeOf(context).width,
|
||||||
|
height: MediaQuery.sizeOf(context).height,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(Assets.imagesVector),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.9,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.imagesLogo,
|
||||||
|
width: 240,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,19 @@ class UserAgreementDialog extends StatelessWidget {
|
|||||||
const Text('By using this app you agree to the terms and conditions'),
|
const Text('By using this app you agree to the terms and conditions'),
|
||||||
actions: [
|
actions: [
|
||||||
DefaultButton(
|
DefaultButton(
|
||||||
text: 'I Agree',
|
child: const Text(
|
||||||
|
'Login',
|
||||||
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
DefaultButton(
|
DefaultButton(
|
||||||
text: 'I Disagree',
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
isSecondary: true,
|
isSecondary: true,
|
||||||
|
child: const Text(
|
||||||
|
'Cancel',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -15,12 +15,14 @@ class Assets {
|
|||||||
static const String iconsDevices = 'assets/icons/Devices.svg';
|
static const String iconsDevices = 'assets/icons/Devices.svg';
|
||||||
static const String iconsDevicesFill = 'assets/icons/Devices-fill.svg';
|
static const String iconsDevicesFill = 'assets/icons/Devices-fill.svg';
|
||||||
static const String iconsDoorLock = 'assets/icons/doorLock.svg';
|
static const String iconsDoorLock = 'assets/icons/doorLock.svg';
|
||||||
|
static const String iconsFacebook = 'assets/icons/Facebook.svg';
|
||||||
static const String iconsFan0 = 'assets/icons/fan-0.svg';
|
static const String iconsFan0 = 'assets/icons/fan-0.svg';
|
||||||
static const String iconsFan1 = 'assets/icons/fan-1.svg';
|
static const String iconsFan1 = 'assets/icons/fan-1.svg';
|
||||||
static const String iconsFan2 = 'assets/icons/fan-2.svg';
|
static const String iconsFan2 = 'assets/icons/fan-2.svg';
|
||||||
static const String iconsFan3 = 'assets/icons/fan-3.svg';
|
static const String iconsFan3 = 'assets/icons/fan-3.svg';
|
||||||
static const String iconsFrequency = 'assets/icons/frequency.svg';
|
static const String iconsFrequency = 'assets/icons/frequency.svg';
|
||||||
static const String iconsGateway = 'assets/icons/Gateway.svg';
|
static const String iconsGateway = 'assets/icons/Gateway.svg';
|
||||||
|
static const String iconsGoogle = 'assets/icons/Google.svg';
|
||||||
static const String iconsHome = 'assets/icons/home.svg';
|
static const String iconsHome = 'assets/icons/home.svg';
|
||||||
static const String iconsHot1 = 'assets/icons/hot1.jpg';
|
static const String iconsHot1 = 'assets/icons/hot1.jpg';
|
||||||
static const String iconsKalvin = 'assets/icons/kalvin.svg';
|
static const String iconsKalvin = 'assets/icons/kalvin.svg';
|
||||||
@ -51,7 +53,9 @@ class Assets {
|
|||||||
static const String imagesBackground = 'assets/images/Background.png';
|
static const String imagesBackground = 'assets/images/Background.png';
|
||||||
static const String imagesBlackLogo = 'assets/images/black-logo.png';
|
static const String imagesBlackLogo = 'assets/images/black-logo.png';
|
||||||
static const String imagesBoxEmpty = 'assets/images/box-empty.jpg';
|
static const String imagesBoxEmpty = 'assets/images/box-empty.jpg';
|
||||||
|
static const String imagesLogo = 'assets/images/Logo.svg';
|
||||||
static const String imagesTestDash = 'assets/images/test_dash.png';
|
static const String imagesTestDash = 'assets/images/test_dash.png';
|
||||||
static const String imagesTestDash2 = 'assets/images/test_dash2.png';
|
static const String imagesTestDash2 = 'assets/images/test_dash2.png';
|
||||||
|
static const String imagesVector = 'assets/images/Vector.png';
|
||||||
static const String imagesWhiteLogo = 'assets/images/white-logo.png';
|
static const String imagesWhiteLogo = 'assets/images/white-logo.png';
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_app/features/app_layout/view/app_layout.dart';
|
import 'package:syncrow_app/features/app_layout/view/app_layout.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/auth_view.dart';
|
|
||||||
import 'package:syncrow_app/features/auth/view/widgets/didnt_get_code/didnt_get_code_view.dart';
|
import 'package:syncrow_app/features/auth/view/widgets/didnt_get_code/didnt_get_code_view.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/widgets/login/login_view.dart';
|
import 'package:syncrow_app/features/auth/view/widgets/login/login_view.dart';
|
||||||
import 'package:syncrow_app/features/auth/view/widgets/one_time_password/one_time_password_view.dart';
|
import 'package:syncrow_app/features/auth/view/widgets/one_time_password/one_time_password_view.dart';
|
||||||
@ -39,10 +38,6 @@ class Router {
|
|||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => const LayoutPage(), settings: settings);
|
builder: (_) => const LayoutPage(), settings: settings);
|
||||||
|
|
||||||
case Routes.authRoute:
|
|
||||||
return MaterialPageRoute(
|
|
||||||
builder: (_) => const AuthView(), settings: settings);
|
|
||||||
|
|
||||||
case Routes.authLogin:
|
case Routes.authLogin:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => const LoginView(), settings: settings);
|
builder: (_) => const LoginView(), settings: settings);
|
||||||
|
@ -10,6 +10,9 @@ extension ContextExtension on BuildContext {
|
|||||||
|
|
||||||
double get height => MediaQuery.sizeOf(this).height;
|
double get height => MediaQuery.sizeOf(this).height;
|
||||||
|
|
||||||
|
InputDecorationTheme get inputDecoration =>
|
||||||
|
Theme.of(this).inputDecorationTheme;
|
||||||
|
|
||||||
TextStyle get displayLarge => Theme.of(this).textTheme.displayLarge!;
|
TextStyle get displayLarge => Theme.of(this).textTheme.displayLarge!;
|
||||||
|
|
||||||
TextStyle get displayMedium => Theme.of(this).textTheme.displayMedium!;
|
TextStyle get displayMedium => Theme.of(this).textTheme.displayMedium!;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_app/utils/context_extension.dart';
|
||||||
|
|
||||||
import 'font_manager.dart';
|
import 'font_manager.dart';
|
||||||
|
|
||||||
@ -85,3 +86,18 @@ TextStyle getTextStyleExtraBold({
|
|||||||
color: color,
|
color: color,
|
||||||
fontWeight: fontWeight,
|
fontWeight: fontWeight,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
///inputDecoration
|
||||||
|
|
||||||
|
InputDecoration defaultInputDecoration(BuildContext context, {String? hint}) =>
|
||||||
|
InputDecoration(
|
||||||
|
enabledBorder: context.inputDecoration.enabledBorder,
|
||||||
|
focusedBorder: context.inputDecoration.enabledBorder,
|
||||||
|
errorBorder: context.inputDecoration.errorBorder,
|
||||||
|
focusedErrorBorder: context.inputDecoration.enabledBorder,
|
||||||
|
hintText: hint,
|
||||||
|
hintStyle: context.inputDecoration.hintStyle,
|
||||||
|
filled: context.inputDecoration.filled,
|
||||||
|
fillColor: context.inputDecoration.fillColor,
|
||||||
|
contentPadding: context.inputDecoration.contentPadding,
|
||||||
|
);
|
||||||
|
@ -141,19 +141,32 @@ abstract class ThemeManager {
|
|||||||
// ),
|
// ),
|
||||||
|
|
||||||
///input decoration theme
|
///input decoration theme
|
||||||
inputDecorationTheme: const InputDecorationTheme(
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
|
||||||
),
|
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: Colors.grey),
|
borderSide: BorderSide.none,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: ColorsManager.primaryColor),
|
borderSide: BorderSide.none,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
labelStyle: TextStyle(
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: const BorderSide(color: Colors.red)),
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
fontFamily: FontsManager.fontFamily,
|
||||||
|
fontSize: FontSize.s14,
|
||||||
|
fontWeight: FontsManager.regular,
|
||||||
|
color: ColorsManager.textPrimaryColor,
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
contentPadding: const EdgeInsets.all(10),
|
||||||
|
labelStyle: const TextStyle(
|
||||||
fontFamily: FontsManager.fontFamily,
|
fontFamily: FontsManager.fontFamily,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
fontSize: FontSize.s16,
|
fontSize: FontSize.s16,
|
||||||
|
Reference in New Issue
Block a user