mirror of
https://github.com/Iconica-Development/flutter_availability.git
synced 2025-05-18 20:53:45 +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.overviewScreenTitle,
|
||||
required this.createTemplateButton,
|
||||
required this.templateScreenTitle,
|
||||
required this.dayTemplates,
|
||||
required this.weekTemplates,
|
||||
required this.createDayTemplate,
|
||||
required this.createWeekTemplate,
|
||||
required this.monthYearFormatter,
|
||||
required this.weekDayAbbreviatedFormatter,
|
||||
});
|
||||
|
@ -30,6 +35,11 @@ class AvailabilityTranslations {
|
|||
this.templateSelectionLabel = "Selected day(s)",
|
||||
this.createTemplateButton = "Create a new template",
|
||||
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.weekDayAbbreviatedFormatter = _defaultWeekDayAbbreviatedFormatter,
|
||||
});
|
||||
|
@ -49,9 +59,24 @@ class AvailabilityTranslations {
|
|||
/// The title on the overview screen
|
||||
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;
|
||||
|
||||
/// 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
|
||||
///
|
||||
/// The default implementation is `MonthName Year` in english
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
import "package:flutter/material.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_overview.dart";
|
||||
|
||||
///
|
||||
MaterialPageRoute homePageRoute(VoidCallback onExit) => MaterialPageRoute(
|
||||
builder: (context) => AvailabilityOverview(
|
||||
onEditDateRange: (range) async {
|
||||
await Navigator.of(context).push(availabilityViewRoute(range.start));
|
||||
},
|
||||
onViewTemplates: () {},
|
||||
onExit: () {
|
||||
onExit();
|
||||
},
|
||||
onEditDateRange: (range) async =>
|
||||
Navigator.of(context).push(availabilityViewRoute(range.start)),
|
||||
onViewTemplates: () async =>
|
||||
Navigator.of(context).push(templateOverviewRoute()),
|
||||
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