mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-08-25 22:49:39 +00:00
Compare commits
11 Commits
76da7debfd
...
Add-Bookin
Author | SHA1 | Date | |
---|---|---|---|
bae6a09a87 | |||
6f0e83b95b | |||
15b6d642ff | |||
99852464c7 | |||
4ac6077011 | |||
d5321a9ca0 | |||
9d507f30eb | |||
029e36ee3d | |||
dd55d5c082 | |||
09dc8cc330 | |||
f7245e5de9 |
10
assets/icons/booking_icon.svg
Normal file
10
assets/icons/booking_icon.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_11681_2046)">
|
||||
<path d="M20.615 14.4212L18.9717 5.10949C18.62 3.11866 16.89 1.66699 14.8684 1.66699H6.46502C3.58336 1.66699 2.57836 3.87949 2.36169 5.10949L0.726691 14.3703C0.625024 14.9487 0.646691 15.5512 0.848357 16.102C1.35502 17.4895 2.62252 18.3337 4.00086 18.3337C4.00086 18.3337 4.93586 18.3287 4.98752 18.3187C5.35502 18.2495 5.60836 17.9462 5.64919 17.5928C5.14919 16.9095 4.77586 16.122 4.61086 15.2453L3.61836 9.97616C3.47252 9.20199 3.47586 8.40866 3.62752 7.63532C3.86252 6.43866 4.20669 4.74033 4.29836 4.58199L6.24752 14.937C6.61836 16.9062 8.33836 18.3328 10.3425 18.3328H17.2109C17.9684 18.3328 18.7284 18.1287 19.3317 17.6695C20.3575 16.8895 20.83 15.6403 20.615 14.4212ZM8.16669 6.66699C8.16669 6.20699 8.54002 5.83366 9.00002 5.83366H14.8334C15.2934 5.83366 15.6667 6.20699 15.6667 6.66699C15.6667 7.12699 15.2934 7.50033 14.8334 7.50033H9.00002C8.54002 7.50033 8.16669 7.12699 8.16669 6.66699ZM8.77586 10.0003C8.77586 9.54033 9.14919 9.16699 9.60919 9.16699H15.4425C15.9025 9.16699 16.2759 9.54033 16.2759 10.0003C16.2759 10.4603 15.9025 10.8337 15.4425 10.8337H9.60919C9.14919 10.8337 8.77586 10.4603 8.77586 10.0003ZM16.0834 14.167H10.25C9.79002 14.167 9.41669 13.7945 9.41669 13.3337C9.41669 12.8728 9.79002 12.5003 10.25 12.5003H16.0834C16.5434 12.5003 16.9167 12.8728 16.9167 13.3337C16.9167 13.7945 16.5434 14.167 16.0834 14.167Z" fill="#999999"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_11681_2046">
|
||||
<rect width="20" height="20" fill="white" transform="translate(0.666687)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -12,6 +12,7 @@ import 'package:syncrow_app/features/app_layout/model/space_model.dart';
|
||||
import 'package:syncrow_app/features/app_layout/view/widgets/app_bar_home_dropdown.dart';
|
||||
import 'package:syncrow_app/features/auth/model/project_model.dart';
|
||||
import 'package:syncrow_app/features/auth/model/user_model.dart';
|
||||
import 'package:syncrow_app/features/booking_system/presentation/screens/booking_system_page.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/subspace_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
|
||||
@ -32,6 +33,7 @@ import 'package:syncrow_app/services/api/spaces_api.dart';
|
||||
import 'package:syncrow_app/utils/constants/temp_const.dart';
|
||||
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
|
||||
part 'home_state.dart';
|
||||
|
||||
class HomeCubit extends Cubit<HomeState> {
|
||||
@ -479,7 +481,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
],
|
||||
'Routine': [
|
||||
'Automation': [
|
||||
// IconButton(
|
||||
// icon: Image.asset(
|
||||
// Assets.assetsIconsFilter,
|
||||
@ -538,6 +540,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
],
|
||||
'Booking': [],
|
||||
'Menu': [
|
||||
// IconButton(
|
||||
// icon: SvgPicture.asset(
|
||||
@ -553,7 +556,19 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
static Map<String, Widget?> appBarLeading = {
|
||||
// 'Dashboard': const AppBarHomeDropdown(),
|
||||
'Devices': const AppBarHomeDropdown(),
|
||||
'Routine': const AppBarHomeDropdown(),
|
||||
'Automation': const AppBarHomeDropdown(),
|
||||
'Booking': Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Text(
|
||||
'Booking',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.textPrimaryColor,
|
||||
fontSize: 26,
|
||||
fontFamily: FontsManager.fontFamily,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
'Menu': Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Image.asset(
|
||||
@ -569,7 +584,9 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
// defaultBottomNavBarItem(icon: Assets.assetsIconsDashboard, label: 'Dashboard'),
|
||||
// defaultBottomNavBarItem(icon: Assets.assetsIconslayout, label: 'Layout'),
|
||||
defaultBottomNavBarItem(icon: Assets.assetsIconsDevices, label: 'Devices'),
|
||||
defaultBottomNavBarItem(icon: Assets.assetsIconsRoutines, label: 'Routine'),
|
||||
defaultBottomNavBarItem(
|
||||
icon: Assets.assetsIconsRoutines, label: 'Automation'),
|
||||
defaultBottomNavBarItem(icon: Assets.bookingIcon, label: 'Booking'),
|
||||
defaultBottomNavBarItem(icon: Assets.assetsIconsMenu, label: 'Menu'),
|
||||
];
|
||||
|
||||
@ -581,6 +598,7 @@ class HomeCubit extends Cubit<HomeState> {
|
||||
child: const DevicesViewBody(),
|
||||
),
|
||||
const RoutinesView(),
|
||||
const BookingSystemPage(),
|
||||
const MenuView(),
|
||||
];
|
||||
|
||||
@ -616,7 +634,6 @@ BottomNavigationBarItem defaultBottomNavBarItem(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// class PermissionUtils {
|
||||
// // Check if the "VIEW" permission exists in "MANAGE_SUBSPACE"
|
||||
// static bool hasViewPermission(List<dynamic> permissions) {
|
||||
|
@ -3,9 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/booking_system/data/booking_dummy_source.dart';
|
||||
import 'package:syncrow_app/features/booking_system/presentation/blocs/upcoming_bookings_bloc/upcoming_bookings_bloc.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import '../blocs/past_bookings_bloc/past_bookings_bloc.dart';
|
||||
import '../widgets/booking_appbar_widget.dart';
|
||||
import '../widgets/current_balance_widget.dart';
|
||||
import '../widgets/past_booking_widget.dart';
|
||||
import '../widgets/upcoming_bookings_widget.dart';
|
||||
@ -26,41 +24,35 @@ class BookingSystemPage extends StatelessWidget {
|
||||
..add(GetPastBookingsEvent()),
|
||||
)
|
||||
],
|
||||
child: DefaultScaffold(
|
||||
appBar: BookingAppBar(),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 20,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CurrentBalanceWidget(
|
||||
userBalance: HomeCubit.user!.points == null
|
||||
? '0'
|
||||
: HomeCubit.user!.points.toString(),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: CurrentBalanceWidget(
|
||||
userBalance: HomeCubit.user!.points == null
|
||||
? '0'
|
||||
: HomeCubit.user!.points.toString(),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: Column(
|
||||
children: [
|
||||
UpcomingBookingsWidget(),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
PastBookingsWidget(),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: Column(
|
||||
children: [
|
||||
UpcomingBookingsWidget(),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
PastBookingsWidget(),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
@ -10,10 +10,7 @@ class BookingAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
return AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
centerTitle: true,
|
||||
leading: IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: Icon(Icons.arrow_back_ios_new)),
|
||||
title: Text(
|
||||
leading: Text(
|
||||
'Booking',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.blueColor1,
|
||||
|
@ -39,7 +39,7 @@ class PastBookingsWidget extends StatelessWidget {
|
||||
);
|
||||
} else if (state is PastBookingLoadedState) {
|
||||
return SizedBox(
|
||||
height: deviceHeight(context) * 0.3,
|
||||
height: deviceHeight(context) * 0.22,
|
||||
child: state.pastBookings.isEmpty
|
||||
? Text('You Dont Have past Bookings')
|
||||
: ListView.separated(
|
||||
|
@ -45,18 +45,6 @@ class MenuCubit extends Cubit<MenuState> {
|
||||
}
|
||||
|
||||
List<Map<String, Object>> menuSections = [
|
||||
//Booking System
|
||||
{
|
||||
'title': 'Booking System',
|
||||
'color': const Color(0xFF8AB9FF),
|
||||
'buttons': [
|
||||
{
|
||||
'title': 'Booking',
|
||||
'Icon': Assets.assetsIconsMenuBookingSystem,
|
||||
'page': BookingSystemPage()
|
||||
},
|
||||
],
|
||||
},
|
||||
//Home Management
|
||||
{
|
||||
'title': 'Home Management',
|
||||
|
@ -262,6 +262,17 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
||||
if (parts.any((part) => part.length < 2 || part.length > 30)) {
|
||||
return 'Full name parts must be between 2 and 30 characters long';
|
||||
}
|
||||
if (RegExp(r"\s{2,}").hasMatch(value)) {
|
||||
return 'Only one space is allowed between first and last names';
|
||||
}
|
||||
// Check for leading or trailing spaces
|
||||
if (value != value.trim()) {
|
||||
return 'No leading or trailing spaces allowed';
|
||||
}
|
||||
// Check if only alphabetic characters and one space are used
|
||||
if (!RegExp(r'^[A-Za-z]+(?: [A-Za-z]+)?$').hasMatch(value)) {
|
||||
return 'Only alphabetic characters and a single space are allowed';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,15 @@ class RoutinesView extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
final selectedSpace = HomeCubit.getInstance().selectedSpace;
|
||||
if (state is DeleteSceneSuccess) {
|
||||
if (state.success) _loadScenesAndAutomations(context, selectedSpace);
|
||||
if (state.success)
|
||||
_loadScenesAndAutomations(context, selectedSpace);
|
||||
}
|
||||
if (state is CreateSceneWithTasks) {
|
||||
if (state.success) {
|
||||
_loadScenesAndAutomations(context, selectedSpace);
|
||||
context.read<SmartSceneSelectBloc>().add(const SmartSceneClearEvent());
|
||||
context
|
||||
.read<SmartSceneSelectBloc>()
|
||||
.add(const SmartSceneClearEvent());
|
||||
}
|
||||
}
|
||||
return BlocListener<SceneBloc, SceneState>(
|
||||
@ -72,30 +75,28 @@ class RoutinesView extends StatelessWidget {
|
||||
data: Theme.of(context).copyWith(
|
||||
dividerColor: Colors.transparent,
|
||||
),
|
||||
child: Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
RoutinesExpansionTile(
|
||||
title: 'Tap to run routines',
|
||||
emptyRoutinesMessage:
|
||||
'No scenes have been added yet',
|
||||
routines: state.scenes,
|
||||
loadingStates: state.loadingStates,
|
||||
loadingSceneId: state.loadingSceneId,
|
||||
disablePlayButton: false,
|
||||
),
|
||||
RoutinesExpansionTile(
|
||||
title: 'Automation',
|
||||
emptyRoutinesMessage:
|
||||
'No automations have been added yet',
|
||||
routines: state.automationList,
|
||||
loadingStates: state.loadingStates,
|
||||
loadingSceneId: state.loadingSceneId,
|
||||
disablePlayButton: true,
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
],
|
||||
),
|
||||
child: ListView(
|
||||
children: [
|
||||
RoutinesExpansionTile(
|
||||
title: 'Tap to run automations',
|
||||
emptyRoutinesMessage:
|
||||
'No scenes have been added yet',
|
||||
routines: state.scenes,
|
||||
loadingStates: state.loadingStates,
|
||||
loadingSceneId: state.loadingSceneId,
|
||||
disablePlayButton: false,
|
||||
),
|
||||
RoutinesExpansionTile(
|
||||
title: 'Automation',
|
||||
emptyRoutinesMessage:
|
||||
'No automations have been added yet',
|
||||
routines: state.automationList,
|
||||
loadingStates: state.loadingStates,
|
||||
loadingSceneId: state.loadingSceneId,
|
||||
disablePlayButton: true,
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -111,7 +112,8 @@ class RoutinesView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _loadScenesAndAutomations(BuildContext context, SpaceModel? selectedSpace) {
|
||||
void _loadScenesAndAutomations(
|
||||
BuildContext context, SpaceModel? selectedSpace) {
|
||||
context.read<SceneBloc>()
|
||||
..add(LoadScenes(selectedSpace!.id, selectedSpace, showInDevice: false))
|
||||
..add(LoadAutomation(selectedSpace.id, selectedSpace.community.uuid));
|
||||
|
@ -100,7 +100,7 @@ class SceneView extends StatelessWidget {
|
||||
initiallyExpanded: true,
|
||||
iconColor: ColorsManager.grayColor,
|
||||
title: const BodyMedium(
|
||||
text: 'Tap to run routines',
|
||||
text: 'Tap to run automations',
|
||||
),
|
||||
children: [
|
||||
if (scenes.isNotEmpty)
|
||||
|
@ -23,7 +23,7 @@ class DeleteRoutineDialog extends StatelessWidget {
|
||||
height: 10,
|
||||
),
|
||||
const BodyLarge(
|
||||
text: 'Delete Routine',
|
||||
text: 'Delete Automation',
|
||||
fontWeight: FontWeight.w700,
|
||||
fontColor: ColorsManager.red,
|
||||
fontSize: 16,
|
||||
@ -39,7 +39,7 @@ class DeleteRoutineDialog extends StatelessWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
Center(child: const Text('Are you sure you want to ')),
|
||||
Center(child: const Text('delete the routine?'))
|
||||
Center(child: const Text('delete the automation?'))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -52,7 +52,7 @@ class DeleteRoutineButton extends StatelessWidget {
|
||||
},
|
||||
child: const Center(
|
||||
child: Text(
|
||||
'Remove Routine',
|
||||
'Remove Automation',
|
||||
style: TextStyle(color: ColorsManager.red),
|
||||
))
|
||||
// : SceneListTile(
|
||||
|
@ -9,7 +9,7 @@ class EmptyDevicesWidget extends StatelessWidget {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 48),
|
||||
child: Text(
|
||||
"No routines.\nEnable 'Show on Home Screen' to add routines",
|
||||
"No automations.\nEnable 'Show on Home Screen' to add automations",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: ColorsManager.grayColor,
|
||||
|
@ -23,7 +23,7 @@ class EmptyRoutinesWidget extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
BodyMedium(
|
||||
text: 'No Routines yet',
|
||||
text: 'No automations yet',
|
||||
fontColor: ColorsManager.textGray,
|
||||
),
|
||||
],
|
||||
|
@ -1129,6 +1129,7 @@ class Assets {
|
||||
|
||||
static const String verificationIcon = "assets/icons/verification_icon.svg";
|
||||
static const String deleteAccountIcon='assets/icons/delete_account_icon.svg';
|
||||
static const String bookingIcon='assets/icons/booking_icon.svg';
|
||||
static const String passwordUnvisibility =
|
||||
"assets/icons/password_unvisibility.svg";
|
||||
static const String passwordVisibility =
|
||||
|
@ -4,8 +4,8 @@ class StringsManager {
|
||||
|
||||
static const String dashboard = 'Dashboard';
|
||||
static const String devices = 'Devices';
|
||||
static const String routine = 'Routines';
|
||||
static const String tapToRunRoutine = 'Tap to run routine';
|
||||
static const String routine = 'Automation';
|
||||
static const String tapToRunRoutine = 'Tap to run automation';
|
||||
static const String wizard = 'Wizard';
|
||||
static const String active = 'Active';
|
||||
static const String current = 'Current';
|
||||
@ -39,6 +39,6 @@ class StringsManager {
|
||||
'Example: when an unusual activity is detected.';
|
||||
static const String functions = "Functions";
|
||||
static const String firstLaunch = "firstLaunch";
|
||||
static const String deleteScene = 'Remove Routine';
|
||||
static const String deleteScene = 'Remove Automation';
|
||||
static const String deleteAutomation = 'Delete Automation';
|
||||
}
|
||||
|
Reference in New Issue
Block a user