Compare commits

...

2 Commits

10 changed files with 133 additions and 46 deletions

View File

@ -1,5 +1,6 @@
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_config.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/params/bookable_spaces_params.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/service/bookable_spaces_service.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/shared/models/paginated_data_model.dart';
@ -16,8 +17,8 @@ class DummyBookableSpacesService implements BookableSpacesService {
configUuid: 'uuid',
bookableDays: ['wed', 'saturday'],
availability: true,
bookingEndTime: '08:00 PM',
bookingStartTime: '5:00 PM',
bookingEndTime: const TimeOfDay(hour: 13, minute: 20),
bookingStartTime: const TimeOfDay(hour: 13, minute: 20),
cost: 6,
),
spaceUuid: 'uuiiddd',
@ -29,8 +30,8 @@ class DummyBookableSpacesService implements BookableSpacesService {
configUuid: 'uuid',
bookableDays: ['wed', 'thur'],
availability: true,
bookingEndTime: '08:00 PM',
bookingStartTime: '5:00 PM',
bookingEndTime: const TimeOfDay(hour: 13, minute: 20),
bookingStartTime: const TimeOfDay(hour: 13, minute: 20),
cost: 6,
),
spaceUuid: 'uuiiddd',
@ -42,8 +43,8 @@ class DummyBookableSpacesService implements BookableSpacesService {
configUuid: 'uuid',
bookableDays: ['wed', 'fri', 'tues'],
availability: true,
bookingEndTime: '08:00 PM',
bookingStartTime: '5:00 PM',
bookingEndTime: const TimeOfDay(hour: 13, minute: 20),
bookingStartTime: const TimeOfDay(hour: 13, minute: 20),
cost: 6,
),
spaceUuid: 'uuiiddd',

View File

@ -1,3 +1,4 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_config.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/params/non_bookable_spaces_params.dart';
@ -17,8 +18,8 @@ class DummyNonNookableSpaces implements NonBookableSpacesService {
configUuid: 'uuid',
bookableDays: ['wed', 'saturday'],
availability: true,
bookingEndTime: '08:00 PM',
bookingStartTime: '5:00 PM',
bookingEndTime: const TimeOfDay(hour: 13, minute: 20),
bookingStartTime: const TimeOfDay(hour: 6, minute: 20),
cost: 6,
),
spaceUuid: 'uuiiddd',
@ -30,8 +31,8 @@ class DummyNonNookableSpaces implements NonBookableSpacesService {
configUuid: 'uuid',
bookableDays: ['wed', 'saturday', 'thuresday'],
availability: true,
bookingEndTime: '08:00 PM',
bookingStartTime: '5:00 PM',
bookingEndTime: const TimeOfDay(hour: 13, minute: 20),
bookingStartTime: const TimeOfDay(hour: 5, minute: 20),
cost: 5,
),
spaceUuid: 'uuiiddd',
@ -50,8 +51,8 @@ class DummyNonNookableSpaces implements NonBookableSpacesService {
'thuresday'
],
availability: true,
bookingEndTime: '08:00 PM',
bookingStartTime: '5:00 PM',
bookingEndTime: const TimeOfDay(hour: 13, minute: 20),
bookingStartTime: const TimeOfDay(hour: 15, minute: 20),
cost: 2,
),
spaceUuid: 'uuiiddd',

View File

