initialized Application theme

This commit is contained in:
Mohammad Salameh
2024-02-15 14:00:09 +03:00
parent 16f47f744c
commit 3190361901
98 changed files with 871 additions and 1004 deletions

View File

@ -24,7 +24,7 @@ if (flutterVersionName == null) {
android { android {
namespace "com.example.syncrow_app" namespace "com.example.syncrow_app"
compileSdkVersion flutter.compileSdkVersion compileSdkVersion 34
ndkVersion flutter.ndkVersion ndkVersion flutter.ndkVersion
compileOptions { compileOptions {

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

BIN
assets/icons/Devices.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

BIN
assets/icons/Layout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

BIN
assets/icons/Menu-fill.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

BIN
assets/icons/Menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

BIN
assets/icons/Routines.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

BIN
assets/icons/dashboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

View File

@ -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: '',
);
}

View File

@ -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),
],
),
),
),
);
}
}

View 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());
}

View File

@ -0,0 +1,6 @@
part of 'auth_cubit.dart';
@immutable
abstract class AuthState {}
class AuthInitial extends AuthState {}

View 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(),
);
},
);
}
}

View 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),
],
),
);
}
}

View 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);
}

View File

@ -0,0 +1,5 @@
part of 'dashboard_cubit.dart';
abstract class DashboardState {}
class DashboardInitial extends DashboardState {}

View 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();
}
}

View File

@ -1,29 +1,31 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_app/features/home/model/device_model.dart'; import 'package:flutter_bloc/flutter_bloc.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 'home_state.dart'; import '../../profile/view/profile_view.dart';
import 'widgets/home_view_body.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 { part 'home_state.dart';
HomeProvider() {
print('HomeProvider created'); class HomeCubit extends Cubit<HomeState> {
HomeCubit() : super(HomeInitial()) {
getDevices(); getDevices();
} }
HomeState state = HomeState(); //TODO separate the navigation logic to another cubit
static HomeCubit get(context) => BlocProvider.of(context);
static int pageIndex = 0; static int pageIndex = 0;
var devices = <DeviceModel>[]; var devices = <DeviceModel>[];
Future<List<DeviceModel>> getDevices() async { Future<List<DeviceModel>> getDevices() async {
state.setLoading(); emit(HomeLoading());
await Future.delayed(const Duration(seconds: 2)); await Future.delayed(const Duration(seconds: 2));
state.setSuccess(); emit(HomeSuccess());
notifyListeners();
return devices = []; return devices = [];
} }
@ -64,19 +66,15 @@ class HomeProvider extends ChangeNotifier {
final List<Widget> pages = [ final List<Widget> pages = [
const HomeViewBody(), const HomeViewBody(),
const ScenePage(), const SceneView(),
const SmartPage(), const SmartPage(),
const ProfilePage(), const ProfileView(),
]; ];
Widget getCurrentPage() { static Widget get currentPage => HomeCubit().pages[pageIndex];
notifyListeners();
return pages[pageIndex];
}
void updatePageIndex(int index, BuildContext context) { void updatePageIndex(int index, BuildContext context) {
emit(HomeChangeIndex());
pageIndex = index; pageIndex = index;
notifyListeners();
} }
} }

View 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 {}

View File

@ -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;
}
}

View File

@ -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(),
);
},
),
);
}
}

View 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(),
);
},
),
);
}
}

View 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();
},
));
}
}

View 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',
),
],
),
);
}
}

View File

@ -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();
},
),
);
}
}

View 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());
}

View File

@ -0,0 +1,6 @@
part of 'profile_cubit.dart';
@immutable
abstract class ProfileState {}
class ProfileInitial extends ProfileState {}

View File

@ -1,7 +0,0 @@
import 'package:flutter/material.dart';
import 'profile_state.dart';
class ProfileProvider extends ChangeNotifier {
final state = ProfileState();
}

View File

@ -1,6 +0,0 @@
class ProfileState {
ProfileState() {
// init some variables
}
}

View File

@ -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'),
),
);
}
}

View 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'),
);
},
),
);
}
}

View 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>[];
}

View 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 {}

View 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'],
);
}
}

View File

@ -1,7 +0,0 @@
import 'package:flutter/material.dart';
import 'scene_state.dart';
class SceneProvider extends ChangeNotifier {
final state = SceneState();
}

View File

@ -1,6 +0,0 @@
class SceneState {
SceneState() {
// init some variables
}
}

View File

@ -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'),
),
);
}
}

View 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();
},
),
);
}
}

View 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',
)
],
),
),
);
}
}

View File

