mirror of
https://github.com/Iconica-Development/flutter_availability.git
synced 2025-05-19 05:03:44 +02:00
feat: add availability screen individual components
This commit is contained in:
parent
095eff2c21
commit
20104160eb
5 changed files with 201 additions and 14 deletions
|
@ -18,6 +18,11 @@ class AvailabilityTranslations {
|
|||
required this.availabilityWithoutTemplateLabel,
|
||||
required this.overviewScreenTitle,
|
||||
required this.createTemplateButton,
|
||||
required this.unavailableForDay,
|
||||
required this.unavailableForMultipleDays,
|
||||
required this.availabilityAddTemplateTitle,
|
||||
required this.availabilityTimeTitle,
|
||||
required this.availabilitiesTimeTitle,
|
||||
required this.templateScreenTitle,
|
||||
required this.dayTemplates,
|
||||
required this.weekTemplates,
|
||||
|
@ -41,6 +46,8 @@ class AvailabilityTranslations {
|
|||
required this.saveButton,
|
||||
required this.addButton,
|
||||
required this.timeFormatter,
|
||||
required this.dayMonthFormatter,
|
||||
required this.periodFormatter,
|
||||
required this.monthYearFormatter,
|
||||
required this.weekDayAbbreviatedFormatter,
|
||||
});
|
||||
|
@ -54,6 +61,11 @@ class AvailabilityTranslations {
|
|||
this.templateSelectionLabel = "Selected day(s)",
|
||||
this.availabilityWithoutTemplateLabel = "Availabilty without template",
|
||||
this.createTemplateButton = "Create a new template",
|
||||
this.unavailableForDay = "I am not available this day",
|
||||
this.unavailableForMultipleDays = "I am not available these days",
|
||||
this.availabilityAddTemplateTitle = "Add template to availability",
|
||||
this.availabilityTimeTitle = "Start and end time workday",
|
||||
this.availabilitiesTimeTitle = "Start and end time workdays",
|
||||
this.overviewScreenTitle = "Availability",
|
||||
this.templateScreenTitle = "Templates",
|
||||
this.dayTemplates = "Day templates",
|
||||
|
@ -79,6 +91,8 @@ class AvailabilityTranslations {
|
|||
"Select between which times you want to take a break",
|
||||
this.saveButton = "Save",
|
||||
this.addButton = "Add",
|
||||
this.dayMonthFormatter = _defaultDayMonthFormatter,
|
||||
this.periodFormatter = _defaultPeriodFormatter,
|
||||
this.monthYearFormatter = _defaultMonthYearFormatter,
|
||||
this.weekDayAbbreviatedFormatter = _defaultWeekDayAbbreviatedFormatter,
|
||||
this.timeFormatter = _defaultTimeFormatter,
|
||||
|
@ -105,6 +119,21 @@ class AvailabilityTranslations {
|
|||
/// The label on the button to go to the template screen
|
||||
final String createTemplateButton;
|
||||
|
||||
/// The text shown to clear the availability for a day
|
||||
final String unavailableForDay;
|
||||
|
||||
/// The text shown to clear the availability for multiple days
|
||||
final String unavailableForMultipleDays;
|
||||
|
||||
/// The title on the template selection section for adding availabilities
|
||||
final String availabilityAddTemplateTitle;
|
||||
|
||||
/// The title on the time selection section for adding a single availability
|
||||
final String availabilityTimeTitle;
|
||||
|
||||
/// The title on the time selection section for adding multiple availabilities
|
||||
final String availabilitiesTimeTitle;
|
||||
|
||||
/// The title on the template screen
|
||||
final String templateScreenTitle;
|
||||
|
||||
|
@ -172,6 +201,16 @@ class AvailabilityTranslations {
|
|||
/// The text on the add button
|
||||
final String addButton;
|
||||
|
||||
/// Gets the day and month formatted as a string
|
||||
///
|
||||
/// The default implementation is `Dayname day monthname` in english
|
||||
final String Function(BuildContext, DateTime) dayMonthFormatter;
|
||||
|
||||
/// Gets the period between two dates formatted as a string
|
||||
///
|
||||
/// The default implementation is `day monthname to day monthname` in english
|
||||
final String Function(BuildContext, DateTimeRange) periodFormatter;
|
||||
|
||||
/// Gets the month and year formatted as a string
|
||||
///
|
||||
/// The default implementation is `MonthName Year` in english
|
||||
|
@ -190,8 +229,15 @@ class AvailabilityTranslations {
|
|||
}
|
||||
|
||||
String _defaultTimeFormatter(BuildContext context, DateTime date) =>
|
||||
"${date.hour}:${date.minute}";
|
||||
"${date.hour.toString().padLeft(2, '0')}:"
|
||||
"${date.minute.toString().padLeft(2, '0')}";
|
||||
|
||||
String _defaultDayMonthFormatter(BuildContext context, DateTime date) =>
|
||||
"${_getDayName(date.weekday)} ${date.day} ${_getMonthName(date.month)}";
|
||||
|
||||
String _defaultPeriodFormatter(BuildContext context, DateTimeRange range) =>
|
||||
"${range.start.day} ${_getMonthName(range.start.month)} to "
|
||||
"${range.end.day} ${_getMonthName(range.end.month)}";
|
||||
String _defaultWeekDayAbbreviatedFormatter(
|
||||
BuildContext context,
|
||||
DateTime date,
|
||||
|
@ -201,16 +247,8 @@ String _defaultWeekDayAbbreviatedFormatter(
|
|||
String _defaultMonthYearFormatter(BuildContext context, DateTime date) =>
|
||||
"${_getMonthName(date.month)} ${date.year}";
|
||||
|
||||
String _getWeekDayAbbreviation(int weekday) => switch (weekday) {
|
||||
1 => "Mo",
|
||||
2 => "Tu",
|
||||
3 => "We",
|
||||
4 => "Th",
|
||||
5 => "Fr",
|
||||
6 => "Sa",
|
||||
7 => "Su",
|
||||
_ => "",
|
||||
};
|
||||
String _getWeekDayAbbreviation(int weekday) =>
|
||||
_getDayName(weekday).substring(0, 2);
|
||||
|
||||
String _getMonthName(int month) => switch (month) {
|
||||
1 => "January",
|
||||
|
@ -227,3 +265,14 @@ String _getMonthName(int month) => switch (month) {
|
|||
12 => "December",
|
||||
_ => "",
|
||||
};
|
||||
|
||||
String _getDayName(int day) => switch (day) {
|
||||
1 => "Monday",
|
||||
2 => "Tuesday",
|
||||
3 => "Wednesday",
|
||||
4 => "Thursday",
|
||||
5 => "Friday",
|
||||
6 => "Saturday",
|
||||
7 => "Sunday",
|
||||
_ => "",
|
||||
};
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import "package:flutter/material.dart";
|
||||
import "package:flutter_availability/src/util/scope.dart";
|
||||
|
||||
///
|
||||
class AvailabilityClearSection extends StatelessWidget {
|
||||
///
|
||||
const AvailabilityClearSection({
|
||||
required this.range,
|
||||
required this.clearAvailable,
|
||||
required this.onChanged,
|
||||
super.key,
|
||||
});
|
||||
|
||||
/// The date range for which the availabilities can be cleared
|
||||
/// If the range is a single day, the range will be formatted as a single day
|
||||
/// If the range is multiple days, the range will be formatted as a period
|
||||
final DateTimeRange range;
|
||||
|
||||
/// Whether the clear available checkbox should be checked
|
||||
final bool clearAvailable;
|
||||
|
||||
/// Callback for when the clear available checkbox is toggled
|
||||
// ignore: avoid_positional_boolean_parameters
|
||||
final void Function(bool isChecked) onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var theme = Theme.of(context);
|
||||
var textTheme = theme.textTheme;
|
||||
var availabilityScope = AvailabilityScope.of(context);
|
||||
var options = availabilityScope.options;
|
||||
var translations = options.translations;
|
||||
|
||||
var isSingleDay = range.start.isAtSameMomentAs(range.end);
|
||||
|
||||
var titleText = isSingleDay
|
||||
? translations.dayMonthFormatter(context, range.start)
|
||||
: translations.periodFormatter(context, range);
|
||||
var unavailableText = isSingleDay
|
||||
? translations.unavailableForDay
|
||||
: translations.unavailableForMultipleDays;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
titleText,
|
||||
style: textTheme.titleMedium,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: clearAvailable,
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
onChanged(value);
|
||||
},
|
||||
),
|
||||
Text(
|
||||
unavailableText,
|
||||
style: textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import "package:flutter/material.dart";
|
||||
|
||||
/// Selection of the template to use for the availability
|
||||
///
|
||||
/// This can show multiple templates when the user selects a date range.
|
||||
/// When updating the templates for a date range where there are multiple
|
||||
/// different templates used, the user first needs to remove the existing
|
||||
/// templates.
|
||||
class AvailabilityTemplateSelection extends StatelessWidget {
|
||||
/// Constructor
|
||||
const AvailabilityTemplateSelection({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
const SizedBox(height: 50, child: Placeholder());
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import "package:flutter/material.dart";
|
||||
import "package:flutter_availability/src/ui/widgets/generic_time_selection.dart";
|
||||
import "package:flutter_availability/src/util/scope.dart";
|
||||
|
||||
///
|
||||
class AvailabilityTimeSelection extends StatelessWidget {
|
||||
///
|
||||
const AvailabilityTimeSelection({
|
||||
required this.startTime,
|
||||
required this.endTime,
|
||||
required this.onStartChanged,
|
||||
required this.onEndChanged,
|
||||
required this.dateRange,
|
||||
super.key,
|
||||
});
|
||||
|
||||
///
|
||||
final DateTime? startTime;
|
||||
|
||||
///
|
||||
final DateTime? endTime;
|
||||
|
||||
///
|
||||
final void Function(DateTime) onStartChanged;
|
||||
|
||||
///
|
||||
final void Function(DateTime) onEndChanged;
|
||||
|
||||
/// The date range for which the availabilities are being managed
|
||||
final DateTimeRange dateRange;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var availabilityScope = AvailabilityScope.of(context);
|
||||
var options = availabilityScope.options;
|
||||
var translations = options.translations;
|
||||
|
||||
var isSingleDay = dateRange.start.isAtSameMomentAs(dateRange.end);
|
||||
var titleText = isSingleDay
|
||||
? translations.availabilityTimeTitle
|
||||
: translations.availabilitiesTimeTitle;
|
||||
|
||||
return TimeSelection(
|
||||
title: titleText,
|
||||
description: null,
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
onStartChanged: onStartChanged,
|
||||
onEndChanged: onEndChanged,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ class TimeSelection extends StatelessWidget {
|
|||
final String title;
|
||||
|
||||
/// The description of the time selection
|
||||
final String description;
|
||||
final String? description;
|
||||
|
||||
/// the axis aligment for the column
|
||||
final CrossAxisAlignment crossAxisAlignment;
|
||||
|
@ -49,8 +49,10 @@ class TimeSelection extends StatelessWidget {
|
|||
crossAxisAlignment: crossAxisAlignment,
|
||||
children: [
|
||||
Text(title, style: textTheme.titleMedium),
|
||||
const SizedBox(height: 4),
|
||||
Text(description, style: textTheme.bodyMedium),
|
||||
if (description != null) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(description!, style: textTheme.bodyMedium),
|
||||
],
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
|
|
Loading…
Reference in a new issue