@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
class BookableSpaceConfig {
String configUuid;
List<String> bookableDays;
String bookingStartTime;
String bookingEndTime;
TimeOfDay bookingStartTime;
TimeOfDay bookingEndTime;
int cost;
bool availability;
BookableSpaceConfig({
@ -17,8 +19,8 @@ class BookableSpaceConfig {
configUuid: '',
bookableDays: [],
availability: false,
bookingEndTime: '',
bookingStartTime: '',
bookingEndTime: TimeOfDay.now(),
bookingStartTime: TimeOfDay.now(),
cost: -1,
);
factory BookableSpaceConfig.fromJson(Map<String, dynamic> json) =>
@ -26,14 +28,18 @@ class BookableSpaceConfig {
configUuid: json['uuid'] as String,
bookableDays: json['daysAvailable'] as List<String>,
availability: (json['active'] as bool?) ?? false,
bookingEndTime: json['startTime'] as String,
bookingStartTime: json['endTime'] as String,
bookingEndTime: parseTimeOfDay(json['startTime'] as String),
bookingStartTime: parseTimeOfDay(json['endTime'] as String),
cost: json['points'] as int,
);
static TimeOfDay parseTimeOfDay(String timeString) {
final parts = timeString.split(':');
final hour = int.parse(parts[0]);
final minute = int.parse(parts[1]);
return TimeOfDay(hour: hour, minute: minute);
}
bool get isValid =>
configUuid.isNotEmpty &&
bookableDays.isNotEmpty &&
bookingStartTime.isNotEmpty &&
bookingEndTime.isNotEmpty &&
cost > 0;
configUuid.isNotEmpty && bookableDays.isNotEmpty && cost > 0;
}

View File

@ -1,4 +1,5 @@
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/utils/string_utils.dart';
class SendBookableSpacesToApiParams {
List<String> spaceUuids;
@ -14,7 +15,7 @@ class SendBookableSpacesToApiParams {
required this.points,
});
static SendBookableSpacesToApiParams fromBookableSpacesModel(
static SendBookableSpacesToApiParams fromBookableSpacesModel(
List<BookableSpacemodel> bookableSpaces) {
return SendBookableSpacesToApiParams(
spaceUuids: bookableSpaces.map((space) => space.spaceUuid).toList(),
@ -22,8 +23,10 @@ class SendBookableSpacesToApiParams {
.expand((space) => space.spaceConfig.bookableDays)
.toSet()
.toList(),
startTime: bookableSpaces.first.spaceConfig.bookingStartTime,
endTime: bookableSpaces.first.spaceConfig.bookingEndTime,
startTime: formatTimeOfDayTo24HourString(
bookableSpaces.first.spaceConfig.bookingStartTime),
endTime: formatTimeOfDayTo24HourString(
bookableSpaces.first.spaceConfig.bookingEndTime),
points: bookableSpaces.first.spaceConfig.cost,
);
}

View File

@ -1,5 +1,6 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/params/non_bookable_spaces_params.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/service/non_bookable_spaces_service.dart';
@ -20,6 +21,12 @@ class NonBookableSpacesBloc
on<RemoveFromBookableSpaceEvent>(_onRemoveFromBookableSpaceEvent);
on<SendBookableSpacesToApi>(_onSendBookableSpacesToApi);
}
TimeOfDay get endTime =>
selectedBookableSpaces.first.spaceConfig.bookingEndTime;
TimeOfDay get startTime =>
selectedBookableSpaces.first.spaceConfig.bookingStartTime;
Future<void> _onLoadUnBookableSpacesEvent(LoadUnBookableSpacesEvent event,
Emitter<NonBookableSpacesState> emit) async {
emit(NonBookableSpacesLoading());
@ -80,7 +87,8 @@ class NonBookableSpacesBloc
try {
await nonBookableSpacesService.sendBookableSpacesToApi(
SendBookableSpacesToApiParams.fromBookableSpacesModel(
selectedBookableSpaces),
selectedBookableSpaces,
),
);
} catch (e) {
emit(

View File

@ -142,12 +142,22 @@ class ManageBookableSpacesWidget extends StatelessWidget {
.toList(),
),
)),
DataCell(Padding(
DataCell(
Padding(
padding: const EdgeInsetsGeometry.only(left: 10),
child: Text(space.spaceConfig.bookingStartTime))),
DataCell(Padding(
child: Text(
space.spaceConfig.bookingStartTime.format(context),
),
),
),
DataCell(
Padding(
padding: const EdgeInsetsGeometry.only(left: 10),
child: Text(space.spaceConfig.bookingEndTime))),
child: Text(
space.spaceConfig.bookingEndTime.format(context),
),
),
),
DataCell(Padding(
padding: const EdgeInsetsGeometry.only(left: 10),
child: Text('${space.spaceConfig.cost} Points'))),

View File

@ -79,6 +79,7 @@ class SetupBookableSpacesDialog extends StatelessWidget {
if (selectedSpaces.isNotEmpty) {
context.read<StepsCubit>().goToNextStep();
} else {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please select at least one space.'),
@ -87,18 +88,23 @@ class SetupBookableSpacesDialog extends StatelessWidget {
}
} else if (stepsState is StepTwoState) {
selectedSpaces.forEach(
(e) =>
e.spaceConfig.cost = int.parse(pointsController.text),
(e) => e.spaceConfig.cost = int.parse(
pointsController.text.isEmpty
? '0'
: pointsController.text),
);
if (selectedSpaces.any(
(element) => !element.isValid,
)) {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please fill the required fields.'),
),
);
} else {}
} else {
print(selectedSpaces.first.spaceUuid);
}
}
},
onCancelPressed: () => context.pop(),