@ -1,17 +1,16 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/home/widgets/syncrow_logo.dart'; import 'package:syncrow_app/features/home/bloc/home_cubit.dart';
import 'package:syncrow_app/resource_manager/color_manager.dart'; import 'package:syncrow_app/features/shared_widgets/syncrow_logo.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import '../home_provider.dart';
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
const DefaultAppBar({super.key}); const DefaultAppBar({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<HomeProvider>( return BlocBuilder<HomeCubit, HomeState>(
builder: (context, provider, child) { builder: (context, state) {
return AppBar( return AppBar(
title: const SyncrowLogo(), title: const SyncrowLogo(),
actions: <Widget>[ actions: <Widget>[

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/home/bloc/home_cubit.dart';
import '../home/home_provider.dart'; import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class DefaultNavBar extends StatelessWidget { class DefaultNavBar extends StatelessWidget {
const DefaultNavBar({ const DefaultNavBar({
@ -10,15 +10,19 @@ class DefaultNavBar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<HomeProvider>( return BlocBuilder<HomeCubit, HomeState>(
builder: (context, provider, child) { builder: (context, state) {
return BottomNavigationBar( return BottomNavigationBar(
onTap: (int index) => provider.updatePageIndex(index, context), onTap: (int index) =>
currentIndex: HomeProvider.pageIndex, HomeCubit.get(context).updatePageIndex(index, context),
selectedItemColor: Colors.black, currentIndex: HomeCubit.pageIndex,
selectedItemColor: ColorsManager.primaryColor,
selectedLabelStyle: const TextStyle(
color: ColorsManager.primaryColor,
),
unselectedItemColor: Colors.grey, unselectedItemColor: Colors.grey,
elevation: 10, elevation: 10,
items: provider.bottomNavItems, items: HomeCubit.get(context).bottomNavItems,
); );
}, },
); );

View File

@ -1,25 +1,25 @@
import 'package:flutter/material.dart'; 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 { class DefaultTextButton extends StatelessWidget {
const DefaultTextButton({ const DefaultTextButton({
super.key, super.key,
this.onPressed, this.onPressed,
required this.text, required this.text,
this.isPrimary = false, this.isSecondary = false,
}); });
final void Function()? onPressed; final void Function()? onPressed;
final String text; final String text;
final bool isSecondary;
final bool isPrimary;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return TextButton( return TextButton(
onPressed: onPressed, onPressed: onPressed,
style: isPrimary style: isSecondary
? ButtonStyle( ? null
: ButtonStyle(
backgroundColor: backgroundColor:
MaterialStateProperty.all(ColorsManager.primaryColor), MaterialStateProperty.all(ColorsManager.primaryColor),
shape: MaterialStateProperty.all( shape: MaterialStateProperty.all(
@ -27,11 +27,10 @@ class DefaultTextButton extends StatelessWidget {
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
), ),
), ),
) ),
: null,
child: Text( child: Text(
text, text,
style: TextStyle(color: isPrimary ? Colors.white : Colors.black), style: TextStyle(color: isSecondary ? Colors.black : Colors.white),
), ),
); );
} }

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; 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 { class SyncrowLogo extends StatelessWidget {
const SyncrowLogo({ const SyncrowLogo({

View 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());
}

View File

@ -0,0 +1,6 @@
part of 'smart_cubit.dart';
@immutable
abstract class SmartState {}
class SmartInitial extends SmartState {}

View File

@ -1,7 +0,0 @@
import 'package:flutter/material.dart';
import 'smart_state.dart';
class SmartProvider extends ChangeNotifier {
final state = SmartState();
}

View File

@ -1,6 +0,0 @@
class SmartState {
SmartState() {
// init some variables
}
}

View File

@ -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'),
),
);
}
}

View 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'),
);
},
));
}
}

View File

@ -1,30 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_app/features/splash/user_agreement_dialog.dart'; import 'package:syncrow_app/features/splash/view/widgets/user_agreement_dialog.dart';
import 'package:syncrow_app/navigation/route_manager.dart';
import 'package:syncrow_app/navigation/routing_constants.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 { class SplashView extends StatelessWidget {
const SplashView({super.key}); const SplashView({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
//TODO Remove delay
// Future.delayed(const Duration(seconds: 5), () {
// RouteManager().routerManagerPushUntil(
// context,
// routeName: Routes.homeRoute,
// );
// });
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.arrow_forward), icon: const Icon(Icons.arrow_forward),
onPressed: () { onPressed: () {
RouteManager().routerManagerPopAndPushNamed( Navigator.popAndPushNamed(
routeName: Routes.authRoute, context,
context: context, Routes.authRoute,
); );
}, },
), ),

View File

@ -19,11 +19,11 @@ class UserAgreementDialog extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
isPrimary: true,
), ),
DefaultTextButton( DefaultTextButton(
text: 'I Disagree', text: 'I Disagree',
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
isSecondary: true,
), ),
], ],
); );

View File

@ -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';
}

View File

@ -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);
}
}
}

View File

@ -1,8 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/utils/bloc_observer.dart';
import 'my_app.dart'; import 'my_app.dart';
void main() { void main() {
Bloc.observer = MyBlocObserver();
//TODO: Uncomment
// runZonedGuarded(() async { // runZonedGuarded(() async {
// const environment = // const environment =
// String.fromEnvironment('FLAVOR', defaultValue: 'production'); // String.fromEnvironment('FLAVOR', defaultValue: 'production');
@ -10,9 +14,6 @@ void main() {
// //
// HttpOverrides.global = MyHttpOverrides(); // HttpOverrides.global = MyHttpOverrides();
// WidgetsFlutterBinding.ensureInitialized(); // WidgetsFlutterBinding.ensureInitialized();
// // if (Platform.isAndroid) {
// // await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
// // }
// LicenseRegistry.addLicense(() async* { // LicenseRegistry.addLicense(() async* {
// final license = // final license =
// await rootBundle.loadString('assets/fonts/roboto/LICENSE.txt'); // await rootBundle.loadString('assets/fonts/roboto/LICENSE.txt');

View File

@ -1,50 +1,44 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart'; import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
import 'package:syncrow_app/resource_manager/color_manager.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/router.dart' as router;
import 'navigation/routing_constants.dart'; import 'navigation/routing_constants.dart';
import 'services/navigation_service.dart';
class MyApp extends StatefulWidget { class MyApp extends StatelessWidget {
final Locale locale; final Locale locale;
const MyApp(this.locale, {super.key}); const MyApp(this.locale, {super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const SystemUiOverlayStyle( return MultiBlocProvider(
statusBarColor: Colors.transparent, 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', ''),
));
} }
} }

View File

@ -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);
}
}

View File

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_app/features/auth/auth_view.dart'; import 'package:syncrow_app/features/auth/view/auth_view.dart';
import 'package:syncrow_app/features/home/home_view.dart'; import 'package:syncrow_app/features/home/view/home_view.dart';
import 'package:syncrow_app/features/profile/profile_view.dart'; import 'package:syncrow_app/features/profile/view/profile_view.dart';
import 'package:syncrow_app/features/scene/scene_view.dart'; import 'package:syncrow_app/features/scene/view/scene_view.dart';
import 'package:syncrow_app/features/smart/smart_view.dart'; import 'package:syncrow_app/features/smart/view/smart_view.dart';
import 'package:syncrow_app/features/splash/splash_view.dart'; import 'package:syncrow_app/features/splash/view/splash_view.dart';
import 'routing_constants.dart'; import 'routing_constants.dart';
@ -17,15 +17,15 @@ class Router {
case Routes.homeRoute: case Routes.homeRoute:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => const HomePage(), settings: settings); builder: (_) => const HomeView(), settings: settings);
case Routes.profileRoute: case Routes.profileRoute:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => const ProfilePage(), settings: settings); builder: (_) => const ProfileView(), settings: settings);
case Routes.sceneRoute: case Routes.sceneRoute:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => const ScenePage(), settings: settings); builder: (_) => const SceneView(), settings: settings);
case Routes.smartRoute: case Routes.smartRoute:
return MaterialPageRoute( return MaterialPageRoute(
@ -33,7 +33,7 @@ class Router {
case Routes.authRoute: case Routes.authRoute:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => const AuthPage(), settings: settings); builder: (_) => const AuthView(), settings: settings);
default: default:
return MaterialPageRoute( return MaterialPageRoute(

View File

@ -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;
// }

View File

@ -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()),
// ];
// }

View File

@ -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,
// );

View File

@ -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)),
// ),
// ),
// );

View File

