mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-08-26 09:09:41 +00:00
Compare commits
7 Commits
Implement-
...
08e2ed4b4c
Author | SHA1 | Date | |
---|---|---|---|
08e2ed4b4c | |||
59e04708cd | |||
b6664ec1ba | |||
21f8b2962c | |||
645a07287e | |||
e55e793081 | |||
dcf1df9b4a |
@ -2,11 +2,12 @@ import 'package:bloc/bloc.dart';
|
||||
import 'package:syncrow_web/pages/access_management/booking_system/presentation/bloc/date_selection/date_selection_event.dart';
|
||||
import 'date_selection_state.dart';
|
||||
|
||||
|
||||
class DateSelectionBloc extends Bloc<DateSelectionEvent, DateSelectionState> {
|
||||
DateSelectionBloc() : super(DateSelectionState.initial()) {
|
||||
on<SelectDate>((event, emit) {
|
||||
final newWeekStart = _getStartOfWeek(event.selectedDate);
|
||||
emit(DateSelectionState(
|
||||
emit(state.copyWith(
|
||||
selectedDate: event.selectedDate,
|
||||
weekStart: newWeekStart,
|
||||
));
|
||||
@ -14,19 +15,21 @@ class DateSelectionBloc extends Bloc<DateSelectionEvent, DateSelectionState> {
|
||||
|
||||
on<NextWeek>((event, emit) {
|
||||
final newWeekStart = state.weekStart.add(const Duration(days: 7));
|
||||
final inNewWeek = state.selectedDate
|
||||
.isAfter(newWeekStart.subtract(const Duration(days: 1))) &&
|
||||
state.selectedDate
|
||||
.isBefore(newWeekStart.add(const Duration(days: 7)));
|
||||
emit(DateSelectionState(
|
||||
selectedDate: state.selectedDate,
|
||||
emit(state.copyWith(
|
||||
weekStart: newWeekStart,
|
||||
));
|
||||
});
|
||||
|
||||
on<PreviousWeek>((event, emit) {
|
||||
emit(DateSelectionState(
|
||||
selectedDate: state.selectedDate!.subtract(const Duration(days: 7)),
|
||||
weekStart: state.weekStart.subtract(const Duration(days: 7)),
|
||||
final newWeekStart = state.weekStart.subtract(const Duration(days: 7));
|
||||
emit(state.copyWith(
|
||||
weekStart: newWeekStart,
|
||||
));
|
||||
});
|
||||
|
||||
on<SelectDateFromSidebarCalendar>((event, emit) {
|
||||
emit(state.copyWith(
|
||||
selectedDateFromSideBarCalender: event.selectedDate,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
@ -10,4 +10,9 @@ class SelectDate extends DateSelectionEvent {
|
||||
|
||||
class NextWeek extends DateSelectionEvent {}
|
||||
|
||||
class PreviousWeek extends DateSelectionEvent {}
|
||||
class PreviousWeek extends DateSelectionEvent {}
|
||||
|
||||
class SelectDateFromSidebarCalendar extends DateSelectionEvent {
|
||||
final DateTime selectedDate;
|
||||
SelectDateFromSidebarCalendar(this.selectedDate);
|
||||
}
|
@ -1,21 +1,34 @@
|
||||
|
||||
class DateSelectionState {
|
||||
final DateTime selectedDate;
|
||||
final DateTime weekStart;
|
||||
final DateTime? selectedDateFromSideBarCalender;
|
||||
|
||||
const DateSelectionState({
|
||||
DateSelectionState({
|
||||
required this.selectedDate,
|
||||
required this.weekStart,
|
||||
this.selectedDateFromSideBarCalender,
|
||||
});
|
||||
|
||||
factory DateSelectionState.initial() {
|
||||
final now = DateTime.now();
|
||||
final weekStart = now.subtract(Duration(days: now.weekday - 1));
|
||||
return DateSelectionState(
|
||||
selectedDate: now,
|
||||
weekStart: _getStartOfWeek(now),
|
||||
weekStart: weekStart,
|
||||
selectedDateFromSideBarCalender: null,
|
||||
);
|
||||
}
|
||||
|
||||
static DateTime _getStartOfWeek(DateTime date) {
|
||||
return date.subtract(Duration(days: date.weekday - 1));
|
||||
DateSelectionState copyWith({
|
||||
DateTime? selectedDate,
|
||||
DateTime? weekStart,
|
||||
DateTime? selectedDateFromSideBarCalender,
|
||||
}) {
|
||||
return DateSelectionState(
|
||||
selectedDate: selectedDate ?? this.selectedDate,
|
||||
weekStart: weekStart ?? this.weekStart,
|
||||
selectedDateFromSideBarCalender: selectedDateFromSideBarCalender ?? this.selectedDateFromSideBarCalender,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +120,9 @@ class _BookingPageState extends State<BookingPage> {
|
||||
context
|
||||
.read<DateSelectionBloc>()
|
||||
.add(SelectDate(newDate));
|
||||
context
|
||||
.read<DateSelectionBloc>()
|
||||
.add(SelectDateFromSidebarCalendar(newDate));
|
||||
},
|
||||
);
|
||||
},
|
||||
@ -227,6 +230,10 @@ class _BookingPageState extends State<BookingPage> {
|
||||
weekStart: dateState.weekStart,
|
||||
selectedDate: dateState.selectedDate,
|
||||
eventController: _eventController,
|
||||
selectedDateFromSideBarCalender: context
|
||||
.watch<DateSelectionBloc>()
|
||||
.state
|
||||
.selectedDateFromSideBarCalender,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -9,6 +9,7 @@ class WeeklyCalendarPage extends StatelessWidget {
|
||||
final EventController eventController;
|
||||
final String? startTime;
|
||||
final String? endTime;
|
||||
final DateTime? selectedDateFromSideBarCalender;
|
||||
|
||||
const WeeklyCalendarPage({
|
||||
super.key,
|
||||
@ -17,32 +18,55 @@ class WeeklyCalendarPage extends StatelessWidget {
|
||||
required this.eventController,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.selectedDateFromSideBarCalender,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final startHour = _parseHour(startTime, defaultValue: 0);
|
||||
final endHour = _parseHour(endTime, defaultValue: 24);
|
||||
|
||||
if (endTime == null || endTime!.isEmpty) {
|
||||
return const Center(
|
||||
child: Text(
|
||||
'Please select a bookable space to view the calendar.',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.calendar_today,
|
||||
color: ColorsManager.lightGrayColor,
|
||||
size: 80,
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Text(
|
||||
'Please select a bookable space to view the calendar.',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: ColorsManager.lightGrayColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final weekDays = _getWeekDays(weekStart);
|
||||
|
||||
final selectedDayIndex =
|
||||
weekDays.indexWhere((d) => isSameDay(d, selectedDate));
|
||||
final selectedSidebarIndex = selectedDateFromSideBarCalender == null
|
||||
? -1
|
||||
: weekDays
|
||||
.indexWhere((d) => isSameDay(d, selectedDateFromSideBarCalender!));
|
||||
|
||||
const double timeLineWidth = 80;
|
||||
const int totalDays = 7;
|
||||
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final double calendarWidth = constraints.maxWidth;
|
||||
const double timeLineWidth = 80;
|
||||
const int totalDays = 7;
|
||||
final double dayColumnWidth =
|
||||
(calendarWidth - timeLineWidth) / totalDays - 0.1;
|
||||
final selectedDayIndex =
|
||||
weekDays.indexWhere((d) => isSameDay(d, selectedDate));
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 25.0, right: 25.0, top: 25),
|
||||
child: Stack(
|
||||
@ -64,13 +88,8 @@ class WeeklyCalendarPage extends StatelessWidget {
|
||||
height: 0,
|
||||
),
|
||||
weekDayBuilder: (date) {
|
||||
final weekDays = _getWeekDays(weekStart);
|
||||
final selectedDayIndex =
|
||||
weekDays.indexWhere((d) => isSameDay(d, selectedDate));
|
||||
final index = weekDays.indexWhere((d) => isSameDay(d, date));
|
||||
final isSelectedDay = index == selectedDayIndex;
|
||||
final isToday = isSameDay(date, DateTime.now());
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
@ -138,10 +157,7 @@ class WeeklyCalendarPage extends StatelessWidget {
|
||||
weekPageHeaderBuilder: (start, end) => Container(),
|
||||
weekTitleHeight: 60,
|
||||
weekNumberBuilder: (firstDayOfWeek) => Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 15,
|
||||
bottom: 10,
|
||||
),
|
||||
padding: const EdgeInsets.only(right: 15, bottom: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
@ -219,6 +235,22 @@ class WeeklyCalendarPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (selectedSidebarIndex >= 0 &&
|
||||
selectedSidebarIndex != selectedDayIndex)
|
||||
Positioned(
|
||||
left: (timeLineWidth + 3) +
|
||||
(dayColumnWidth - 8) * (selectedSidebarIndex - 0.01),
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
width: dayColumnWidth,
|
||||
child: IgnorePointer(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 0, horizontal: 4),
|
||||
color: Colors.orange.withOpacity(0.14),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 50,
|
||||
|
@ -46,15 +46,15 @@ class DeviceManagementBloc
|
||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||
|
||||
if (spaceBloc.state.selectedCommunities.isEmpty) {
|
||||
devices = await DevicesManagementApi().fetchDevices('', '', projectUuid);
|
||||
devices = await DevicesManagementApi().fetchDevices(
|
||||
projectUuid,
|
||||
);
|
||||
} else {
|
||||
for (final community in spaceBloc.state.selectedCommunities) {
|
||||
for (var community in spaceBloc.state.selectedCommunities) {
|
||||
final spacesList =
|
||||
spaceBloc.state.selectedCommunityAndSpaces[community] ?? [];
|
||||
for (final space in spacesList) {
|
||||
devices.addAll(await DevicesManagementApi()
|
||||
.fetchDevices(community, space, projectUuid));
|
||||
}
|
||||
devices.addAll(await DevicesManagementApi()
|
||||
.fetchDevices(projectUuid, spacesId: spacesList));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,45 +170,45 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onLoadScenes(
|
||||
LoadScenes event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||
List<ScenesModel> scenes = [];
|
||||
try {
|
||||
BuildContext context = NavigationService.navigatorKey.currentContext!;
|
||||
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||
if (createRoutineBloc.selectedSpaceId == '' &&
|
||||
createRoutineBloc.selectedCommunityId == '') {
|
||||
var spaceBloc = context.read<SpaceTreeBloc>();
|
||||
for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||
List<String> spacesList =
|
||||
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||
for (var spaceId in spacesList) {
|
||||
scenes.addAll(
|
||||
await SceneApi.getScenes(spaceId, communityId, projectUuid));
|
||||
Future<void> _onLoadScenes(
|
||||
LoadScenes event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||
List<ScenesModel> scenes = [];
|
||||
try {
|
||||
BuildContext context = NavigationService.navigatorKey.currentContext!;
|
||||
var createRoutineBloc = context.read<CreateRoutineBloc>();
|
||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||
if (createRoutineBloc.selectedSpaceId == '' &&
|
||||
createRoutineBloc.selectedCommunityId == '') {
|
||||
var spaceBloc = context.read<SpaceTreeBloc>();
|
||||
for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||
List<String> spacesList =
|
||||
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||
for (var spaceId in spacesList) {
|
||||
scenes.addAll(
|
||||
await SceneApi.getScenes(spaceId, communityId, projectUuid));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scenes.addAll(await SceneApi.getScenes(
|
||||
createRoutineBloc.selectedSpaceId,
|
||||
createRoutineBloc.selectedCommunityId,
|
||||
projectUuid));
|
||||
}
|
||||
} else {
|
||||
scenes.addAll(await SceneApi.getScenes(
|
||||
createRoutineBloc.selectedSpaceId,
|
||||
createRoutineBloc.selectedCommunityId,
|
||||
projectUuid));
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
scenes: scenes,
|
||||
isLoading: false,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
emit(state.copyWith(
|
||||
scenes: scenes,
|
||||
isLoading: false,
|
||||
loadScenesErrorMessage: 'Failed to load scenes',
|
||||
errorMessage: '',
|
||||
loadAutomationErrorMessage: '',
|
||||
scenes: scenes));
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
loadScenesErrorMessage: 'Failed to load scenes',
|
||||
errorMessage: '',
|
||||
loadAutomationErrorMessage: '',
|
||||
scenes: scenes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onLoadAutomation(
|
||||
LoadAutomation event, Emitter<RoutineState> emit) async {
|
||||
@ -936,16 +936,15 @@ Future<void> _onLoadScenes(
|
||||
for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||
List<String> spacesList =
|
||||
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||
for (var spaceId in spacesList) {
|
||||
devices.addAll(await DevicesManagementApi()
|
||||
.fetchDevices(communityId, spaceId, projectUuid));
|
||||
}
|
||||
|
||||
devices.addAll(await DevicesManagementApi()
|
||||
.fetchDevices(projectUuid, spacesId: spacesList));
|
||||
}
|
||||
} else {
|
||||
devices.addAll(await DevicesManagementApi().fetchDevices(
|
||||
createRoutineBloc.selectedCommunityId,
|
||||
createRoutineBloc.selectedSpaceId,
|
||||
projectUuid));
|
||||
projectUuid,
|
||||
spacesId: [createRoutineBloc.selectedSpaceId],
|
||||
));
|
||||
}
|
||||
|
||||
emit(state.copyWith(isLoading: false, devices: devices));
|
||||
|
@ -96,9 +96,7 @@ class _WallPresenceSensorState extends State<FlushPresenceSensor> {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DialogHeader(widget.dialogType == 'THEN'
|
||||
? 'Presence Sensor Functions'
|
||||
: 'Presence Sensor Condition'),
|
||||
const DialogHeader('Presence Sensor'),
|
||||
Expanded(child: _buildMainContent(context, state)),
|
||||
_buildDialogFooter(context, state),
|
||||
],
|
||||
|
@ -12,20 +12,16 @@ import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
|
||||
class DevicesManagementApi {
|
||||
Future<List<AllDevicesModel>> fetchDevices(
|
||||
String communityId, String spaceId, String projectId) async {
|
||||
Future<List<AllDevicesModel>> fetchDevices(String projectId,
|
||||
{List<String>? spacesId}) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: communityId.isNotEmpty && spaceId.isNotEmpty
|
||||
? ApiEndpoints.getSpaceDevices
|
||||
.replaceAll('{spaceUuid}', spaceId)
|
||||
.replaceAll('{communityUuid}', communityId)
|
||||
.replaceAll('{projectId}', projectId)
|
||||
: ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
|
||||
path: ApiEndpoints.getSpaceDevices.replaceAll('{projectId}', projectId),
|
||||
queryParameters: {if (spacesId != null) 'spaces': spacesId},
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
List<dynamic> jsonData = json['data'];
|
||||
List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
|
||||
final List<dynamic> jsonData = json['data'] as List<dynamic>;
|
||||
final List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
|
||||
return AllDevicesModel.fromJson(jsonItem);
|
||||
}).toList();
|
||||
return devicesList;
|
||||
@ -416,5 +412,4 @@ class DevicesManagementApi {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,8 +17,7 @@ abstract class ApiEndpoints {
|
||||
////// Devices Management ////////////////
|
||||
|
||||
static const String getAllDevices = '/projects/{projectId}/devices';
|
||||
static const String getSpaceDevices =
|
||||
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
||||
static const String getSpaceDevices = '/projects/{projectId}/devices';
|
||||
static const String getDeviceStatus = '/devices/{uuid}/functions/status';
|
||||
static const String getBatchStatus = '/devices/batch';
|
||||
|
||||
|
Reference in New Issue
Block a user