mirror of
https://github.com/Iconica-Development/flutter_availability.git
synced 2025-05-19 05:03:44 +02:00
feat: add template overview screen
The mocked templates will be replaced later with a template stream for fetching templates from the flutter_availability_data_interface
This commit is contained in:
parent
bc2a7e2f08
commit
f2e279a592
3 changed files with 240 additions and 8 deletions
|
@ -17,6 +17,11 @@ class AvailabilityTranslations {
|
||||||
required this.templateSelectionLabel,
|
required this.templateSelectionLabel,
|
||||||
required this.overviewScreenTitle,
|
required this.overviewScreenTitle,
|
||||||
required this.createTemplateButton,
|
required this.createTemplateButton,
|
||||||
|
required this.templateScreenTitle,
|
||||||
|
required this.dayTemplates,
|
||||||
|
required this.weekTemplates,
|
||||||
|
required this.createDayTemplate,
|
||||||
|
required this.createWeekTemplate,
|
||||||
required this.monthYearFormatter,
|
required this.monthYearFormatter,
|
||||||
required this.weekDayAbbreviatedFormatter,
|
required this.weekDayAbbreviatedFormatter,
|
||||||
});
|
});
|
||||||
|
@ -30,6 +35,11 @@ class AvailabilityTranslations {
|
||||||
this.templateSelectionLabel = "Selected day(s)",
|
this.templateSelectionLabel = "Selected day(s)",
|
||||||
this.createTemplateButton = "Create a new template",
|
this.createTemplateButton = "Create a new template",
|
||||||
this.overviewScreenTitle = "Availability",
|
this.overviewScreenTitle = "Availability",
|
||||||
|
this.templateScreenTitle = "Templates",
|
||||||
|
this.dayTemplates = "Day templates",
|
||||||
|
this.weekTemplates = "Week templates",
|
||||||
|
this.createDayTemplate = "Create day template",
|
||||||
|
this.createWeekTemplate = "Create week template",
|
||||||
this.monthYearFormatter = _defaultMonthYearFormatter,
|
this.monthYearFormatter = _defaultMonthYearFormatter,
|
||||||
this.weekDayAbbreviatedFormatter = _defaultWeekDayAbbreviatedFormatter,
|
this.weekDayAbbreviatedFormatter = _defaultWeekDayAbbreviatedFormatter,
|
||||||
});
|
});
|
||||||
|
@ -49,9 +59,24 @@ class AvailabilityTranslations {
|
||||||
/// The title on the overview screen
|
/// The title on the overview screen
|
||||||
final String overviewScreenTitle;
|
final String overviewScreenTitle;
|
||||||
|
|
||||||
/// The label on the button to go to the tempalte creation page
|
/// The label on the button to go to the template screen
|
||||||
final String createTemplateButton;
|
final String createTemplateButton;
|
||||||
|
|
||||||
|
/// The title on the template screen
|
||||||
|
final String templateScreenTitle;
|
||||||
|
|
||||||
|
/// The title for the day templates section on the template screen
|
||||||
|
final String dayTemplates;
|
||||||
|
|
||||||
|
/// The title for the week templates section on the template screen
|
||||||
|
final String weekTemplates;
|
||||||
|
|
||||||
|
/// The label for the button to create a new day template
|
||||||
|
final String createDayTemplate;
|
||||||
|
|
||||||
|
/// The label for the button to create a new week template
|
||||||
|
final String createWeekTemplate;
|
||||||
|
|
||||||
/// Gets the month and year formatted as a string
|
/// Gets the month and year formatted as a string
|
||||||
///
|
///
|
||||||
/// The default implementation is `MonthName Year` in english
|
/// The default implementation is `MonthName Year` in english
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_availability/flutter_availability.dart";
|
import "package:flutter_availability/flutter_availability.dart";
|
||||||
import "package:flutter_availability/src/ui/screens/template_availability_day_overview.dart";
|
import "package:flutter_availability/src/ui/screens/template_availability_day_overview.dart";
|
||||||
|
import "package:flutter_availability/src/ui/screens/template_overview.dart";
|
||||||
|
|
||||||
///
|
///
|
||||||
MaterialPageRoute homePageRoute(VoidCallback onExit) => MaterialPageRoute(
|
MaterialPageRoute homePageRoute(VoidCallback onExit) => MaterialPageRoute(
|
||||||
builder: (context) => AvailabilityOverview(
|
builder: (context) => AvailabilityOverview(
|
||||||
onEditDateRange: (range) async {
|
onEditDateRange: (range) async =>
|
||||||
await Navigator.of(context).push(availabilityViewRoute(range.start));
|
Navigator.of(context).push(availabilityViewRoute(range.start)),
|
||||||
},
|
onViewTemplates: () async =>
|
||||||
onViewTemplates: () {},
|
Navigator.of(context).push(templateOverviewRoute()),
|
||||||
onExit: () {
|
onExit: () => onExit(),
|
||||||
onExit();
|
),
|
||||||
},
|
);
|
||||||
|
|
||||||
|
///
|
||||||
|
MaterialPageRoute templateOverviewRoute() => MaterialPageRoute(
|
||||||
|
builder: (context) => AvailabilityTemplateOverview(
|
||||||
|
onExit: () => Navigator.of(context).pop(),
|
||||||
|
onEditTemplate: (template) {},
|
||||||
|
onAddTemplate: (type) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
import "package:flutter_availability/src/util/scope.dart";
|
||||||
|
import "package:flutter_availability_data_interface/flutter_availability_data_interface.dart";
|
||||||
|
|
||||||
|
/// Overview screen for all the availability templates
|
||||||
|
class AvailabilityTemplateOverview extends StatelessWidget {
|
||||||
|
/// Constructor
|
||||||
|
const AvailabilityTemplateOverview({
|
||||||
|
required this.onExit,
|
||||||
|
required this.onEditTemplate,
|
||||||
|
required this.onAddTemplate,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Callback for when the user wants to navigate back
|
||||||
|
final VoidCallback onExit;
|
||||||
|
|
||||||
|
/// Callback for when the user goes to edit an existing template
|
||||||
|
final void Function(AvailabilityTemplateModel template) onEditTemplate;
|
||||||
|
|
||||||
|
/// Callback for when the user goes to create a new template
|
||||||
|
final void Function(AvailabilityTemplateType type) onAddTemplate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var theme = Theme.of(context);
|
||||||
|
var availabilityScope = AvailabilityScope.of(context);
|
||||||
|
var options = availabilityScope.options;
|
||||||
|
var translations = options.translations;
|
||||||
|
var spacing = options.spacing;
|
||||||
|
|
||||||
|
var title = Center(
|
||||||
|
child: Text(
|
||||||
|
translations.templateScreenTitle,
|
||||||
|
style: theme.textTheme.displaySmall,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
var dayTemplateSection = _TemplateListSection(
|
||||||
|
sectionTitle: translations.dayTemplates,
|
||||||
|
createButtonText: translations.createDayTemplate,
|
||||||
|
templates: [
|
||||||
|
for (var template in <(Color, String)>[
|
||||||
|
(Colors.red, "Template 1"),
|
||||||
|
(Colors.blue, "Template 2"),
|
||||||
|
(Colors.green, "Template 3"),
|
||||||
|
(Colors.yellow, "Template 4"),
|
||||||
|
]) ...[
|
||||||
|
AvailabilityTemplateModel(
|
||||||
|
userId: "1",
|
||||||
|
id: "1",
|
||||||
|
name: template.$2,
|
||||||
|
templateType: AvailabilityTemplateType.day,
|
||||||
|
templateData: DayTemplateData(
|
||||||
|
startTime: DateTime.now(),
|
||||||
|
endTime: DateTime.now(),
|
||||||
|
breaks: [],
|
||||||
|
),
|
||||||
|
color: template.$1.value,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
onEditTemplate: onEditTemplate,
|
||||||
|
onAddTemplate: () => onAddTemplate(AvailabilityTemplateType.day),
|
||||||
|
);
|
||||||
|
|
||||||
|
var weekTemplateSection = _TemplateListSection(
|
||||||
|
sectionTitle: translations.weekTemplates,
|
||||||
|
createButtonText: translations.createWeekTemplate,
|
||||||
|
templates: [
|
||||||
|
for (var template in <(Color, String)>[
|
||||||
|
(Colors.purple, "Template 5"),
|
||||||
|
(Colors.orange, "Template 6"),
|
||||||
|
(Colors.teal, "Template 7"),
|
||||||
|
(Colors.pink, "Template 8"),
|
||||||
|
(Colors.indigo, "Template 9"),
|
||||||
|
]) ...[
|
||||||
|
AvailabilityTemplateModel(
|
||||||
|
userId: "1",
|
||||||
|
id: "1",
|
||||||
|
name: template.$2,
|
||||||
|
templateType: AvailabilityTemplateType.week,
|
||||||
|
templateData: DayTemplateData(
|
||||||
|
startTime: DateTime.now(),
|
||||||
|
endTime: DateTime.now(),
|
||||||
|
breaks: [],
|
||||||
|
),
|
||||||
|
color: template.$1.value,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
onEditTemplate: onEditTemplate,
|
||||||
|
onAddTemplate: () => onAddTemplate(AvailabilityTemplateType.week),
|
||||||
|
);
|
||||||
|
|
||||||
|
var body = Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: spacing.sidePadding),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 40),
|
||||||
|
title,
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
dayTemplateSection,
|
||||||
|
const SizedBox(height: 40),
|
||||||
|
weekTemplateSection,
|
||||||
|
SizedBox(height: spacing.bottomButtonPadding),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return options.baseScreenBuilder(context, onExit, body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Displays a list of templates and a button to create a new template
|
||||||
|
class _TemplateListSection extends StatelessWidget {
|
||||||
|
const _TemplateListSection({
|
||||||
|
required this.sectionTitle,
|
||||||
|
required this.createButtonText,
|
||||||
|
required this.templates,
|
||||||
|
required this.onEditTemplate,
|
||||||
|
required this.onAddTemplate,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String sectionTitle;
|
||||||
|
final String createButtonText;
|
||||||
|
final List<AvailabilityTemplateModel> templates;
|
||||||
|
final void Function(AvailabilityTemplateModel template) onEditTemplate;
|
||||||
|
final VoidCallback onAddTemplate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var theme = Theme.of(context);
|
||||||
|
var textTheme = theme.textTheme;
|
||||||
|
|
||||||
|
var templateCreationButton = GestureDetector(
|
||||||
|
onTap: onAddTemplate,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
height: 44,
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.add),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
createButtonText,
|
||||||
|
style: textTheme.bodyLarge?.copyWith(
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Text(sectionTitle, style: textTheme.titleMedium),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
const Divider(height: 1),
|
||||||
|
for (var template in templates) ...[
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => onEditTemplate(template),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
margin: const EdgeInsets.only(top: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: theme.dividerColor, width: 1),
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(template.color),
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(template.name, style: textTheme.bodyLarge),
|
||||||
|
const Spacer(),
|
||||||
|
const Icon(Icons.edit),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
templateCreationButton,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue