mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-10-23 11:37:56 +00:00
Added create a unit screen, and implemented otp screen bloc and view
This commit is contained in:
@@ -22,6 +22,7 @@ import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/navigation/navigation_service.dart';
|
||||
import 'package:syncrow_app/services/api/spaces_api.dart';
|
||||
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
|
||||
@@ -198,7 +199,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
try {
|
||||
spaces = await SpacesAPI.getUnitsByUserId();
|
||||
} catch (failure) {
|
||||
emitSafe(GetSpacesError(failure.toString()));
|
||||
emitSafe(GetSpacesError("No units found"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,6 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
final TextEditingController emailController = TextEditingController();
|
||||
final TextEditingController passwordController = TextEditingController();
|
||||
|
||||
// final TextEditingController emailSignUpController = TextEditingController();
|
||||
// final TextEditingController fullNameController = TextEditingController();
|
||||
// final TextEditingController passwordSignUpController = TextEditingController();
|
||||
// final TextEditingController reEnterPasswordSignUpController = TextEditingController();
|
||||
|
||||
String fullName = '';
|
||||
String email = '';
|
||||
String signUpPassword = '';
|
||||
@@ -51,6 +46,10 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
|
||||
static Token token = Token.emptyConstructor();
|
||||
|
||||
setOtpCode(String value) {
|
||||
otpCode = value;
|
||||
}
|
||||
|
||||
/////////////////////////////////////VALIDATORS/////////////////////////////////////
|
||||
String? passwordValidator(String? value) {
|
||||
if (value != null) {
|
||||
@@ -64,9 +63,6 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (signUpFormKey.currentState != null) {
|
||||
signUpFormKey.currentState!.save();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -94,19 +90,16 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
if (parts.any((part) => part.length < 2 || part.length > 30)) {
|
||||
return 'Full name parts must be between 2 and 30 characters long';
|
||||
}
|
||||
if (signUpFormKey.currentState != null) {
|
||||
signUpFormKey.currentState!.save();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String reEnterPasswordCheck(String? value) {
|
||||
String? reEnterPasswordCheck(String? value) {
|
||||
passwordValidator(value);
|
||||
if (signUpPassword == value) {
|
||||
if (signUpFormKey.currentState != null) {
|
||||
signUpFormKey.currentState!.save();
|
||||
}
|
||||
return '';
|
||||
// if (signUpFormKey.currentState != null) {
|
||||
// signUpFormKey.currentState!.save();
|
||||
// }
|
||||
return null;
|
||||
} else {
|
||||
return 'Passwords do not match';
|
||||
}
|
||||
@@ -115,9 +108,6 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
String? emailAddressValidator(String? value) {
|
||||
if (value != null && value.isNotEmpty && value != "") {
|
||||
if (checkValidityOfEmail(value)) {
|
||||
if (signUpFormKey.currentState != null) {
|
||||
signUpFormKey.currentState!.save();
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return 'Please enter a valid email';
|
||||
@@ -204,14 +194,47 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
}
|
||||
if (response) {
|
||||
maskedEmail = maskEmail(email);
|
||||
final response = await AuthenticationAPI.sendOtp(body: {'email': email, 'type': 'PASSWORD'});
|
||||
otpCode = response['otp'];
|
||||
emit(AuthSignUpSuccess());
|
||||
await sendOtp();
|
||||
} else {
|
||||
emit(AuthLoginError(message: 'Something went wrong'));
|
||||
}
|
||||
}
|
||||
|
||||
sendOtp() async {
|
||||
try {
|
||||
final response =
|
||||
await AuthenticationAPI.sendOtp(body: {'email': email, 'type': 'VERIFICATION'});
|
||||
// otpCode = response['otp'];
|
||||
emit(AuthSignUpSuccess());
|
||||
} catch (_) {
|
||||
emit(AuthLoginError(message: 'Something went wrong'));
|
||||
}
|
||||
}
|
||||
|
||||
verifyOtp() async {
|
||||
emit(AuthLoginLoading());
|
||||
try {
|
||||
final response = await AuthenticationAPI.verifyPassCode(
|
||||
body: {'email': email, 'type': 'VERIFICATION', 'otpCode': otpCode});
|
||||
if (response['statusCode'] == 200) {
|
||||
emailController.text = email;
|
||||
passwordController.text = signUpPassword;
|
||||
await login();
|
||||
emit(AuthOtpSuccess());
|
||||
} else {
|
||||
emit(AuthLoginError(message: 'Something went wrong'));
|
||||
}
|
||||
// if (otpCode == '654321') {
|
||||
// emit(AuthOtpSuccess());
|
||||
// } else {
|
||||
// emit(AuthLoginError(message: 'Otp is not correct'));
|
||||
// }
|
||||
} catch (failure) {
|
||||
emit(AuthLoginError(message: failure.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
logout() async {
|
||||
emit(AuthLogoutLoading());
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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';
|
||||
@@ -18,6 +19,8 @@ class LoginView extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
||||
statusBarBrightness: Brightness.light, statusBarIconBrightness: Brightness.light));
|
||||
return BlocConsumer<AuthCubit, AuthState>(
|
||||
listener: (context, state) {
|
||||
if (state is AuthError) {
|
||||
@@ -31,9 +34,9 @@ class LoginView extends StatelessWidget {
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: Stack(
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:pin_code_fields/pin_code_fields.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_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/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/constants.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/styles_manager.dart';
|
||||
|
||||
class OtpView extends StatelessWidget {
|
||||
const OtpView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final formKey = AuthCubit.get(context).signUpFormKey;
|
||||
String maskedEmail = AuthCubit.get(context).maskEmail(AuthCubit.get(context).email);
|
||||
return BlocConsumer<AuthCubit, AuthState>(
|
||||
listener: (context, state) {
|
||||
if (state is AuthError) {
|
||||
} else if (state is AuthOtpSuccess) {
|
||||
Navigator.popAndPushNamed(context, Routes.homeRoute);
|
||||
if (state is AuthOtpSuccess) {
|
||||
Navigator.pushNamedAndRemoveUntil(context, Routes.homeRoute, (value) => false);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: Stack(
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
@@ -96,7 +94,7 @@ class OtpView extends StatelessWidget {
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' ex******[email protected]',
|
||||
text: ' $maskedEmail',
|
||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontsManager.bold,
|
||||
@@ -116,20 +114,19 @@ class OtpView extends StatelessWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
),
|
||||
PinCodeTextField(
|
||||
key: const Key('pin_code_text_field'),
|
||||
appContext: context,
|
||||
length: 4,
|
||||
length: 6,
|
||||
obscuringCharacter: '-',
|
||||
cursorHeight: 25,
|
||||
backgroundColor: Colors.transparent,
|
||||
keyboardType: TextInputType.number,
|
||||
autoFocus: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
animationDuration: const Duration(milliseconds: 30),
|
||||
// controller: AuthCubit.get(context).emailController,
|
||||
// cursorColor: KeysperColors.primaryBase,
|
||||
beforeTextPaste: (text) {
|
||||
// Allow pasting only if all characters are numeric
|
||||
return int.tryParse(text!) != null;
|
||||
@@ -137,11 +134,11 @@ class OtpView extends StatelessWidget {
|
||||
textStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineMedium!
|
||||
.copyWith(color: Colors.black),
|
||||
.copyWith(color: Colors.white),
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineMedium!
|
||||
.copyWith(color: Colors.grey),
|
||||
.copyWith(color: Colors.white),
|
||||
enablePinAutofill: true,
|
||||
pinTheme: PinTheme(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@@ -152,24 +149,28 @@ class OtpView extends StatelessWidget {
|
||||
errorBorderWidth: 1,
|
||||
borderWidth: 1,
|
||||
errorBorderColor: Colors.red,
|
||||
activeColor: Colors.white,
|
||||
inactiveColor: Colors.white,
|
||||
activeFillColor: Colors.white,
|
||||
inactiveFillColor: Colors.white,
|
||||
selectedFillColor: Colors.white,
|
||||
activeColor: state is AuthLoginError ? Colors.red : Colors.white,
|
||||
inactiveColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
activeFillColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
inactiveFillColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
selectedFillColor:
|
||||
state is AuthLoginError ? Colors.red : Colors.white,
|
||||
disabledColor: Colors.white,
|
||||
fieldHeight: 50,
|
||||
fieldWidth: 50,
|
||||
fieldHeight: 56,
|
||||
fieldWidth: MediaQuery.sizeOf(context).width > 340 ? 40 : 20,
|
||||
// fieldWidth: 40,
|
||||
selectedColor: Colors.white,
|
||||
shape: PinCodeFieldShape.box,
|
||||
),
|
||||
onChanged: (value) async {
|
||||
// otpCode = value;
|
||||
// await bloc.onOTPChanged(value);
|
||||
onChanged: (value) {
|
||||
AuthCubit.get(context).setOtpCode(value);
|
||||
},
|
||||
onCompleted: (value) {},
|
||||
onSubmitted: (value) async {
|
||||
// await bloc.onOTPSubmitted();
|
||||
onSubmitted: (value) {
|
||||
// AuthCubit.get(context).setOtpCode(value);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
@@ -192,11 +193,35 @@ class OtpView extends StatelessWidget {
|
||||
'Verify',
|
||||
),
|
||||
onPressed: () {
|
||||
if (formKey.currentState!.validate()) {
|
||||
if ((state is! AuthLoading)) {
|
||||
AuthCubit.get(context).signUp();
|
||||
FocusScope.of(context).unfocus();
|
||||
}
|
||||
if ((state is! AuthLoading)) {
|
||||
AuthCubit.get(context).verifyOtp();
|
||||
FocusScope.of(context).unfocus();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Expanded(
|
||||
child: DefaultButton(
|
||||
isDone: state is AuthLoginSuccess,
|
||||
isLoading: state is AuthLoading,
|
||||
customButtonStyle: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
Colors.black.withOpacity(.25),
|
||||
),
|
||||
foregroundColor: MaterialStateProperty.all(
|
||||
Colors.white,
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
'Resend',
|
||||
),
|
||||
onPressed: () async {
|
||||
if ((state is! AuthLoading)) {
|
||||
await AuthCubit.get(context).sendOtp();
|
||||
FocusScope.of(context).unfocus();
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/auth/view/widgets/login_form.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_button.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||
@@ -26,13 +25,14 @@ class SignUpView extends StatelessWidget {
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: Stack(
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
padding: const EdgeInsets.symmetric(vertical: 24),
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
@@ -86,6 +86,7 @@ class SignUpView extends StatelessWidget {
|
||||
),
|
||||
Form(
|
||||
key: formKey,
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -95,7 +96,7 @@ class SignUpView extends StatelessWidget {
|
||||
fontColor: Colors.white,
|
||||
),
|
||||
TextFormField(
|
||||
// autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
textInputAction: TextInputAction.done,
|
||||
keyboardType: TextInputType.name,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
@@ -109,6 +110,7 @@ class SignUpView extends StatelessWidget {
|
||||
onChanged: (value) {
|
||||
AuthCubit.get(context).fullName = value;
|
||||
},
|
||||
onTap: () {},
|
||||
decoration: defaultInputDecoration(context, hint: "Full Name"),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -117,6 +119,7 @@ class SignUpView extends StatelessWidget {
|
||||
fontColor: Colors.white,
|
||||
),
|
||||
TextFormField(
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
textInputAction: TextInputAction.done,
|
||||
keyboardType: TextInputType.text,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
@@ -138,6 +141,7 @@ class SignUpView extends StatelessWidget {
|
||||
fontColor: Colors.white,
|
||||
),
|
||||
TextFormField(
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
textInputAction: TextInputAction.done,
|
||||
keyboardType: TextInputType.text,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
@@ -160,6 +164,7 @@ class SignUpView extends StatelessWidget {
|
||||
fontColor: Colors.white,
|
||||
),
|
||||
TextFormField(
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
textInputAction: TextInputAction.done,
|
||||
keyboardType: TextInputType.text,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
@@ -220,6 +225,5 @@ class SignUpView extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/carbon_emission.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/consumption.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/live_monitor_tab.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
@@ -14,37 +14,39 @@ class DashboardView extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const TitleMedium(
|
||||
text: StringsManager.dashboard,
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const LiveMonitorTab(),
|
||||
const SizedBox(height: 10),
|
||||
const EnergyUsage(),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 220,
|
||||
maxHeight: 240,
|
||||
),
|
||||
child: const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
return HomeCubit.getInstance().spaces?.isEmpty ?? true
|
||||
? const CreateUnitWidget()
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Consumption(),
|
||||
SizedBox(height: 20),
|
||||
CarbonEmission(),
|
||||
const TitleMedium(
|
||||
text: StringsManager.dashboard,
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const LiveMonitorTab(),
|
||||
const SizedBox(height: 10),
|
||||
const EnergyUsage(),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 220,
|
||||
maxHeight: 240,
|
||||
),
|
||||
child: const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Consumption(),
|
||||
SizedBox(height: 20),
|
||||
CarbonEmission(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:syncrow_app/features/devices/view/widgets/devices_view_header.da
|
||||
import 'package:syncrow_app/features/devices/view/widgets/room_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/rooms_slider.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/wizard_page.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/create_unit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
|
||||
class DevicesViewBody extends StatelessWidget {
|
||||
@@ -23,59 +24,56 @@ class DevicesViewBody extends StatelessWidget {
|
||||
state is DevicesCategoriesLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const DevicesViewHeader(),
|
||||
const RoomsSlider(),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: PageView(
|
||||
controller: HomeCubit.getInstance().devicesPageController,
|
||||
onPageChanged: (index) {
|
||||
HomeCubit.getInstance().devicesPageChanged(index);
|
||||
},
|
||||
return HomeCubit.getInstance().spaces?.isEmpty ?? true
|
||||
? const CreateUnitWidget()
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const WizardPage(),
|
||||
if (HomeCubit.getInstance().selectedSpace != null)
|
||||
if (HomeCubit.getInstance().selectedSpace!.rooms != null)
|
||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map(
|
||||
(room) {
|
||||
return RoomPage(
|
||||
room: room,
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
HomeCubit.getInstance().selectedSpace != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 7,
|
||||
),
|
||||
child: SmoothPageIndicator(
|
||||
controller:
|
||||
HomeCubit.getInstance().devicesPageController,
|
||||
count: HomeCubit.getInstance()
|
||||
.selectedSpace!
|
||||
.rooms!
|
||||
.length +
|
||||
1,
|
||||
effect: const WormEffect(
|
||||
paintStyle: PaintingStyle.stroke,
|
||||
dotHeight: 8,
|
||||
dotWidth: 8,
|
||||
),
|
||||
),
|
||||
)
|
||||
: const Center(
|
||||
child: BodyLarge(text: 'No Home Found'),
|
||||
const DevicesViewHeader(),
|
||||
const RoomsSlider(),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
],
|
||||
);
|
||||
Expanded(
|
||||
child: PageView(
|
||||
controller: HomeCubit.getInstance().devicesPageController,
|
||||
onPageChanged: (index) {
|
||||
HomeCubit.getInstance().devicesPageChanged(index);
|
||||
},
|
||||
children: [
|
||||
const WizardPage(),
|
||||
if (HomeCubit.getInstance().selectedSpace != null)
|
||||
if (HomeCubit.getInstance().selectedSpace!.rooms != null)
|
||||
...HomeCubit.getInstance().selectedSpace!.rooms!.map(
|
||||
(room) {
|
||||
return RoomPage(
|
||||
room: room,
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
HomeCubit.getInstance().selectedSpace != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 7,
|
||||
),
|
||||
child: SmoothPageIndicator(
|
||||
controller: HomeCubit.getInstance().devicesPageController,
|
||||
count: HomeCubit.getInstance().selectedSpace!.rooms!.length + 1,
|
||||
effect: const WormEffect(
|
||||
paintStyle: PaintingStyle.stroke,
|
||||
dotHeight: 8,
|
||||
dotWidth: 8,
|
||||
),
|
||||
),
|
||||
)
|
||||
: const Center(
|
||||
child: BodyLarge(text: 'No Home Found'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_event.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_state.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
|
||||
class CreateUnitBloc extends Bloc<CreateUnitEvent, CreateUnitState> {
|
||||
List<String> rooms = [];
|
||||
String unitName = '';
|
||||
String locationName = '';
|
||||
|
||||
CreateUnitBloc() : super(InitialState()) {
|
||||
on<CreateRoomEvent>(_createRoom);
|
||||
on<RemoveRoomEvent>(_removeRoom);
|
||||
}
|
||||
|
||||
void _createRoom(CreateRoomEvent event, Emitter<CreateUnitState> emit) async {
|
||||
try {
|
||||
emit(LoadingState());
|
||||
if (rooms.contains(event.roomName)) {
|
||||
emit(const ErrorState(message: 'This name is already exist'));
|
||||
emit(CreateRoomState(roomList: rooms));
|
||||
return;
|
||||
}
|
||||
rooms.add(event.roomName);
|
||||
emit(CreateRoomState(roomList: rooms));
|
||||
} catch (e) {
|
||||
emit(const ErrorState(message: 'Something went wrong'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void _removeRoom(RemoveRoomEvent event, Emitter<CreateUnitState> emit) {
|
||||
try {
|
||||
emit(LoadingState());
|
||||
rooms.removeWhere((element) => element == event.roomName);
|
||||
emit(CreateRoomState(roomList: rooms));
|
||||
} catch (e) {
|
||||
emit(const ErrorState(message: 'Something went wrong'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class CreateUnitEvent extends Equatable {
|
||||
const CreateUnitEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class InitialEvent extends CreateUnitEvent {}
|
||||
|
||||
class LoadingEvent extends CreateUnitEvent {}
|
||||
|
||||
class CreateRoomEvent extends CreateUnitEvent {
|
||||
final String roomName;
|
||||
|
||||
const CreateRoomEvent({required this.roomName});
|
||||
|
||||
@override
|
||||
List<Object> get props => [roomName];
|
||||
}
|
||||
|
||||
class RemoveRoomEvent extends CreateUnitEvent {
|
||||
final String roomName;
|
||||
|
||||
const RemoveRoomEvent({required this.roomName});
|
||||
|
||||
@override
|
||||
List<Object> get props => [roomName];
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class CreateUnitState extends Equatable {
|
||||
const CreateUnitState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class InitialState extends CreateUnitState {}
|
||||
|
||||
class LoadingState extends CreateUnitState {}
|
||||
|
||||
class CreateRoomState extends CreateUnitState {
|
||||
final List<String> roomList;
|
||||
|
||||
const CreateRoomState({required this.roomList});
|
||||
|
||||
@override
|
||||
List<Object> get props => [roomList];
|
||||
}
|
||||
|
||||
class ErrorState extends CreateUnitState {
|
||||
final String message;
|
||||
|
||||
const ErrorState({required this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
@@ -1,124 +1,247 @@
|
||||
// ignore_for_file: unnecessary_const
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_bloc.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_event.dart';
|
||||
import 'package:syncrow_app/features/menu/bloc/create_unit_bloc/create_unit_state.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class CreateHomeView extends StatelessWidget {
|
||||
const CreateHomeView({super.key});
|
||||
class CreateUnitView extends StatelessWidget {
|
||||
const CreateUnitView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: const BodyLarge(
|
||||
text: 'Save',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
title: 'Create Home',
|
||||
child: Column(
|
||||
children: [
|
||||
//Home Info
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 25,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const BodyMedium(text: 'Home Name '),
|
||||
Flexible(
|
||||
child: TextField(
|
||||
textAlign: TextAlign.end,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Enter Name',
|
||||
hintStyle:
|
||||
context.bodyMedium.copyWith(color: Colors.grey),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
//Divider
|
||||
Container(
|
||||
height: 1,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const BodyMedium(text: 'Location '),
|
||||
Flexible(
|
||||
child: TextField(
|
||||
textAlign: TextAlign.end,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Set',
|
||||
hintStyle:
|
||||
context.bodyMedium.copyWith(color: Colors.grey),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
//Rooms Info
|
||||
const SizedBox(height: 10),
|
||||
const Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 25,
|
||||
),
|
||||
BodySmall(
|
||||
text: 'Rooms',
|
||||
String unitName = '';
|
||||
String location = '';
|
||||
TextEditingController textEditingController = TextEditingController();
|
||||
return BlocProvider(
|
||||
create: (context) => CreateUnitBloc(),
|
||||
child: BlocConsumer<CreateUnitBloc, CreateUnitState>(listener: (context, state) {
|
||||
if (state is ErrorState) {
|
||||
CustomSnackBar.displaySnackBar(state.message);
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
textEditingController.text = '';
|
||||
return DefaultScaffold(
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: const BodyLarge(
|
||||
text: 'Save',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 25,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
//TODO add room
|
||||
},
|
||||
child: const Row(
|
||||
],
|
||||
title: 'Create a Unit',
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 40),
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
//Home Info
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 25,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: 'Add Room',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const BodyMedium(text: 'Unit Name'),
|
||||
Flexible(
|
||||
child: TextField(
|
||||
textAlign: TextAlign.end,
|
||||
onChanged: (value) {
|
||||
unitName = value;
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Enter Name',
|
||||
hintStyle: context.bodyMedium.copyWith(color: Colors.grey),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const BodyMedium(text: 'Location '),
|
||||
Flexible(
|
||||
child: TextField(
|
||||
textAlign: TextAlign.end,
|
||||
onChanged: (value) {
|
||||
location = value;
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Set',
|
||||
hintStyle: context.bodyMedium.copyWith(color: Colors.grey),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
//Rooms Info
|
||||
const SizedBox(height: 10),
|
||||
const Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 25,
|
||||
),
|
||||
BodySmall(
|
||||
text: 'Spaces',
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
DefaultContainer(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 25,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (state is CreateRoomState)
|
||||
if (state.roomList.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: (state.roomList.length) * 55,
|
||||
child: ListView.separated(
|
||||
physics:
|
||||
const NeverScrollableScrollPhysics(), // Disable scrolling
|
||||
separatorBuilder: (context, index) => const Divider(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
itemCount: state.roomList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Dismissible(
|
||||
key: Key(state.roomList[index]),
|
||||
background: Container(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
decoration: ShapeDecoration(
|
||||
color: const Color(0xFFFF0000),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(index == 0 ? 20 : 0),
|
||||
topRight: Radius.circular(index == 0 ? 20 : 0),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
Assets.assetsDeleteIcon,
|
||||
width: 20,
|
||||
height: 22,
|
||||
),
|
||||
),
|
||||
direction: DismissDirection.endToStart,
|
||||
onDismissed: (direction) {
|
||||
String removedUnit = state.roomList[index];
|
||||
|
||||
BlocProvider.of<CreateUnitBloc>(context)
|
||||
.add(RemoveRoomEvent(roomName: removedUnit));
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('$removedUnit removed')),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Text(
|
||||
state.roomList[index],
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF5D5D5D),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (textEditingController.text.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Please add the room name')),
|
||||
);
|
||||
return;
|
||||
}
|
||||
BlocProvider.of<CreateUnitBloc>(context)
|
||||
.add(CreateRoomEvent(roomName: textEditingController.text));
|
||||
},
|
||||
child: const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: 'Add Space',
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
),
|
||||
],
|
||||
)),
|
||||
Flexible(
|
||||
child: TextField(
|
||||
textAlign: TextAlign.end,
|
||||
controller: textEditingController,
|
||||
onChanged: (value) {
|
||||
textEditingController.text = value;
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Set',
|
||||
hintStyle: context.bodyMedium.copyWith(color: Colors.grey),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/scene_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/create_unit.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/features/shared_widgets/text_widgets/body_small.dart';
|
||||
@@ -17,100 +19,102 @@ class SceneView extends StatelessWidget {
|
||||
create: (BuildContext context) => SceneCubit(),
|
||||
child: BlocBuilder<SceneCubit, SceneState>(
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const TitleMedium(
|
||||
text: StringsManager.routine,
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const BodySmall(
|
||||
text: StringsManager.tapToRunRoutine,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
),
|
||||
child: DefaultContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset(
|
||||
height: 50,
|
||||
width: 50,
|
||||
Assets.assetsIconsHot1,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
const Icon(
|
||||
Icons.play_circle,
|
||||
size: 40,
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
const BodyMedium(
|
||||
text: StringsManager.summerMode,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
)
|
||||
],
|
||||
),
|
||||
return HomeCubit.getInstance().spaces?.isEmpty ?? true
|
||||
? const CreateUnitWidget()
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const TitleMedium(
|
||||
text: StringsManager.routine,
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
),
|
||||
child: DefaultContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset(
|
||||
height: 50,
|
||||
width: 50,
|
||||
Assets.assetsIconsWinter1,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
const Icon(
|
||||
Icons.play_circle,
|
||||
size: 40,
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
const BodyMedium(
|
||||
text: StringsManager.winterMode,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const BodySmall(
|
||||
text: StringsManager.tapToRunRoutine,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
),
|
||||
child: DefaultContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset(
|
||||
height: 50,
|
||||
width: 50,
|
||||
Assets.assetsIconsHot1,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
const Icon(
|
||||
Icons.play_circle,
|
||||
size: 40,
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
const BodyMedium(
|
||||
text: StringsManager.summerMode,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
),
|
||||
child: DefaultContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Image.asset(
|
||||
height: 50,
|
||||
width: 50,
|
||||
Assets.assetsIconsWinter1,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
const Icon(
|
||||
Icons.play_circle,
|
||||
size: 40,
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
const BodyMedium(
|
||||
text: StringsManager.winterMode,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.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';
|
||||
|
||||
class CreateUnitWidget extends StatelessWidget {
|
||||
const CreateUnitWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.noUnitsIconDashboard,
|
||||
width: 100,
|
||||
height: 100,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
Flexible(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, Routes.createUnit);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 34, vertical: 14),
|
||||
decoration: ShapeDecoration(
|
||||
color: const Color(0x99023DFE),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
),
|
||||
child: const TitleMedium(
|
||||
text: 'Create a unit',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -221,6 +221,8 @@ class Assets {
|
||||
/// assets/icons/dashboard.svg
|
||||
static const String assetsIconsDashboard = "assets/icons/dashboard.svg";
|
||||
|
||||
static const String noUnitsIconDashboard = "assets/icons/no_units_ic.svg";
|
||||
|
||||
/// Assets for assetsIconsDashboardFill
|
||||
/// assets/icons/dashboard-fill.svg
|
||||
static const String assetsIconsDashboardFill = "assets/icons/dashboard-fill.svg";
|
||||
@@ -643,6 +645,8 @@ class Assets {
|
||||
/// assets/icons/Winter_mode.svg
|
||||
static const String assetsIconsWinterMode = "assets/icons/Winter_mode.svg";
|
||||
|
||||
static const String assetsDeleteIcon = "assets/icons/delete_room_ic.svg";
|
||||
|
||||
/// Assets for assetsImagesAutomation
|
||||
/// assets/images/automation.jpg
|
||||
static const String assetsImagesAutomation = "assets/images/automation.jpg";
|
||||
|
||||
@@ -6,10 +6,10 @@ import 'package:syncrow_app/features/auth/view/sign_up_view.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
|
||||
import 'package:syncrow_app/features/layout/view/layout_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/menu_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/home%20management/create_home_view.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/profile/profile_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||
import 'package:syncrow_app/features/splash/view/splash_view.dart';
|
||||
|
||||
import 'routing_constants.dart';
|
||||
|
||||
class Router {
|
||||
@@ -49,6 +49,8 @@ class Router {
|
||||
case Routes.menuRoute:
|
||||
return MaterialPageRoute(builder: (_) => const MenuView(), settings: settings);
|
||||
|
||||
case Routes.createUnit:
|
||||
return MaterialPageRoute(builder: (_) => const CreateUnitView(), settings: settings);
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => Scaffold(
|
||||
|
||||
@@ -16,4 +16,5 @@ class Routes {
|
||||
static const String policyRoute = '/policy';
|
||||
static const String termsRoute = '/terms';
|
||||
static const String otpRoute = '/otp';
|
||||
static const String createUnit = '/create-unit';
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import 'package:syncrow_app/features/auth/model/login_with_email_model.dart';
|
||||
import 'package:syncrow_app/features/auth/model/signup_model.dart';
|
||||
import 'package:syncrow_app/features/auth/model/token.dart';
|
||||
import 'package:syncrow_app/features/auth/model/verify_code.dart';
|
||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||
import 'package:syncrow_app/services/api/http_service.dart';
|
||||
|
||||
class AuthenticationAPI {
|
||||
static Future<Token> verifyPassCode(VerifyPassCode data) async {
|
||||
static Future<Map<String, dynamic>> verifyPassCode({required Map<String, dynamic> body}) async {
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.verifyOtp,
|
||||
body: data.toJson(),
|
||||
body: body,
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => Token.fromJson(json));
|
||||
expectedResponseModel: (json) => json);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -251,17 +251,17 @@ List<Map<String, Object>> menuSections = [
|
||||
'color': ColorsManager.primaryColor,
|
||||
'buttons': [
|
||||
{
|
||||
'title': 'Create a Home',
|
||||
'title': 'Create a Unit',
|
||||
'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsCreateHome,
|
||||
'page': const CreateHomeView()
|
||||
'page': const CreateUnitView()
|
||||
},
|
||||
{
|
||||
'title': 'Join a Home',
|
||||
'title': 'Join a Unit',
|
||||
'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsJoinAHome,
|
||||
'page': const JoinHomeView()
|
||||
},
|
||||
{
|
||||
'title': 'Manage Your Home',
|
||||
'title': 'Manage Your Units',
|
||||
'Icon': Assets.assetsIconsMenuIconsHomeManagementIconsManageYourHome,
|
||||
'page': const ManageHomeView()
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user