View File

@ -5,6 +5,8 @@ import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/prese
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/search_unbookable_spaces_widget.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/time_picker_widget.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/week_checkbox_title_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/string_utils.dart';
class StepTwoDetailsWidget extends StatelessWidget {
final TextEditingController pointsController;
@ -29,22 +31,52 @@ class StepTwoDetailsWidget extends StatelessWidget {
TitleAndTimePickerWidget(
title: 'Booking Start Time',
onTimePicked: (timePicked) {
if (timePicked == null) {
return;
}
final nonBookableBloc = context.read<NonBookableSpacesBloc>();
nonBookableBloc.selectedBookableSpaces.forEach(
(e) => e.spaceConfig.bookingStartTime =
timePicked!.format(context),
);
if (isEndTimeAfterStartTime(
timePicked, nonBookableBloc.endTime)) {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content:
Text("You can't choose start Time Before End time"),
duration: Duration(seconds: 2),
backgroundColor: ColorsManager.red,
));
throw Exception();
} else {
nonBookableBloc.selectedBookableSpaces.forEach(
(e) => e.spaceConfig.bookingStartTime = timePicked,
);
}
},
),
SizedBox(width: 20,),
const SizedBox(
width: 20,
),
TitleAndTimePickerWidget(
title: 'Booking End Time',
onTimePicked: (timePicked) {
if (timePicked == null) {
return;
}
final nonBookableBloc = context.read<NonBookableSpacesBloc>();
nonBookableBloc.selectedBookableSpaces.forEach(
(e) => e.spaceConfig.bookingEndTime =
timePicked!.format(context),
);
if (isEndTimeAfterStartTime(
nonBookableBloc.startTime, timePicked)) {
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content:
Text("You can't choose End Time After Start time"),
duration: Duration(seconds: 2),
backgroundColor: ColorsManager.red,
));
throw Exception();
} else {
nonBookableBloc.selectedBookableSpaces.forEach(
(e) => e.spaceConfig.bookingEndTime = timePicked,
);
}
},
)
],

View File

@ -23,7 +23,7 @@ class _TimePickerWidgetState extends State<TimePickerWidget> {
return InkWell(
borderRadius: BorderRadius.circular(10),
onTap: () async {
timePicked = await showTimePicker(
final tempTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
@ -38,7 +38,8 @@ class _TimePickerWidgetState extends State<TimePickerWidget> {
);
},
);
widget.onTimePicked(timePicked);
widget.onTimePicked(tempTime);
timePicked = tempTime;
setState(() {});
},
child: Row(

View File

@ -1,6 +1,25 @@
import 'package:flutter/material.dart';
class StringUtils {
static String capitalizeFirstLetter(String text) {
if (text.isEmpty) return text;
return text[0].toUpperCase() + text.substring(1);
}
}
bool isEndTimeAfterStartTime(TimeOfDay start, TimeOfDay end) {
final startMinutes = start.hour * 60 + start.minute;
final endMinutes = end.hour * 60 + end.minute;
if (endMinutes <= startMinutes) {
return true;
}
return false;
}
String formatTimeOfDayTo24HourString(TimeOfDay time) {
final hour = time.hour.toString().padLeft(2, '0');
final minute = time.minute.toString().padLeft(2, '0');
return '$hour:$minute';
}