@ -1,10 +1,9 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.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 'package:syncrow_app/services/locator.dart';
import 'http_interceptor.dart';
class HTTPService { class HTTPService {
final Dio client = locator<Dio>(); final Dio client = locator<Dio>();
final navigatorKey = GlobalKey<NavigatorState>(); final navigatorKey = GlobalKey<NavigatorState>();
@ -44,8 +43,6 @@ class HTTPService {
bool showServerMessage = true, bool showServerMessage = true,
}) async { }) async {
try { try {
SharedPreferencesHelper.saveBoolToSP(
KeyConstants.showServerMessage, showServerMessage);
final response = await client.get( final response = await client.get(
path, path,
queryParameters: queryParameters, queryParameters: queryParameters,
@ -66,8 +63,6 @@ class HTTPService {
bool showServerMessage = true, bool showServerMessage = true,
required T Function(dynamic) expectedResponseModel}) async { required T Function(dynamic) expectedResponseModel}) async {
try { try {
SharedPreferencesHelper.saveBoolToSP(
KeyConstants.showServerMessage, showServerMessage);
final response = await client.post(path, final response = await client.post(path,
data: body, queryParameters: queryParameters, options: options); data: body, queryParameters: queryParameters, options: options);
debugPrint("status code is ${response.statusCode}"); debugPrint("status code is ${response.statusCode}");

View File

@ -1,6 +1,6 @@
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import '../api/http_interceptor.dart'; import 'api/http_interceptor.dart';
GetIt locator = GetIt.instance; GetIt locator = GetIt.instance;

View File

@ -1,6 +0,0 @@
import 'package:flutter/material.dart';
class NavigationService {
static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
static GlobalKey<ScaffoldMessengerState>? snackbarKey = GlobalKey<ScaffoldMessengerState>();
}

View 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}');
}
}

View File

@ -1,8 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'constants.dart';
class LocalizationService { class LocalizationService {
static saveLocale(Locale locale) async { static saveLocale(Locale locale) async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
@ -14,13 +12,13 @@ class LocalizationService {
static Future<Locale> savedLocale() async { static Future<Locale> savedLocale() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
var savedLanguageCode = prefs.getString(KeyConstants.languageCode); // var savedLanguageCode = prefs.getString(Constants.languageCode);
var savedCountryCode = prefs.getString(KeyConstants.countryCode); // var savedCountryCode = prefs.getString(Constants.countryCode);
var savedLocale = const Locale("ar", "JO"); var savedLocale = const Locale("ar", "JO");
if (savedCountryCode != null && savedLanguageCode != null) { // if (savedCountryCode != null && savedLanguageCode != null) {
savedLocale = Locale(savedLanguageCode, savedCountryCode); // savedLocale = Locale(savedLanguageCode, savedCountryCode);
} // }
return savedLocale; return savedLocale;
} }

View File

@ -1,6 +1,7 @@
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
class ParserHelper { class ParserHelper {
//todo : convert to extension
static int parseInt(String value) { static int parseInt(String value) {
int result; int result;
try { try {

View File

@ -4,6 +4,7 @@ class ImageManager {
static const String whiteLogo = '$base/white-logo.png'; static const String whiteLogo = '$base/white-logo.png';
static const String blackLogo = '$base/black-logo.png'; static const String blackLogo = '$base/black-logo.png';
static const String boxEmpty = '$base/box-empty.jpg'; static const String boxEmpty = '$base/box-empty.jpg';
static const String automation = '$base/automation.jpg';
} }
class IconsManager { class IconsManager {

View 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;
}

View 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,
);

View 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)),
),
),
);

View File

@ -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;
}
}
}

View File

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.11.0" version: "2.11.0"
bloc:
dependency: transitive
description:
name: bloc
sha256: f53a110e3b48dcd78136c10daa5d51512443cea5e1348c9d80a320095fa2db9e
url: "https://pub.dev"
source: hosted
version: "8.1.3"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -206,6 +214,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" 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: flutter_cache_manager:
dependency: transitive dependency: transitive
description: description:
@ -470,7 +486,7 @@ packages:
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
provider: provider:
dependency: "direct main" dependency: transitive
description: description:
name: provider name: provider
sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096"

View File

@ -28,7 +28,7 @@ dependencies:
url_launcher: ^6.2.4 url_launcher: ^6.2.4
dio: ^5.4.0 dio: ^5.4.0
flutter_localization: ^0.2.0 flutter_localization: ^0.2.0
provider: ^6.1.1 flutter_bloc: ^8.1.4
firebase_core: ^2.25.4 firebase_core: ^2.25.4
firebase_analytics: ^10.8.5 firebase_analytics: ^10.8.5
firebase_crashlytics: ^3.4.14 firebase_crashlytics: ^3.4.14
@ -45,12 +45,10 @@ flutter:
- assets/images/ - assets/images/
- assets/icons/ - assets/icons/
- assets/fonts/ - assets/fonts/
#fonts: fonts:
# - family: Schyler - family: Aftika
# fonts: fonts:
# - asset: fonts/Schyler-Regular.ttf - asset: assets/fonts/AftikaRegular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# #
# - family: Trajan Pro # - family: Trajan Pro
# fonts: # fonts: