initialized Application theme
@ -24,7 +24,7 @@ if (flutterVersionName == null) {
|
||||
|
||||
android {
|
||||
namespace "com.example.syncrow_app"
|
||||
compileSdkVersion flutter.compileSdkVersion
|
||||
compileSdkVersion 34
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
|
BIN
assets/fonts/AftikaRegular.ttf
Normal file
BIN
assets/icons/Devices-fill.png
Normal file
After Width: | Height: | Size: 491 B |
BIN
assets/icons/Devices.png
Normal file
After Width: | Height: | Size: 597 B |
BIN
assets/icons/Layout-fill.png
Normal file
After Width: | Height: | Size: 331 B |
BIN
assets/icons/Layout.png
Normal file
After Width: | Height: | Size: 459 B |
BIN
assets/icons/Menu-fill.png
Normal file
After Width: | Height: | Size: 466 B |
BIN
assets/icons/Menu.png
Normal file
After Width: | Height: | Size: 537 B |
BIN
assets/icons/Routines-fill.png
Normal file
After Width: | Height: | Size: 554 B |
BIN
assets/icons/Routines.png
Normal file
After Width: | Height: | Size: 657 B |
BIN
assets/icons/dashboard-fill.png
Normal file
After Width: | Height: | Size: 617 B |
BIN
assets/icons/dashboard.png
Normal file
After Width: | Height: | Size: 692 B |
BIN
assets/images/automation.jpg
Normal file
After Width: | Height: | Size: 2.7 MiB |
@ -1,16 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/auth/models/user_model.dart';
|
||||
|
||||
class AuthProvider extends ChangeNotifier {
|
||||
// todo remove temp user
|
||||
UserModel user = UserModel(
|
||||
id: '1',
|
||||
name: 'John Doe',
|
||||
email: '',
|
||||
photoUrl: '',
|
||||
isAgreementAccepted: false,
|
||||
isAnonymous: false,
|
||||
isEmailVerified: false,
|
||||
phoneNumber: '',
|
||||
);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:syncrow_app/features/home/widgets/syncrow_logo.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_button.dart';
|
||||
import 'package:syncrow_app/navigation/route_manager.dart';
|
||||
|
||||
import '../../navigation/routing_constants.dart';
|
||||
import 'auth_provider.dart';
|
||||
|
||||
class AuthPage extends StatelessWidget {
|
||||
const AuthPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (BuildContext context) => AuthProvider(),
|
||||
builder: (context, child) => Scaffold(
|
||||
body: 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()),
|
||||
DefaultTextButton(
|
||||
text: 'Login',
|
||||
onPressed: () {
|
||||
RouteManager().routerManagerPopAndPushNamed(
|
||||
routeName: Routes.homeRoute,
|
||||
context: context,
|
||||
);
|
||||
},
|
||||
isPrimary: true,
|
||||
),
|
||||
const Gap(15),
|
||||
const DefaultTextButton(text: 'Sign Up'),
|
||||
const Gap(20),
|
||||
Center(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: const Text(
|
||||
'Try as a Guest',
|
||||
style: TextStyle(
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(30),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
8
lib/features/auth/bloc/auth_cubit.dart
Normal file
@ -0,0 +1,8 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'auth_state.dart';
|
||||
|
||||
class AuthCubit extends Cubit<AuthState> {
|
||||
AuthCubit() : super(AuthInitial());
|
||||
}
|
6
lib/features/auth/bloc/auth_state.dart
Normal file
@ -0,0 +1,6 @@
|
||||
part of 'auth_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class AuthState {}
|
||||
|
||||
class AuthInitial extends AuthState {}
|
19
lib/features/auth/view/auth_view.dart
Normal file
@ -0,0 +1,19 @@
|
||||
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(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
51
lib/features/auth/view/widgets/auth_view_body.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_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()),
|
||||
DefaultTextButton(
|
||||
text: 'Login',
|
||||
onPressed: () {
|
||||
Navigator.popAndPushNamed(context, Routes.homeRoute);
|
||||
},
|
||||
),
|
||||
const Gap(15),
|
||||
const DefaultTextButton(
|
||||
text: 'Sign Up',
|
||||
isSecondary: true,
|
||||
),
|
||||
const Gap(20),
|
||||
Center(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: const Text(
|
||||
'Try as a Guest',
|
||||
style: TextStyle(
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(30),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
9
lib/features/dashboard/bloc/dashboard_cubit.dart
Normal file
@ -0,0 +1,9 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
part 'dashboard_state.dart';
|
||||
|
||||
class DashboardCubit extends Cubit<DashboardState> {
|
||||
DashboardCubit() : super(DashboardInitial());
|
||||
|
||||
static DashboardCubit of(context) => BlocProvider.of<DashboardCubit>(context);
|
||||
}
|
5
lib/features/dashboard/bloc/dashboard_state.dart
Normal file
@ -0,0 +1,5 @@
|
||||
part of 'dashboard_cubit.dart';
|
||||
|
||||
abstract class DashboardState {}
|
||||
|
||||
class DashboardInitial extends DashboardState {}
|
10
lib/features/dashboard/view/dashboard_view.dart
Normal file
@ -0,0 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DashboardView extends StatelessWidget {
|
||||
const DashboardView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
@ -1,29 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/home/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/profile/profile_view.dart';
|
||||
import 'package:syncrow_app/features/scene/scene_view.dart';
|
||||
import 'package:syncrow_app/features/smart/smart_view.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'home_state.dart';
|
||||
import 'widgets/home_view_body.dart';
|
||||
import '../../profile/view/profile_view.dart';
|
||||
import '../../scene/view/scene_view.dart';
|
||||
import '../../smart/view/smart_view.dart';
|
||||
import '../model/device_model.dart';
|
||||
import '../view/widgets/home_view_body.dart';
|
||||
|
||||
class HomeProvider extends ChangeNotifier {
|
||||
HomeProvider() {
|
||||
print('HomeProvider created');
|
||||
part 'home_state.dart';
|
||||
|
||||
class HomeCubit extends Cubit<HomeState> {
|
||||
HomeCubit() : super(HomeInitial()) {
|
||||
getDevices();
|
||||
}
|
||||
|
||||
HomeState state = HomeState();
|
||||
//TODO separate the navigation logic to another cubit
|
||||
static HomeCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
static int pageIndex = 0;
|
||||
|
||||
var devices = <DeviceModel>[];
|
||||
|
||||
Future<List<DeviceModel>> getDevices() async {
|
||||
state.setLoading();
|
||||
emit(HomeLoading());
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
state.setSuccess();
|
||||
notifyListeners();
|
||||
emit(HomeSuccess());
|
||||
|
||||
return devices = [];
|
||||
}
|
||||
|
||||
@ -64,19 +66,15 @@ class HomeProvider extends ChangeNotifier {
|
||||
|
||||
final List<Widget> pages = [
|
||||
const HomeViewBody(),
|
||||
const ScenePage(),
|
||||
const SceneView(),
|
||||
const SmartPage(),
|
||||
const ProfilePage(),
|
||||
const ProfileView(),
|
||||
];
|
||||
|
||||
Widget getCurrentPage() {
|
||||
notifyListeners();
|
||||
|
||||
return pages[pageIndex];
|
||||
}
|
||||
static Widget get currentPage => HomeCubit().pages[pageIndex];
|
||||
|
||||
void updatePageIndex(int index, BuildContext context) {
|
||||
emit(HomeChangeIndex());
|
||||
pageIndex = index;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
14
lib/features/home/bloc/home_state.dart
Normal file
@ -0,0 +1,14 @@
|
||||
part of 'home_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class HomeState {}
|
||||
|
||||
class HomeInitial extends HomeState {}
|
||||
|
||||
class HomeLoading extends HomeState {}
|
||||
|
||||
class HomeSuccess extends HomeState {}
|
||||
|
||||
class HomeFailure extends HomeState {}
|
||||
|
||||
class HomeChangeIndex extends HomeState {}
|
@ -1,28 +0,0 @@
|
||||
class HomeState {
|
||||
HomeState() {
|
||||
loading = false;
|
||||
}
|
||||
|
||||
late bool loading;
|
||||
|
||||
late bool success;
|
||||
late bool error;
|
||||
|
||||
void setLoading() {
|
||||
loading = true;
|
||||
success = false;
|
||||
error = false;
|
||||
}
|
||||
|
||||
void setSuccess() {
|
||||
loading = false;
|
||||
success = true;
|
||||
error = false;
|
||||
}
|
||||
|
||||
void setError() {
|
||||
loading = false;
|
||||
success = false;
|
||||
error = true;
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../shared_widgets/default_nav_bar.dart';
|
||||
import 'home_provider.dart';
|
||||
import 'widgets/default_app_bar.dart';
|
||||
|
||||
class HomePage extends StatelessWidget {
|
||||
const HomePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (BuildContext context) => HomeProvider(),
|
||||
builder: (context, child) => Consumer<HomeProvider>(
|
||||
builder: (context, provider, child) {
|
||||
return Scaffold(
|
||||
appBar: const DefaultAppBar(),
|
||||
body: provider.state.loading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: provider.getCurrentPage(),
|
||||
bottomNavigationBar: const DefaultNavBar(),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
28
lib/features/home/view/home_view.dart
Normal file
@ -0,0 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/home/bloc/home_cubit.dart';
|
||||
|
||||
import '../../shared_widgets/default_app_bar.dart';
|
||||
import '../../shared_widgets/default_nav_bar.dart';
|
||||
|
||||
class HomeView extends StatelessWidget {
|
||||
const HomeView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => HomeCubit(),
|
||||
child: BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return Scaffold(
|
||||
appBar: const DefaultAppBar(),
|
||||
body: state is HomeLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: HomeCubit.currentPage,
|
||||
bottomNavigationBar: const DefaultNavBar(),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
24
lib/features/home/view/widgets/home_view_body.dart
Normal file
@ -0,0 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/home/bloc/home_cubit.dart';
|
||||
|
||||
import 'home_view_no_devices.dart';
|
||||
|
||||
class HomeViewBody extends StatelessWidget {
|
||||
const HomeViewBody({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => HomeCubit(),
|
||||
child: BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return HomeCubit.get(context).devices.isEmpty
|
||||
? const HomeViewNoDevices()
|
||||
: const SizedBox();
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
39
lib/features/home/view/widgets/home_view_no_devices.dart
Normal file
@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_button.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
|
||||
|
||||
class HomeViewNoDevices extends StatelessWidget {
|
||||
const HomeViewNoDevices({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
ImageManager.boxEmpty,
|
||||
opacity: const AlwaysStoppedAnimation(0.5),
|
||||
scale: 1,
|
||||
width: 140,
|
||||
),
|
||||
const Gap(15),
|
||||
const Text(
|
||||
'No Devices',
|
||||
style: TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
const Gap(15),
|
||||
const DefaultTextButton(
|
||||
text: 'Add Device',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:syncrow_app/features/home/home_provider.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_button.dart';
|
||||
import 'package:syncrow_app/resource_manager/assets_manager.dart';
|
||||
|
||||
class HomeViewBody extends StatelessWidget {
|
||||
const HomeViewBody({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (BuildContext context) => HomeProvider(),
|
||||
child: Consumer<HomeProvider>(
|
||||
builder: (context, provider, child) {
|
||||
return provider.devices.isEmpty
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
ImageManager.boxEmpty,
|
||||
opacity: const AlwaysStoppedAnimation(0.5),
|
||||
scale: 1,
|
||||
width: 140,
|
||||
),
|
||||
const Gap(15),
|
||||
const Text(
|
||||
'No Devices',
|
||||
style: TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
const Gap(15),
|
||||
const DefaultTextButton(
|
||||
text: 'Add Device',
|
||||
isPrimary: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const SizedBox();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
8
lib/features/profile/bloc/profile_cubit.dart
Normal file
@ -0,0 +1,8 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'profile_state.dart';
|
||||
|
||||
class ProfileCubit extends Cubit<ProfileState> {
|
||||
ProfileCubit() : super(ProfileInitial());
|
||||
}
|
6
lib/features/profile/bloc/profile_state.dart
Normal file
@ -0,0 +1,6 @@
|
||||
part of 'profile_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ProfileState {}
|
||||
|
||||
class ProfileInitial extends ProfileState {}
|
@ -1,7 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'profile_state.dart';
|
||||
|
||||
class ProfileProvider extends ChangeNotifier {
|
||||
final state = ProfileState();
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
class ProfileState {
|
||||
|
||||
ProfileState() {
|
||||
// init some variables
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'profile_provider.dart';
|
||||
|
||||
class ProfilePage extends StatelessWidget {
|
||||
const ProfilePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (BuildContext context) => ProfileProvider(),
|
||||
builder: (context, child) => const Center(
|
||||
child: Text('Profile Page'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
21
lib/features/profile/view/profile_view.dart
Normal file
@ -0,0 +1,21 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/profile/bloc/profile_cubit.dart';
|
||||
|
||||
class ProfileView extends StatelessWidget {
|
||||
const ProfileView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => ProfileCubit(),
|
||||
child: BlocBuilder<ProfileCubit, ProfileState>(
|
||||
builder: (context, state) {
|
||||
return const Center(
|
||||
child: Text('Profile Page'),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
22
lib/features/scene/bloc/scene_cubit.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_model.dart';
|
||||
|
||||
part 'scene_state.dart';
|
||||
|
||||
class SceneCubit extends Cubit<SceneState> {
|
||||
SceneCubit() : super(SceneInitial()) {
|
||||
getScenes();
|
||||
}
|
||||
|
||||
static SceneCubit of(context) => BlocProvider.of<SceneCubit>(context);
|
||||
|
||||
void getScenes() {
|
||||
emit(SceneLoading());
|
||||
Future.delayed(const Duration(seconds: 5), () {
|
||||
emit(SceneSuccess());
|
||||
});
|
||||
}
|
||||
|
||||
var scenes = <SceneModel>[];
|
||||
}
|
12
lib/features/scene/bloc/scene_state.dart
Normal file
@ -0,0 +1,12 @@
|
||||
part of 'scene_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class SceneState {}
|
||||
|
||||
class SceneInitial extends SceneState {}
|
||||
|
||||
class SceneLoading extends SceneState {}
|
||||
|
||||
class SceneSuccess extends SceneState {}
|
||||
|
||||
class SceneFailure extends SceneState {}
|
46
lib/features/scene/model/scene_model.dart
Normal file
@ -0,0 +1,46 @@
|
||||
class SceneModel {
|
||||
final String id;
|
||||
final String name;
|
||||
final String description;
|
||||
final String imageUrl;
|
||||
final String location;
|
||||
final String type;
|
||||
final String rating;
|
||||
final String price;
|
||||
final String duration;
|
||||
final String date;
|
||||
final String time;
|
||||
final String status;
|
||||
|
||||
SceneModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.imageUrl,
|
||||
required this.location,
|
||||
required this.type,
|
||||
required this.rating,
|
||||
required this.price,
|
||||
required this.duration,
|
||||
required this.date,
|
||||
required this.time,
|
||||
required this.status,
|
||||
});
|
||||
|
||||
factory SceneModel.fromJson(Map<String, dynamic> json) {
|
||||
return SceneModel(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
description: json['description'],
|
||||
imageUrl: json['imageUrl'],
|
||||
location: json['location'],
|
||||
type: json['type'],
|
||||
rating: json['rating'],
|
||||
price: json['price'],
|
||||
duration: json['duration'],
|
||||
date: json['date'],
|
||||
time: json['time'],
|
||||
status: json['status'],
|
||||
);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'scene_state.dart';
|
||||
|
||||
class SceneProvider extends ChangeNotifier {
|
||||
final state = SceneState();
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
class SceneState {
|
||||
|
||||
SceneState() {
|
||||
// init some variables
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'scene_provider.dart';
|
||||
|
||||
class ScenePage extends StatelessWidget {
|
||||
const ScenePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (BuildContext context) => SceneProvider(),
|
||||
builder: (context, child) => const Center(
|
||||
child: Text('Scene Page'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
22
lib/features/scene/view/scene_view.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/scene_cubit.dart';
|
||||
import 'package:syncrow_app/features/scene/view/widgets/scene_view_no_scenes.dart';
|
||||
|
||||
class SceneView extends StatelessWidget {
|
||||
const SceneView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (BuildContext context) => SceneCubit(),
|
||||
child: BlocBuilder<SceneCubit, SceneState>(
|
||||
builder: (context, state) {
|
||||
return state is SceneLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: const SceneViewNoScenes();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
40
lib/features/scene/view/widgets/scene_view_no_scenes.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_button.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
|
||||
|
||||
class SceneViewNoScenes extends StatelessWidget {
|
||||
const SceneViewNoScenes({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
ImageManager.automation,
|
||||
scale: 1,
|
||||
opacity: const AlwaysStoppedAnimation(.5),
|
||||
width: 140,
|
||||
),
|
||||
const Gap(15),
|
||||
const Text(
|
||||
'Home automation saves your time and effort by automating routine tasks.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
const Gap(20),
|
||||
const DefaultTextButton(
|
||||
text: 'Create Scene',
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,17 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:syncrow_app/features/home/widgets/syncrow_logo.dart';
|
||||
import 'package:syncrow_app/resource_manager/color_manager.dart';
|
||||
|
||||
import '../home_provider.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/home/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/syncrow_logo.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
const DefaultAppBar({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<HomeProvider>(
|
||||
builder: (context, provider, child) {
|
||||
return BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return AppBar(
|
||||
title: const SyncrowLogo(),
|
||||
actions: <Widget>[
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../home/home_provider.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/home/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class DefaultNavBar extends StatelessWidget {
|
||||
const DefaultNavBar({
|
||||
@ -10,15 +10,19 @@ class DefaultNavBar extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<HomeProvider>(
|
||||
builder: (context, provider, child) {
|
||||
return BlocBuilder<HomeCubit, HomeState>(
|
||||
builder: (context, state) {
|
||||
return BottomNavigationBar(
|
||||
onTap: (int index) => provider.updatePageIndex(index, context),
|
||||
currentIndex: HomeProvider.pageIndex,
|
||||
selectedItemColor: Colors.black,
|
||||
onTap: (int index) =>
|
||||
HomeCubit.get(context).updatePageIndex(index, context),
|
||||
currentIndex: HomeCubit.pageIndex,
|
||||
selectedItemColor: ColorsManager.primaryColor,
|
||||
selectedLabelStyle: const TextStyle(
|
||||
color: ColorsManager.primaryColor,
|
||||
),
|
||||
unselectedItemColor: Colors.grey,
|
||||
elevation: 10,
|
||||
items: provider.bottomNavItems,
|
||||
items: HomeCubit.get(context).bottomNavItems,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -1,25 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class DefaultTextButton extends StatelessWidget {
|
||||
const DefaultTextButton({
|
||||
super.key,
|
||||
this.onPressed,
|
||||
required this.text,
|
||||
this.isPrimary = false,
|
||||
this.isSecondary = false,
|
||||
});
|
||||
|
||||
final void Function()? onPressed;
|
||||
final String text;
|
||||
|
||||
final bool isPrimary;
|
||||
final bool isSecondary;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
onPressed: onPressed,
|
||||
style: isPrimary
|
||||
? ButtonStyle(
|
||||
style: isSecondary
|
||||
? null
|
||||
: ButtonStyle(
|
||||
backgroundColor:
|
||||
MaterialStateProperty.all(ColorsManager.primaryColor),
|
||||
shape: MaterialStateProperty.all(
|
||||
@ -27,11 +27,10 @@ class DefaultTextButton extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(color: isPrimary ? Colors.white : Colors.black),
|
||||
style: TextStyle(color: isSecondary ? Colors.black : Colors.white),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/resource_manager/assets_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
|
||||
|
||||
class SyncrowLogo extends StatelessWidget {
|
||||
const SyncrowLogo({
|
8
lib/features/smart/bloc/smart_cubit.dart
Normal file
@ -0,0 +1,8 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'smart_state.dart';
|
||||
|
||||
class SmartCubit extends Cubit<SmartState> {
|
||||
SmartCubit() : super(SmartInitial());
|
||||
}
|
6
lib/features/smart/bloc/smart_state.dart
Normal file
@ -0,0 +1,6 @@
|
||||
part of 'smart_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class SmartState {}
|
||||
|
||||
class SmartInitial extends SmartState {}
|
@ -1,7 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'smart_state.dart';
|
||||
|
||||
class SmartProvider extends ChangeNotifier {
|
||||
final state = SmartState();
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
class SmartState {
|
||||
|
||||
SmartState() {
|
||||
// init some variables
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'smart_provider.dart';
|
||||
|
||||
class SmartPage extends StatelessWidget {
|
||||
const SmartPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (BuildContext context) => SmartProvider(),
|
||||
builder: (context, child) => const Center(
|
||||
child: Text('Smart Page'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
20
lib/features/smart/view/smart_view.dart
Normal file
@ -0,0 +1,20 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/smart/bloc/smart_cubit.dart';
|
||||
|
||||
class SmartPage extends StatelessWidget {
|
||||
const SmartPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => SmartCubit(),
|
||||
child: BlocBuilder<SmartCubit, SmartState>(
|
||||
builder: (context, state) {
|
||||
return const Center(
|
||||
child: Text('Smart Page'),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
@ -1,30 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/splash/user_agreement_dialog.dart';
|
||||
import 'package:syncrow_app/navigation/route_manager.dart';
|
||||
import 'package:syncrow_app/features/splash/view/widgets/user_agreement_dialog.dart';
|
||||
import 'package:syncrow_app/navigation/routing_constants.dart';
|
||||
import 'package:syncrow_app/resource_manager/assets_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
|
||||
|
||||
class SplashView extends StatelessWidget {
|
||||
const SplashView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//TODO Remove delay
|
||||
// Future.delayed(const Duration(seconds: 5), () {
|
||||
// RouteManager().routerManagerPushUntil(
|
||||
// context,
|
||||
// routeName: Routes.homeRoute,
|
||||
// );
|
||||
// });
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.arrow_forward),
|
||||
onPressed: () {
|
||||
RouteManager().routerManagerPopAndPushNamed(
|
||||
routeName: Routes.authRoute,
|
||||
context: context,
|
||||
Navigator.popAndPushNamed(
|
||||
context,
|
||||
Routes.authRoute,
|
||||
);
|
||||
},
|
||||
),
|
@ -19,11 +19,11 @@ class UserAgreementDialog extends StatelessWidget {
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
isPrimary: true,
|
||||
),
|
||||
DefaultTextButton(
|
||||
text: 'I Disagree',
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
isSecondary: true,
|
||||
),
|
||||
],
|
||||
);
|
@ -1,124 +0,0 @@
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
class URLConstants {
|
||||
static String baseURL = dotenv.env['BASE_URL'] ?? '';
|
||||
static String helpCenterPageURL = dotenv.env['HELP_PAGE_URL'] ?? '';
|
||||
static String termsPageURL = dotenv.env['TERMS_PAGE_URL'] ?? '';
|
||||
static String privacyPageURL = dotenv.env['PRIVACY_PAGE_URL'] ?? '';
|
||||
static String iosPlayStore = dotenv.env['IOS_PLAY_STORE'] ?? '';
|
||||
}
|
||||
|
||||
class KeyConstants {
|
||||
static const String languageCode = "Language Code";
|
||||
static const String countryCode = "Country Code";
|
||||
static const String username = "User Name";
|
||||
static const String password = "Password";
|
||||
static const String userFullName = "User Full Name";
|
||||
static const String userImageURL = "User Image URL";
|
||||
static const String userType = "User Type";
|
||||
static const String accessToken = "Access Token";
|
||||
static const String refreshToken = "Refresh Token";
|
||||
static const String newToken = "new-token";
|
||||
static const String loginID = "Login ID";
|
||||
static const String faceIDSaved = "Face ID Saved";
|
||||
static const String userID = "User ID";
|
||||
static const String officeID = "Office ID";
|
||||
static const String showServerMessage = "Show Server Message";
|
||||
static String oneSignalAppId = dotenv.env['ONE_SIGNAL_ID'] ?? '';
|
||||
|
||||
//shared preferences keys
|
||||
static const String isDemoFlag = "isDemo";
|
||||
static const String isOnboardingFlag = "isOnboarding";
|
||||
static const String userIdValue = "userId";
|
||||
static const String phoneNumber = "phone";
|
||||
static const String loginCounter = 'loginCounter';
|
||||
static const String notificationCounter = 'notificationCounter';
|
||||
static const String doNotShowAgain = 'doNotShowAgain';
|
||||
static const String sendPlayerId = 'sendPlayerId';
|
||||
static const String srmPhone = 'srmPhone';
|
||||
static const String paragraphTitle = 'title';
|
||||
static const String paragraphBody = 'body';
|
||||
static const String playerId = 'PlayerId';
|
||||
static const String addProperty = 'addProperty';
|
||||
static const String showNotificationSetting = 'showNotificationSetting';
|
||||
static const String numberOfCases = 'numberOfCases';
|
||||
static const String internetConnection = 'internetConnection';
|
||||
static const String lowValuation = 'lowValuation';
|
||||
static const String highValuation = 'highValuation';
|
||||
static const String finalValuation = 'finalValuation';
|
||||
static const String firstLaunch = 'firstLaunch';
|
||||
static const String onboardedFirstUnit = 'onboardedFirstUnit';
|
||||
static const String accountIds = 'accountIds';
|
||||
static const String utmSourceParameter = 'utmSource';
|
||||
static const String utmMediumParameter = 'utmMedium';
|
||||
static const String utmCampaignNameParameter = 'utmCampaign';
|
||||
static const String accountIsDeleted = 'accountIsDeleted';
|
||||
static const String firstTimeLaunch = 'firstTimeLaunch';
|
||||
static const String loggedOut = 'loggedOut';
|
||||
}
|
||||
|
||||
class APIConstants {
|
||||
static const String unitsList = "app/api/v2/units/listInfo";
|
||||
static const String onboardingUnitList = 'app/api/v2/units/onboardingunit';
|
||||
static const String events = "event/events";
|
||||
static const String paymentEvents = "event/payment";
|
||||
static const String tenancyEvents = "event/tenancy";
|
||||
static const String renewTenancyContract = "opportunity/renewal-service";
|
||||
static const String findNewTenant = "opportunity/newTenant-service";
|
||||
static const String loginWithChannel = 'auth/login-with-channel';
|
||||
static const String verifyPassCode = 'auth/validate-pass-code';
|
||||
static const String refreshToken = 'auth/refresh-token';
|
||||
static const String updateUserInfo = 'auth/update-user-info';
|
||||
static const String readUserInfo = 'auth/read-user-info';
|
||||
static const String getCountyCode = 'auth/get-country-code';
|
||||
static const String notificationToken = 'auth/set-notification-token';
|
||||
static const String logout = 'auth/logout';
|
||||
static const String deleteAccount = 'auth/self-delete-user';
|
||||
static const String profileAPI = 'app/api/v2/users/profile';
|
||||
static const String pmUnitsList = 'app/api/v2/service/manageproperty';
|
||||
static const String rentPropertyUnitsList = 'app/api/v2/service/rentproperty';
|
||||
static const String sellPropertyUnitsList = 'app/api/v2/service/sellproperty';
|
||||
static const String upfrontPropertyUnitsList = 'app/api/v2/service/upfrontRentlist';
|
||||
static const String sendPMrequest = 'opportunity/pm-service';
|
||||
static const String sendSellRequest = 'opportunity/sell-service';
|
||||
static const String sendRentRequest = 'opportunity/rent-service';
|
||||
static const String sendUpfrontRequest = 'opportunity/upfront-service';
|
||||
static const String sendBuyRequest = 'opportunity/buy-service';
|
||||
static const String documentsPresignedUrl = 'cases/doc-presigned-url';
|
||||
static const String addDocumentsRequest = 'cases/add-doc-service';
|
||||
static const String handoverRequest = 'opportunity/handedOver-service';
|
||||
static const String tenancyUpfrontRequest = 'opportunity/tenancy-upfront-service';
|
||||
static const String eventsTypes = 'event/types';
|
||||
|
||||
//Add Property APIs
|
||||
static const String getSuggestionsLocations = 'avm/getSuggestedLocations';
|
||||
static const String getSuggestionsUnits = 'avm/getunitbyLocationIdAndUnitNumber';
|
||||
static const String addPropertyRequest = 'cases/add-property-service-request';
|
||||
static const String manualPrepareAddPropertyRequest = 'cases/prepare-add-property-service';
|
||||
static const String manualAddPropertyRequest = 'cases/add-property-manual-service';
|
||||
static const String addPropertyRequestV3 = 'cases/add-property-service';
|
||||
static const String getNeighborhoods = 'cases/neighbourhood-locations';
|
||||
static const String valuateProperty = 'cases/valuate-property';
|
||||
static const String purposes = 'cases/purposesList';
|
||||
//Portfolio API
|
||||
static const String portfolio = 'app/api/v2/users/portfolio';
|
||||
static const String insights = 'app/api/v2/users/portfolioInsights';
|
||||
}
|
||||
|
||||
class AuthenticationConstants {
|
||||
static const platformName = 'platformName';
|
||||
static const productName = 'productName';
|
||||
static const localAuthenticationAttempts = 'localAuthenticationAttempts';
|
||||
static const localAuthenticationLastAttempt = 'localAuthenticationLastAttempt';
|
||||
}
|
||||
|
||||
class MIMEConstants {
|
||||
static const pdfMime = "application/pdf";
|
||||
static const pngMime = "image/png";
|
||||
static const jpgMime = "image/jpeg";
|
||||
static const tiffMime = "image/tiff";
|
||||
}
|
||||
|
||||
class AppDateFormat {
|
||||
static const dateFormat = 'd MMM, yyyy';
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/services/navigation_service.dart';
|
||||
|
||||
class CustomSnackBar {
|
||||
static displaySnackBar(String message) {
|
||||
final key = NavigationService.snackbarKey;
|
||||
if (key != null) {
|
||||
final snackBar = SnackBar(content: Text(message));
|
||||
key.currentState?.clearSnackBars();
|
||||
key.currentState?.showSnackBar(snackBar);
|
||||
}
|
||||
}
|
||||
|
||||
static greenSnackBar(String message) {
|
||||
final key = NavigationService.snackbarKey;
|
||||
BuildContext? currentContext = key?.currentContext;
|
||||
if (key != null && currentContext != null) {
|
||||
final snackBar = SnackBar(
|
||||
padding: const EdgeInsets.all(16),
|
||||
// backgroundColor: KeyperColors.onboardingPortfolioCasesNumberBG,
|
||||
content: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
// Image.asset(
|
||||
// ImageConstants.checkGreenRounded,
|
||||
// width: 32,
|
||||
// height: 32,
|
||||
// ),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Text(
|
||||
message,
|
||||
// style: Theme.of(currentContext)
|
||||
// .textTheme
|
||||
// .bodySmall!
|
||||
// .copyWith(fontSize: 14, fontWeight: FontWeight.w500, color: KeyperColors.greyBody),
|
||||
)
|
||||
]),
|
||||
);
|
||||
key.currentState?.showSnackBar(snackBar);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/utils/bloc_observer.dart';
|
||||
|
||||
import 'my_app.dart';
|
||||
|
||||
void main() {
|
||||
Bloc.observer = MyBlocObserver();
|
||||
//TODO: Uncomment
|
||||
// runZonedGuarded(() async {
|
||||
// const environment =
|
||||
// String.fromEnvironment('FLAVOR', defaultValue: 'production');
|
||||
@ -10,9 +14,6 @@ void main() {
|
||||
//
|
||||
// HttpOverrides.global = MyHttpOverrides();
|
||||
// WidgetsFlutterBinding.ensureInitialized();
|
||||
// // if (Platform.isAndroid) {
|
||||
// // await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||
// // }
|
||||
// LicenseRegistry.addLicense(() async* {
|
||||
// final license =
|
||||
// await rootBundle.loadString('assets/fonts/roboto/LICENSE.txt');
|
||||
|
@ -1,50 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:syncrow_app/resource_manager/color_manager.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/home/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/theme_manager.dart';
|
||||
|
||||
import 'features/auth/auth_provider.dart';
|
||||
import 'navigation/router.dart' as router;
|
||||
import 'navigation/routing_constants.dart';
|
||||
import 'services/navigation_service.dart';
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
class MyApp extends StatelessWidget {
|
||||
final Locale locale;
|
||||
|
||||
const MyApp(this.locale, {super.key});
|
||||
|
||||
@override
|
||||
State<MyApp> createState() => _MyAppState();
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) => AuthCubit(),
|
||||
),
|
||||
BlocProvider(
|
||||
create: (context) => HomeCubit(),
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
color: ColorsManager.primaryColor,
|
||||
title: 'Syncrow App',
|
||||
onGenerateRoute: router.Router.generateRoute,
|
||||
initialRoute: Routes.splash,
|
||||
themeMode: ThemeMode.system,
|
||||
theme: myTheme,
|
||||
supportedLocales: const [
|
||||
Locale('en', ''), // English, no country code
|
||||
Locale('ar', ''), // Arabic, no country code
|
||||
],
|
||||
// locale: locale,
|
||||
locale: const Locale('en', ''),
|
||||
),
|
||||
);
|
||||
return ChangeNotifierProvider(
|
||||
create: (context) => AuthProvider(),
|
||||
child: MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
navigatorKey: NavigationService.navigatorKey,
|
||||
scaffoldMessengerKey: NavigationService.snackbarKey,
|
||||
color: ColorsManager.primaryColor,
|
||||
title: 'Syncrow App',
|
||||
onGenerateRoute: router.Router.generateRoute,
|
||||
initialRoute: Routes.splash,
|
||||
themeMode: ThemeMode.system,
|
||||
supportedLocales: const [
|
||||
Locale('en', ''), // English, no country code
|
||||
Locale('ar', ''), // Arabic, no country code
|
||||
],
|
||||
// locale: locale,
|
||||
locale: const Locale('en', ''),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'routing_constants.dart';
|
||||
|
||||
class RouteManager {
|
||||
List<String> routesWithoutLogin = [
|
||||
Routes.homeRoute,
|
||||
];
|
||||
|
||||
List<String> exclusionList = [];
|
||||
|
||||
//TODO (to mohammad) add the context extension
|
||||
routerManager({required String routeName, required BuildContext context}) {
|
||||
Navigator.of(context).pushNamed(routeName);
|
||||
}
|
||||
|
||||
routerManagerPushUntil(BuildContext? context, {required String routeName}) {
|
||||
if (context != null) {
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(routeName, (route) => false);
|
||||
}
|
||||
}
|
||||
|
||||
routerManagerPopAndPushNamed(
|
||||
{required String routeName, required BuildContext context}) {
|
||||
Navigator.of(context).popAndPushNamed(routeName);
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/auth/auth_view.dart';
|
||||
import 'package:syncrow_app/features/home/home_view.dart';
|
||||
import 'package:syncrow_app/features/profile/profile_view.dart';
|
||||
import 'package:syncrow_app/features/scene/scene_view.dart';
|
||||
import 'package:syncrow_app/features/smart/smart_view.dart';
|
||||
import 'package:syncrow_app/features/splash/splash_view.dart';
|
||||
import 'package:syncrow_app/features/auth/view/auth_view.dart';
|
||||
import 'package:syncrow_app/features/home/view/home_view.dart';
|
||||
import 'package:syncrow_app/features/profile/view/profile_view.dart';
|
||||
import 'package:syncrow_app/features/scene/view/scene_view.dart';
|
||||
import 'package:syncrow_app/features/smart/view/smart_view.dart';
|
||||
import 'package:syncrow_app/features/splash/view/splash_view.dart';
|
||||
|
||||
import 'routing_constants.dart';
|
||||
|
||||
@ -17,15 +17,15 @@ class Router {
|
||||
|
||||
case Routes.homeRoute:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const HomePage(), settings: settings);
|
||||
builder: (_) => const HomeView(), settings: settings);
|
||||
|
||||
case Routes.profileRoute:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const ProfilePage(), settings: settings);
|
||||
builder: (_) => const ProfileView(), settings: settings);
|
||||
|
||||
case Routes.sceneRoute:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const ScenePage(), settings: settings);
|
||||
builder: (_) => const SceneView(), settings: settings);
|
||||
|
||||
case Routes.smartRoute:
|
||||
return MaterialPageRoute(
|
||||
@ -33,7 +33,7 @@ class Router {
|
||||
|
||||
case Routes.authRoute:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => const AuthPage(), settings: settings);
|
||||
builder: (_) => const AuthView(), settings: settings);
|
||||
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
|
@ -1,45 +0,0 @@
|
||||
// import 'dart:ui';
|
||||
|
||||
// /// # To add custom fonts to your application, add a fonts section here,
|
||||
// /// # in this "flutter" section. Each entry in this list should have a
|
||||
// /// # "family" key with the font family name, and a "fonts" key with a
|
||||
// /// # list giving the asset and other descriptors for the font. For
|
||||
// /// # example:
|
||||
// ///
|
||||
// /// fonts:
|
||||
// /// - family:Montserrat
|
||||
// /// fonts:
|
||||
// /// - asset: assets/ fonts/Montserrat-Botd. ttf
|
||||
// /// weight: 700
|
||||
// /// - asset: assets/ fonts/Montserrat-SemiB01d. ttf
|
||||
// /// weight: 600
|
||||
|
||||
// class FontsManager {
|
||||
// static const FontWeight light = FontWeight.w300;
|
||||
// static const FontWeight regular = FontWeight.w400;
|
||||
// static const FontWeight medium = FontWeight.w500;
|
||||
// static const FontWeight semiBold = FontWeight.w600;
|
||||
// static const FontWeight bold = FontWeight.w700;
|
||||
// static const FontWeight extraBold = FontWeight.w800;
|
||||
// static const FontWeight black = FontWeight.w900;
|
||||
|
||||
// static const String fontFamily = 'Avenir';
|
||||
// }
|
||||
|
||||
// class FontSize {
|
||||
// static const double s12 = 12;
|
||||
// static const double s10 = 10;
|
||||
// static const double s14 = 14;
|
||||
// static const double s16 = 16;
|
||||
// static const double s18 = 18;
|
||||
// static const double s20 = 20;
|
||||
// static const double s21 = 21;
|
||||
// static const double s22 = 22;
|
||||
// static const double s24 = 24;
|
||||
// static const double s25 = 25;
|
||||
// static const double s26 = 26;
|
||||
// static const double s28 = 28;
|
||||
// static const double s30 = 30;
|
||||
// static const double s35 = 35;
|
||||
// static const double s48 = 48;
|
||||
// }
|
@ -1,78 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
|
||||
// class RoutesManager {
|
||||
// static const String home = '/';
|
||||
// static const String about = '/about';
|
||||
// static const String complains = '/complains';
|
||||
// static const String reg = '/register';
|
||||
// static const String limit = '/limit';
|
||||
// static const String services = '/services';
|
||||
// static const String agents = '/agent';
|
||||
// static const String contact = '/contact';
|
||||
// static const String merchList = '/merchList';
|
||||
// static const String parkAmman = '/park_amman';
|
||||
// static const String consumerProtection = '/consumerProtection';
|
||||
// static const String definitions = '/definitions';
|
||||
// static const String conditions = '/conditions';
|
||||
// static const String responsibilities = '/responsibilities';
|
||||
// static const String responsibilitiesCompany = '/responsibilitiesCompany';
|
||||
// static const String agentFinder = '/agent_finder';
|
||||
// static const String agentRequest = '/agent_request';
|
||||
// static const String ayaMap = '/aya_map';
|
||||
// }
|
||||
|
||||
// class RouteGenerator {
|
||||
// static Route<dynamic> getRoute(RouteSettings settings) {
|
||||
// switch (settings.name) {
|
||||
// case RoutesManager.home:
|
||||
// return MaterialPageRoute(builder: (_) => const HomeView());
|
||||
// case RoutesManager.about:
|
||||
// return MaterialPageRoute(builder: (_) => const AboutView());
|
||||
// case RoutesManager.complains:
|
||||
// return MaterialPageRoute(builder: (_) => ComplainsView());
|
||||
// case RoutesManager.reg:
|
||||
// return MaterialPageRoute(builder: (_) => const RegistrationView());
|
||||
// case RoutesManager.limit:
|
||||
// return MaterialPageRoute(builder: (_) => const LimitsView());
|
||||
// case RoutesManager.services:
|
||||
// return MaterialPageRoute(builder: (_) => const ServicesView());
|
||||
// case RoutesManager.agents:
|
||||
// return MaterialPageRoute(builder: (_) => const AgentsView());
|
||||
// case RoutesManager.contact:
|
||||
// return MaterialPageRoute(builder: (_) => const ContactUsView());
|
||||
// case RoutesManager.merchList:
|
||||
// return MaterialPageRoute(builder: (_) => const MerchListView());
|
||||
// case RoutesManager.parkAmman:
|
||||
// return MaterialPageRoute(builder: (_) => const ParkAmmanView());
|
||||
// case RoutesManager.consumerProtection:
|
||||
// return MaterialPageRoute(
|
||||
// builder: (_) => const ConsumerProtectionView(),
|
||||
// );
|
||||
// case RoutesManager.definitions:
|
||||
// return MaterialPageRoute(builder: (_) => const DefinitionsView());
|
||||
// case RoutesManager.conditions:
|
||||
// return MaterialPageRoute(builder: (_) => const ConditionsView());
|
||||
// case RoutesManager.responsibilities:
|
||||
// return MaterialPageRoute(builder: (_) => const ResponsibilitiesView());
|
||||
// case RoutesManager.responsibilitiesCompany:
|
||||
// return MaterialPageRoute(
|
||||
// builder: (_) => const ResponsibilitiesCompanyView(),
|
||||
// );
|
||||
// case RoutesManager.agentFinder:
|
||||
// return MaterialPageRoute(builder: (_) => AgentFinderView());
|
||||
// case RoutesManager.agentRequest:
|
||||
// return MaterialPageRoute(builder: (_) => const AgentRequestView());
|
||||
// case RoutesManager.ayaMap:
|
||||
// return MaterialPageRoute(builder: (_) => const AyaMapView());
|
||||
// default:
|
||||
// return MaterialPageRoute(builder: (_) => const ErrorView());
|
||||
// }
|
||||
// }
|
||||
|
||||
// static Route<dynamic> unknownRoute() =>
|
||||
// MaterialPageRoute(builder: (_) => const ErrorView());
|
||||
|
||||
// static List<Route<dynamic>> initialRoute() => [
|
||||
// MaterialPageRoute(builder: (_) => const HomeView()),
|
||||
// ];
|
||||
// }
|
@ -1,74 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
|
||||
// import 'font_manager.dart';
|
||||
|
||||
// TextStyle _getTextStyle({
|
||||
// required double fontSize,
|
||||
// required Color color,
|
||||
// required FontWeight fontWeight,
|
||||
// }) => TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: fontSize,
|
||||
// color: color,
|
||||
// fontWeight: fontWeight,
|
||||
// );
|
||||
|
||||
// /// regular style
|
||||
// TextStyle getTextStyleRegular({
|
||||
// required Color color, double fontSize = FontSize.s14,
|
||||
// fontWeight = FontsManager.regular,
|
||||
// }) => _getTextStyle(
|
||||
// fontSize: fontSize,
|
||||
// color: color,
|
||||
// fontWeight: fontWeight,
|
||||
// );
|
||||
|
||||
// /// light style
|
||||
// TextStyle getTextStyleLight({
|
||||
// required Color color, double fontSize = FontSize.s12,
|
||||
// fontWeight = FontsManager.light,
|
||||
// }) => _getTextStyle(
|
||||
// fontSize: fontSize,
|
||||
// color: color,
|
||||
// fontWeight: fontWeight,
|
||||
// );
|
||||
|
||||
// /// medium style
|
||||
// TextStyle getTextStyleMedium({
|
||||
// required Color color, double fontSize = FontSize.s16,
|
||||
// fontWeight = FontsManager.medium,
|
||||
// }) => _getTextStyle(
|
||||
// fontSize: fontSize,
|
||||
// color: color,
|
||||
// fontWeight: fontWeight,
|
||||
// );
|
||||
|
||||
// /// semi bold style
|
||||
// TextStyle getTextStyleSemiBold({
|
||||
// required Color color, double fontSize = FontSize.s18,
|
||||
// fontWeight = FontsManager.semiBold,
|
||||
// }) => _getTextStyle(
|
||||
// fontSize: fontSize,
|
||||
// color: color,
|
||||
// fontWeight: fontWeight,
|
||||
// );
|
||||
|
||||
// /// bold style
|
||||
// TextStyle getTextStyleBold({
|
||||
// required Color color, double fontSize = FontSize.s20,
|
||||
// fontWeight = FontsManager.bold,
|
||||
// }) => _getTextStyle(
|
||||
// fontSize: fontSize,
|
||||
// color: color,
|
||||
// fontWeight: fontWeight,
|
||||
// );
|
||||
|
||||
// /// extra bold style
|
||||
// TextStyle getTextStyleExtraBold({
|
||||
// required Color color, double fontSize = FontSize.s22,
|
||||
// fontWeight = FontsManager.extraBold,
|
||||
// }) => _getTextStyle(
|
||||
// fontSize: fontSize,
|
||||
// color: color,
|
||||
// fontWeight: fontWeight,
|
||||
// );
|
@ -1,155 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
|
||||
// import 'color_manager.dart';
|
||||
// import 'font_manager.dart';
|
||||
// import 'values_manager.dart';
|
||||
|
||||
// ThemeData myTheme = ThemeData(
|
||||
// ///main colors
|
||||
// primaryColor: ColorsManager.primaryLightColor,
|
||||
// colorScheme: ColorsManager.lightColorScheme,
|
||||
// scaffoldBackgroundColor: Colors.white,
|
||||
|
||||
// ///text theme
|
||||
// textTheme: const TextTheme(
|
||||
// ///display
|
||||
// displayLarge: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s35,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,),
|
||||
// displayMedium: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s20,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// displaySmall: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s16,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
|
||||
// ///title
|
||||
// titleLarge: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s48,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// titleMedium: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s30,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// titleSmall: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s25,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
|
||||
// ///body
|
||||
// bodyLarge: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s18,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// bodyMedium: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s14,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// bodySmall: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s12,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
|
||||
// labelLarge: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s18,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// labelMedium: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s16,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// labelSmall: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s14,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// ///button theme
|
||||
// buttonTheme: ButtonThemeData(
|
||||
// buttonColor: ColorsManager.primaryLightColor,
|
||||
// padding: const EdgeInsets.symmetric(horizontal: AppPadding.p8),
|
||||
// textTheme: ButtonTextTheme.primary,
|
||||
// hoverColor: ColorsManager.primaryDarkColor,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(AppRadius.r4),
|
||||
// ),),
|
||||
|
||||
// textButtonTheme: TextButtonThemeData(
|
||||
// style: ButtonStyle(
|
||||
// backgroundColor:
|
||||
// MaterialStateProperty.all<Color>(ColorsManager.primaryLightColor),
|
||||
// padding: MaterialStateProperty.all<EdgeInsets>(
|
||||
// const EdgeInsets.all(AppPadding.p8),),
|
||||
// textStyle: MaterialStateProperty.all<TextStyle>(
|
||||
// const TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s16,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: ColorsManager.onPrimaryLightColor,
|
||||
// ),
|
||||
// ),
|
||||
// // shape: MaterialStateProperty.all<OutlinedBorder>(
|
||||
// // RoundedRectangleBorder(
|
||||
// // borderRadius: BorderRadius.circular(AppRadius.r4),
|
||||
// // side: const BorderSide(color: Colors.grey),
|
||||
// // ),
|
||||
// // ),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// ///input decoration theme
|
||||
// inputDecorationTheme: const InputDecorationTheme(
|
||||
// border: OutlineInputBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
// ),
|
||||
// enabledBorder: OutlineInputBorder(
|
||||
// borderSide: BorderSide(color: Colors.grey),
|
||||
// borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
// ),
|
||||
// focusedBorder: OutlineInputBorder(
|
||||
// borderSide: BorderSide(color: ColorsManager.primaryLightColor),
|
||||
// borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
// ),
|
||||
// labelStyle: TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// color: Colors.grey,
|
||||
// fontSize: FontSize.s16,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// ///card theme
|
||||
// cardTheme: const CardTheme(
|
||||
// elevation: 0,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
@ -1,10 +1,9 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/api/http_interceptor.dart';
|
||||
import 'package:syncrow_app/helpers/constants.dart';
|
||||
import 'package:syncrow_app/helpers/sharedPreferences_helper.dart';
|
||||
import 'package:syncrow_app/services/locator.dart';
|
||||
|
||||
import 'http_interceptor.dart';
|
||||
|
||||
class HTTPService {
|
||||
final Dio client = locator<Dio>();
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
@ -44,8 +43,6 @@ class HTTPService {
|
||||
bool showServerMessage = true,
|
||||
}) async {
|
||||
try {
|
||||
SharedPreferencesHelper.saveBoolToSP(
|
||||
KeyConstants.showServerMessage, showServerMessage);
|
||||
final response = await client.get(
|
||||
path,
|
||||
queryParameters: queryParameters,
|
||||
@ -66,8 +63,6 @@ class HTTPService {
|
||||
bool showServerMessage = true,
|
||||
required T Function(dynamic) expectedResponseModel}) async {
|
||||
try {
|
||||
SharedPreferencesHelper.saveBoolToSP(
|
||||
KeyConstants.showServerMessage, showServerMessage);
|
||||
final response = await client.post(path,
|
||||
data: body, queryParameters: queryParameters, options: options);
|
||||
debugPrint("status code is ${response.statusCode}");
|
@ -1,6 +1,6 @@
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
import '../api/http_interceptor.dart';
|
||||
import 'api/http_interceptor.dart';
|
||||
|
||||
GetIt locator = GetIt.instance;
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NavigationService {
|
||||
static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
static GlobalKey<ScaffoldMessengerState>? snackbarKey = GlobalKey<ScaffoldMessengerState>();
|
||||
}
|
29
lib/utils/bloc_observer.dart
Normal file
@ -0,0 +1,29 @@
|
||||
// ignore_for_file: avoid_print
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class MyBlocObserver extends BlocObserver {
|
||||
@override
|
||||
void onCreate(BlocBase bloc) {
|
||||
super.onCreate(bloc);
|
||||
print('onCreate -- ${bloc.runtimeType}');
|
||||
}
|
||||
|
||||
@override
|
||||
void onChange(BlocBase bloc, Change change) {
|
||||
super.onChange(bloc, change);
|
||||
print('onChange -- ${bloc.runtimeType}, $change');
|
||||
}
|
||||
|
||||
@override
|
||||
void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
|
||||
print('onError -- ${bloc.runtimeType}, $error');
|
||||
super.onError(bloc, error, stackTrace);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose(BlocBase bloc) {
|
||||
super.onClose(bloc);
|
||||
print('onClose -- ${bloc.runtimeType}');
|
||||
}
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'constants.dart';
|
||||
|
||||
class LocalizationService {
|
||||
static saveLocale(Locale locale) async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
@ -14,13 +12,13 @@ class LocalizationService {
|
||||
|
||||
static Future<Locale> savedLocale() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
var savedLanguageCode = prefs.getString(KeyConstants.languageCode);
|
||||
var savedCountryCode = prefs.getString(KeyConstants.countryCode);
|
||||
// var savedLanguageCode = prefs.getString(Constants.languageCode);
|
||||
// var savedCountryCode = prefs.getString(Constants.countryCode);
|
||||
var savedLocale = const Locale("ar", "JO");
|
||||
|
||||
if (savedCountryCode != null && savedLanguageCode != null) {
|
||||
savedLocale = Locale(savedLanguageCode, savedCountryCode);
|
||||
}
|
||||
// if (savedCountryCode != null && savedLanguageCode != null) {
|
||||
// savedLocale = Locale(savedLanguageCode, savedCountryCode);
|
||||
// }
|
||||
|
||||
return savedLocale;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class ParserHelper {
|
||||
//todo : convert to extension
|
||||
static int parseInt(String value) {
|
||||
int result;
|
||||
try {
|
@ -4,6 +4,7 @@ class ImageManager {
|
||||
static const String whiteLogo = '$base/white-logo.png';
|
||||
static const String blackLogo = '$base/black-logo.png';
|
||||
static const String boxEmpty = '$base/box-empty.jpg';
|
||||
static const String automation = '$base/automation.jpg';
|
||||
}
|
||||
|
||||
class IconsManager {
|
45
lib/utils/resource_manager/font_manager.dart
Normal file
@ -0,0 +1,45 @@
|
||||
import 'dart:ui';
|
||||
|
||||
/// # To add custom fonts to your application, add a fonts section here,
|
||||
/// # in this "flutter" section. Each entry in this list should have a
|
||||
/// # "family" key with the font family name, and a "fonts" key with a
|
||||
/// # list giving the asset and other descriptors for the font. For
|
||||
/// # example:
|
||||
///
|
||||
/// fonts:
|
||||
/// - family:Montserrat
|
||||
/// fonts:
|
||||
/// - asset: assets/ fonts/Montserrat-Botd. ttf
|
||||
/// weight: 700
|
||||
/// - asset: assets/ fonts/Montserrat-SemiB01d. ttf
|
||||
/// weight: 600
|
||||
|
||||
class FontsManager {
|
||||
static const FontWeight light = FontWeight.w300;
|
||||
static const FontWeight regular = FontWeight.w400;
|
||||
static const FontWeight medium = FontWeight.w500;
|
||||
static const FontWeight semiBold = FontWeight.w600;
|
||||
static const FontWeight bold = FontWeight.w700;
|
||||
static const FontWeight extraBold = FontWeight.w800;
|
||||
static const FontWeight black = FontWeight.w900;
|
||||
|
||||
static const String fontFamily = 'Aftika';
|
||||
}
|
||||
|
||||
class FontSize {
|
||||
static const double s12 = 12;
|
||||
static const double s10 = 10;
|
||||
static const double s14 = 14;
|
||||
static const double s16 = 16;
|
||||
static const double s18 = 18;
|
||||
static const double s20 = 20;
|
||||
static const double s21 = 21;
|
||||
static const double s22 = 22;
|
||||
static const double s24 = 24;
|
||||
static const double s25 = 25;
|
||||
static const double s26 = 26;
|
||||
static const double s28 = 28;
|
||||
static const double s30 = 30;
|
||||
static const double s35 = 35;
|
||||
static const double s48 = 48;
|
||||
}
|
87
lib/utils/resource_manager/styles_manager.dart
Normal file
@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'font_manager.dart';
|
||||
|
||||
TextStyle _getTextStyle({
|
||||
required double fontSize,
|
||||
required Color color,
|
||||
required FontWeight fontWeight,
|
||||
}) =>
|
||||
TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: fontWeight,
|
||||
);
|
||||
|
||||
/// regular style
|
||||
TextStyle getTextStyleRegular({
|
||||
required Color color,
|
||||
double fontSize = FontSize.s14,
|
||||
fontWeight = FontsManager.regular,
|
||||
}) =>
|
||||
_getTextStyle(
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: fontWeight,
|
||||
);
|
||||
|
||||
/// light style
|
||||
TextStyle getTextStyleLight({
|
||||
required Color color,
|
||||
double fontSize = FontSize.s12,
|
||||
fontWeight = FontsManager.light,
|
||||
}) =>
|
||||
_getTextStyle(
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: fontWeight,
|
||||
);
|
||||
|
||||
/// medium style
|
||||
TextStyle getTextStyleMedium({
|
||||
required Color color,
|
||||
double fontSize = FontSize.s16,
|
||||
fontWeight = FontsManager.medium,
|
||||
}) =>
|
||||
_getTextStyle(
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: fontWeight,
|
||||
);
|
||||
|
||||
/// semi bold style
|
||||
TextStyle getTextStyleSemiBold({
|
||||
required Color color,
|
||||
double fontSize = FontSize.s18,
|
||||
fontWeight = FontsManager.semiBold,
|
||||
}) =>
|
||||
_getTextStyle(
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: fontWeight,
|
||||
);
|
||||
|
||||
/// bold style
|
||||
TextStyle getTextStyleBold({
|
||||
required Color color,
|
||||
double fontSize = FontSize.s20,
|
||||
fontWeight = FontsManager.bold,
|
||||
}) =>
|
||||
_getTextStyle(
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: fontWeight,
|
||||
);
|
||||
|
||||
/// extra bold style
|
||||
TextStyle getTextStyleExtraBold({
|
||||
required Color color,
|
||||
double fontSize = FontSize.s22,
|
||||
fontWeight = FontsManager.extraBold,
|
||||
}) =>
|
||||
_getTextStyle(
|
||||
fontSize: fontSize,
|
||||
color: color,
|
||||
fontWeight: fontWeight,
|
||||
);
|
156
lib/utils/resource_manager/theme_manager.dart
Normal file
@ -0,0 +1,156 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'color_manager.dart';
|
||||
import 'font_manager.dart';
|
||||
|
||||
ThemeData myTheme = ThemeData(
|
||||
///main colors
|
||||
primaryColor: ColorsManager.primaryColor,
|
||||
// colorScheme: ColorsManager.lightColorScheme,
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
|
||||
///text theme
|
||||
textTheme: const TextTheme(
|
||||
///display
|
||||
displayLarge: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s35,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
displayMedium: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s20,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
displaySmall: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s16,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
|
||||
///title
|
||||
titleLarge: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s48,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
titleMedium: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s30,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
titleSmall: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s25,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
|
||||
///body
|
||||
bodyLarge: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s18,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
bodyMedium: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s14,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
bodySmall: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s12,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
|
||||
labelLarge: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s18,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
labelMedium: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s16,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
labelSmall: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontSize: FontSize.s14,
|
||||
fontWeight: FontsManager.regular,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
|
||||
///button theme
|
||||
// buttonTheme: ButtonThemeData(
|
||||
// buttonColor: ColorsManager.primaryLightColor,
|
||||
// padding: const EdgeInsets.symmetric(horizontal: AppPadding.p8),
|
||||
// textTheme: ButtonTextTheme.primary,
|
||||
// hoverColor: ColorsManager.primaryDarkColor,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(AppRadius.r4),
|
||||
// ),),
|
||||
//
|
||||
// textButtonTheme: TextButtonThemeData(
|
||||
// style: ButtonStyle(
|
||||
// backgroundColor:
|
||||
// MaterialStateProperty.all<Color>(ColorsManager.primaryLightColor),
|
||||
// padding: MaterialStateProperty.all<EdgeInsets>(
|
||||
// const EdgeInsets.all(AppPadding.p8),),
|
||||
// textStyle: MaterialStateProperty.all<TextStyle>(
|
||||
// const TextStyle(
|
||||
// fontFamily: FontsManager.fontFamily,
|
||||
// fontSize: FontSize.s16,
|
||||
// fontWeight: FontsManager.regular,
|
||||
// color: ColorsManager.onPrimaryLightColor,
|
||||
// ),
|
||||
// ),
|
||||
// // shape: MaterialStateProperty.all<OutlinedBorder>(
|
||||
// // RoundedRectangleBorder(
|
||||
// // borderRadius: BorderRadius.circular(AppRadius.r4),
|
||||
// // side: const BorderSide(color: Colors.grey),
|
||||
// // ),
|
||||
// // ),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
///input decoration theme
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.grey),
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: ColorsManager.primaryColor),
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
labelStyle: TextStyle(
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
color: Colors.grey,
|
||||
fontSize: FontSize.s16,
|
||||
fontWeight: FontsManager.regular,
|
||||
),
|
||||
),
|
||||
|
||||
///card theme
|
||||
//TODO edit card theme
|
||||
cardTheme: const CardTheme(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
),
|
||||
);
|
@ -1,44 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Responsive extends StatelessWidget {
|
||||
final Widget mobile;
|
||||
final Widget? tablet;
|
||||
final Widget desktop;
|
||||
|
||||
const Responsive({
|
||||
super.key,
|
||||
required this.mobile,
|
||||
this.tablet,
|
||||
required this.desktop,
|
||||
});
|
||||
|
||||
// This size work fine on my design, maybe you need some customization depends on your design
|
||||
|
||||
// This isMobile, isTablet, isDesktop help us later
|
||||
static bool isMobile(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width < 850;
|
||||
|
||||
static bool isTablet(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width < 1100 &&
|
||||
MediaQuery.of(context).size.width >= 850;
|
||||
|
||||
static bool isDesktop(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width >= 1100;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Size size = MediaQuery.of(context).size;
|
||||
// If our width is more than 1100 then we consider it a desktop
|
||||
if (size.width >= 1100) {
|
||||
return desktop;
|
||||
}
|
||||
// If width it less then 1100 and more then 850 we consider it as tablet
|
||||
else if (size.width >= 850 && tablet != null) {
|
||||
return tablet!;
|
||||
}
|
||||
// Or less then that we called it mobile
|
||||
else {
|
||||
return mobile;
|
||||
}
|
||||
}
|
||||
}
|
18
pubspec.lock
@ -17,6 +17,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.0"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
sha256: f53a110e3b48dcd78136c10daa5d51512443cea5e1348c9d80a320095fa2db9e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.3"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -206,6 +214,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flutter_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
sha256: "87325da1ac757fcc4813e6b34ed5dd61169973871fdf181d6c2109dd6935ece1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.4"
|
||||
flutter_cache_manager:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -470,7 +486,7 @@ packages:
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: provider
|
||||
sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"
|
||||
|
12
pubspec.yaml
@ -28,7 +28,7 @@ dependencies:
|
||||
url_launcher: ^6.2.4
|
||||
dio: ^5.4.0
|
||||
flutter_localization: ^0.2.0
|
||||
provider: ^6.1.1
|
||||
flutter_bloc: ^8.1.4
|
||||
firebase_core: ^2.25.4
|
||||
firebase_analytics: ^10.8.5
|
||||
firebase_crashlytics: ^3.4.14
|
||||
@ -45,12 +45,10 @@ flutter:
|
||||
- assets/images/
|
||||
- assets/icons/
|
||||
- assets/fonts/
|
||||
#fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
fonts:
|
||||
- family: Aftika
|
||||
fonts:
|
||||
- asset: assets/fonts/AftikaRegular.ttf
|
||||
#
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
|