This commit is contained in:
Thomas Fransolet 2026-05-09 00:23:04 +02:00
parent 2e8b82aa80
commit 205f1ec933
27 changed files with 1379 additions and 462 deletions

View File

@ -1,6 +1,24 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_api_new/api.dart'; import 'package:manager_api_new/api.dart';
String getSectionTypeName(SectionType? type) {
switch (type) {
case SectionType.Map: return 'Map';
case SectionType.Slider: return 'Slider';
case SectionType.Video: return 'Vidéo';
case SectionType.Web: return 'Web';
case SectionType.Menu: return 'Menu';
case SectionType.Quiz: return 'Quiz';
case SectionType.Article: return 'Article';
case SectionType.Pdf: return 'PDF';
case SectionType.Game: return 'Jeu';
case SectionType.Agenda: return 'Agenda';
case SectionType.Weather: return 'Météo';
case SectionType.Event: return 'Événement';
default: return 'Section';
}
}
IconData getSectionIcon(elementType) { IconData getSectionIcon(elementType) {
switch(elementType) { switch(elementType) {
case SectionType.Map: case SectionType.Map:

View File

@ -1,38 +1,26 @@
//import 'package:another_flushbar/flushbar.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toastification/toastification.dart';
import 'package:manager_app/constants.dart';
showNotification (Color backgroundColor, Color textColor, String text, BuildContext context, int? duration) async { showNotification(Color backgroundColor, Color textColor, String text, BuildContext context, int? duration) {
final ToastificationType type;
if (backgroundColor == kSuccess) {
type = ToastificationType.success;
} else if (backgroundColor == kError) {
type = ToastificationType.error;
} else if (backgroundColor == Colors.orange) {
type = ToastificationType.warning;
} else {
type = ToastificationType.info;
}
/*await Flushbar( toastification.show(
message: text, context: context,
messageColor: textColor, type: type,
margin: EdgeInsets.all(8), style: ToastificationStyle.fillColored,
backgroundColor: backgroundColor, description: Text(text, softWrap: true),
borderRadius: BorderRadius.circular(8), alignment: Alignment.topRight,
duration: duration == null ? Duration(milliseconds: 1500) : Duration(milliseconds: duration), autoCloseDuration: Duration(milliseconds: duration ?? 4000),
).show(context);*/ pauseOnHover: true,
final snackBar = SnackBar(
behavior: SnackBarBehavior.floating,
duration: duration == null ? Duration(milliseconds: 1500) : Duration(milliseconds: duration),
width: 450.0, // Width of the SnackBar.
backgroundColor: backgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
padding: const EdgeInsets.symmetric(
horizontal: 10.0, // Inner padding for SnackBar content.
),
content: Container(
height: 50.5,
child: Center(
child: Text(
text,
textAlign: TextAlign.center,
style: TextStyle(color: textColor),
),
),
)
); );
ScaffoldMessenger.of(context).showSnackBar(snackBar);
} }

View File

@ -17,7 +17,7 @@ showMultiStringInputHTML (String label, String modalLabel, bool isTitle, List<Tr
), ),
insetPadding: const EdgeInsets.symmetric(horizontal: 60, vertical: 24), insetPadding: const EdgeInsets.symmetric(horizontal: 60, vertical: 24),
child: ConstrainedBox( child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 800), constraints: BoxConstraints(maxWidth: 800, maxHeight: MediaQuery.of(context).size.height - 48),
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(24, 20, 24, 16), padding: const EdgeInsets.fromLTRB(24, 20, 24, 16),
child: Column( child: Column(
@ -28,7 +28,7 @@ showMultiStringInputHTML (String label, String modalLabel, bool isTitle, List<Tr
Flexible( Flexible(
child: TranslationInputContainer(isTitle: isTitle, values: values, newValues: newValues, onGetResult: onGetResult, maxLines: maxLines, resourceTypes: resourceTypes), child: TranslationInputContainer(isTitle: isTitle, values: values, newValues: newValues, onGetResult: onGetResult, maxLines: maxLines, resourceTypes: resourceTypes),
), ),
const SizedBox(height: 8), const SizedBox(height: 16),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
@ -91,7 +91,7 @@ showMultiStringInputAndResourceHTML (String label, String modalLabel, bool isTit
), ),
insetPadding: const EdgeInsets.symmetric(horizontal: 60, vertical: 24), insetPadding: const EdgeInsets.symmetric(horizontal: 60, vertical: 24),
child: ConstrainedBox( child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 800), constraints: BoxConstraints(maxWidth: 800, maxHeight: MediaQuery.of(context).size.height - 48),
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(24, 20, 24, 16), padding: const EdgeInsets.fromLTRB(24, 20, 24, 16),
child: Column( child: Column(

View File

@ -169,6 +169,7 @@ class _TranslationInputAndResourceContainerState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Flexible( Flexible(

View File

@ -189,6 +189,7 @@ class _TranslationInputContainerState extends State<TranslationInputContainer> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Flexible( Flexible(
@ -219,19 +220,22 @@ class _TranslationInputContainerState extends State<TranslationInputContainer> {
Builder(builder: (ctx) { Builder(builder: (ctx) {
final instance = ctx.watch<AppContext>().getContext()?.instanceDTO; final instance = ctx.watch<AppContext>().getContext()?.instanceDTO;
if (instance?.isAssistant != true) return const SizedBox.shrink(); if (instance?.isAssistant != true) return const SizedBox.shrink();
return Center( return Padding(
child: SizedBox( padding: const EdgeInsets.only(top: 8),
width: 370, child: Center(
height: 70, child: SizedBox(
child: _isTranslating width: 370,
? const Center(child: CircularProgressIndicator()) height: 70,
: RoundedButton( child: _isTranslating
text: "Traduire via IA", ? const Center(child: CircularProgressIndicator())
icon: Icons.auto_awesome, : RoundedButton(
color: kPrimaryColor, text: "Traduire via IA",
press: _translateWithAI, icon: Icons.auto_awesome,
fontSize: 20, color: kPrimaryColor,
), press: _translateWithAI,
fontSize: 20,
),
),
), ),
); );
}), }),

View File

@ -14,6 +14,8 @@ class ManagerAppContext with ChangeNotifier{
Client? clientAPI; Client? clientAPI;
ConfigurationDTO? selectedConfiguration; ConfigurationDTO? selectedConfiguration;
SectionDTO? selectedSection; SectionDTO? selectedSection;
SectionDTO? selectedSubSection;
Object? selectedSubSectionRawData;
bool? isLoading = false; bool? isLoading = false;
UserRole? role; UserRole? role;
Locale locale = const Locale('fr'); Locale locale = const Locale('fr');

View File

@ -54,7 +54,6 @@ class _WebInstanceLoaderState extends State<WebInstanceLoader> {
languages: ['fr'], languages: ['fr'],
layoutMainPage: LayoutMainPageType.MasonryGrid, layoutMainPage: LayoutMainPageType.MasonryGrid,
isAssistant: false, isAssistant: false,
isStatistic: false,
); );
final created = await managerCtx.clientAPI!.applicationInstanceApi! final created = await managerCtx.clientAPI!.applicationInstanceApi!

View File

@ -35,6 +35,12 @@ class _EventConfigState extends State<EventConfig> {
void initState() { void initState() {
super.initState(); super.initState();
eventDTO = widget.initialValue; eventDTO = widget.initialValue;
if (eventDTO.startDate != null && eventDTO.startDate!.toUtc().year < 1000) {
eventDTO.startDate = null;
}
if (eventDTO.endDate != null && eventDTO.endDate!.toUtc().year < 1000) {
eventDTO.endDate = null;
}
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_loadProgrammeBlocks(); _loadProgrammeBlocks();
_loadGlobalAnnotations(); _loadGlobalAnnotations();

View File

@ -5,7 +5,6 @@ import 'package:manager_app/l10n/app_localizations.dart';
import 'package:manager_app/Components/fetch_section_icon.dart'; import 'package:manager_app/Components/fetch_section_icon.dart';
import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/Components/message_notification.dart';
import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/Models/managerContext.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Menu/showEditSubSection.dart';
import 'package:manager_app/app_context.dart'; import 'package:manager_app/app_context.dart';
import 'package:manager_app/constants.dart'; import 'package:manager_app/constants.dart';
import 'package:manager_api_new/api.dart'; import 'package:manager_api_new/api.dart';
@ -61,27 +60,10 @@ class _ListViewCardSubSection extends State<ListViewCardSubSection> {
children: [ children: [
InkWell( InkWell(
onTap: () { onTap: () {
showEditSubSection( final ctx = appContext.getContext() as ManagerAppContext;
widget.listItems[widget.index], ctx.selectedSubSection = widget.listItems[widget.index];
(Object value) async { ctx.selectedSubSectionRawData = widget.rawData;
final l = AppLocalizations.of(context)!; appContext.setContext(ctx);
try {
var test = updateSectionDetail(widget.listItems[widget.index], value);
// update sub section
await (appContext.getContext() as ManagerAppContext).clientAPI!.sectionApi!.sectionUpdate(test);
showNotification(kSuccess, kWhite, l.subSectionUpdatedSuccess, context, null);
setState(() {
//widget.listItems[widget.index] = value;
widget.onChanged(widget.listItems); // For resfreh ui
});
} catch(e) {
showNotification(kError, kWhite, l.subSectionUpdateError, context, null);
}
},
widget.appContext,
context,
widget.rawData
);
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.all(6.0), padding: const EdgeInsets.all(6.0),
@ -191,60 +173,6 @@ class _ListViewCardSubSection extends State<ListViewCardSubSection> {
); );
} }
dynamic updateSectionDetail(SectionDTO sectionDTO, Object sectionDetailDTO) {
dynamic castedDetail;
switch (sectionDTO.type) {
case SectionType.Map:
castedDetail = sectionDetailDTO is MapDTO ? sectionDetailDTO : MapDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Slider:
castedDetail = sectionDetailDTO is SliderDTO ? sectionDetailDTO : SliderDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Video:
castedDetail = sectionDetailDTO is VideoDTO ? sectionDetailDTO : VideoDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Web:
castedDetail = sectionDetailDTO is WebDTO ? sectionDetailDTO : WebDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Quiz:
castedDetail = sectionDetailDTO is QuizDTO ? sectionDetailDTO : QuizDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Pdf:
castedDetail = sectionDetailDTO is PdfDTO ? sectionDetailDTO : PdfDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Game:
castedDetail = sectionDetailDTO is GameDTO ? sectionDetailDTO : GameDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Agenda:
castedDetail = sectionDetailDTO is AgendaDTO ? sectionDetailDTO : AgendaDTO.fromJson(sectionDetailDTO)!;
break;
case SectionType.Weather:
castedDetail = sectionDetailDTO is WeatherDTO ? sectionDetailDTO : WeatherDTO.fromJson(sectionDetailDTO)!;
break;
}
// Mise à jour générique des champs communs
castedDetail.id = sectionDTO.id;
castedDetail.order = sectionDTO.order;
castedDetail.dateCreation = sectionDTO.dateCreation;
castedDetail.type = sectionDTO.type;
castedDetail.instanceId = sectionDTO.instanceId;
castedDetail.configurationId = sectionDTO.configurationId;
castedDetail.isSubSection = sectionDTO.isSubSection;
castedDetail.parentId = sectionDTO.parentId;
castedDetail.label = sectionDTO.label;
castedDetail.title = sectionDTO.title;
castedDetail.description = sectionDTO.description;
castedDetail.imageId = sectionDTO.imageId;
castedDetail.imageSource = sectionDTO.imageSource;
castedDetail.isBeacon = sectionDTO.isBeacon;
castedDetail.beaconId = sectionDTO.beaconId;
castedDetail.latitude = sectionDTO.latitude;
castedDetail.longitude = sectionDTO.longitude;
castedDetail.meterZoneGPS = sectionDTO.meterZoneGPS;
return castedDetail;
}
} }

View File

@ -1,293 +0,0 @@
import 'package:manager_app/Components/resource_input_container.dart';
import 'package:flutter/material.dart';
import 'package:manager_app/Components/multi_string_input_container.dart';
import 'package:manager_app/Components/rounded_button.dart';
import 'package:manager_app/Components/string_input_container.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Agenda/agenda_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Article/article_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Game/game_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Map/map_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/PDF/PDF_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Quizz/quizz_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Slider/slider_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Video/video_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Weather/weather_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/WebOrVideo/web_config.dart';
import 'package:manager_app/app_context.dart';
import 'package:manager_app/constants.dart';
import 'package:manager_app/l10n/app_localizations.dart';
import 'package:manager_api_new/api.dart';
import 'menu_config.dart';
void showEditSubSection(SectionDTO subSectionDTO, Function getResult, AppContext appContext, BuildContext context, Object rawSubSectionData) {
Object updatedRawSubSectionData = rawSubSectionData;
Size size = MediaQuery.of(context).size;
showDialog(
builder: (BuildContext context) => Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0))
),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.85,
child: Padding(
padding: const EdgeInsets.fromLTRB(24, 20, 24, 24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
child: SingleChildScrollView(
child: Column(
children: [
Text("Modifier sous section", style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
height: 100,
child: StringInputContainer(
label: "Nom :",
initialValue: subSectionDTO.label,
onChanged: (String name) {
subSectionDTO.label = name;
},
),
),
ResourceInputContainer(
label: "Image :",
initialValue: subSectionDTO.imageId,
color: kPrimaryColor,
onChanged: (ResourceDTO resource) {
if(resource.id == null) {
subSectionDTO.imageId = null;
subSectionDTO.imageSource = null;
} else {
subSectionDTO.imageId = resource.id;
subSectionDTO.imageSource = resource.url;
}
},
isSmall: true,
),
],
),
Container(
height: size.height * 0.1,
width: double.infinity,
constraints: BoxConstraints(minHeight: 50),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
constraints: BoxConstraints(minHeight: 50, maxHeight: 80),
child: MultiStringInputContainer(
label: AppLocalizations.of(context)!.displayTitleLabel,
modalLabel: "Titre",
fontSize: 20,
isHTML: true,
color: kPrimaryColor,
initialValue: subSectionDTO.title != null ? subSectionDTO.title! : [],
onGetResult: (value) {
if (subSectionDTO.title != value) {
subSectionDTO.title = value;
}
},
maxLines: 1,
isTitle: true
),
),
Container(
constraints: BoxConstraints(minHeight: 50, maxHeight: 80),
child: MultiStringInputContainer(
label: AppLocalizations.of(context)!.displayedDescriptionLabel,
modalLabel: "Description",
fontSize: 20,
isHTML: true,
color: kPrimaryColor,
initialValue: subSectionDTO.description != null ? subSectionDTO.description! : [],
isMandatory: false,
onGetResult: (value) {
if (subSectionDTO.description != value) {
subSectionDTO.description = value;
}
},
maxLines: 1,
isTitle: false
),
),
],
)
),
Container(
decoration: BoxDecoration(
color: kWhite,
borderRadius: BorderRadius.circular(20),
border: Border.all(width: 0.5, color: kSecond)
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: getSpecificData(
subSectionDTO,
rawSubSectionData,
rawSubSectionData,
appContext,
(updatedData) {
updatedRawSubSectionData = updatedData;
}, context),
),
),
],
),
],
),
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Align(
alignment: AlignmentDirectional.bottomEnd,
child: Container(
width: 175,
height: 70,
child: RoundedButton(
text: "Annuler",
icon: Icons.undo,
color: kSecond,
press: () {
Navigator.of(context).pop();
},
fontSize: 20,
),
),
),
Align(
alignment: AlignmentDirectional.bottomEnd,
child: Container(
width: subSectionDTO != null ? 220: 150,
height: 70,
child: RoundedButton(
text: "Sauvegarder",
icon: Icons.check,
color: kPrimaryColor,
textColor: kWhite,
press: () {
getResult(updatedRawSubSectionData);
Navigator.of(context).pop();
},
fontSize: 20,
),
),
),
],
),
],
),
),
),
), context: context
);
}
getSpecificData(SectionDTO subSectionDTO, Object? rawSectionData, Object sectionDetailDTO, AppContext appContext, Function(Object) onChanged, [BuildContext? context]) {
switch(subSectionDTO.type) {
case SectionType.Map:
MapDTO mapDTO = MapDTO.fromJson(rawSectionData)!;
sectionDetailDTO = mapDTO;
return MapConfig(
initialValue: mapDTO,
onChanged: (MapDTO changedMap) {
onChanged(changedMap);
},
);
case SectionType.Slider:
SliderDTO sliderDTO = SliderDTO.fromJson(rawSectionData)!;
sectionDetailDTO = sliderDTO;
return SliderConfig(
initialValue: sliderDTO,
onChanged: (SliderDTO changedSlider) {
onChanged(changedSlider);
},
);
case SectionType.Video:
VideoDTO videoDTO = VideoDTO.fromJson(rawSectionData)!;
sectionDetailDTO = videoDTO;
return VideoConfig(
label: context != null ? AppLocalizations.of(context)!.videoUrlLabel : "Url de la vidéo:",
initialValue: videoDTO,
onChanged: (VideoDTO updatedWebDTO) {
onChanged(updatedWebDTO);
},
);
case SectionType.Web:
WebDTO webDTO = WebDTO.fromJson(rawSectionData)!;
sectionDetailDTO = webDTO;
return WebConfig(
label: "Url du site web:",
initialValue: webDTO,
onChanged: (WebDTO updatedWebDTO) {
onChanged(updatedWebDTO);
},
);
case SectionType.Quiz:
QuizDTO quizDTO = QuizDTO.fromJson(rawSectionData)!;
sectionDetailDTO = quizDTO;
return QuizzConfig(
initialValue: quizDTO,
onChanged: (QuizDTO updatedQuiz) {
onChanged(updatedQuiz);
},
);
case SectionType.Article:
ArticleDTO articleDTO = ArticleDTO.fromJson(rawSectionData)!;
sectionDetailDTO = articleDTO;
return ArticleConfig(
initialValue: articleDTO,
onChanged: (ArticleDTO changedArticle)
{
onChanged(changedArticle);
},
);
case SectionType.Pdf:
PdfDTO pdfDTO = PdfDTO.fromJson(rawSectionData)!;
sectionDetailDTO = pdfDTO;
return PDFConfig(
initialValue: pdfDTO,
onChanged: (PdfDTO changedPDF) {
onChanged(changedPDF);
},
);
case SectionType.Game:
GameDTO gameDTO = GameDTO.fromJson(rawSectionData)!;
sectionDetailDTO = gameDTO;
return GameConfig(
initialValue: gameDTO,
onChanged: (GameDTO updatedGame) {
onChanged(updatedGame);
},
);
case SectionType.Agenda:
AgendaDTO agendaDTO = AgendaDTO.fromJson(rawSectionData)!;
sectionDetailDTO = agendaDTO;
return AgendaConfig(
initialValue: agendaDTO,
onChanged: (AgendaDTO updatedAgenda) {
onChanged(updatedAgenda);
},
);
case SectionType.Weather:
WeatherDTO weatherDTO = WeatherDTO.fromJson(rawSectionData)!;
sectionDetailDTO = weatherDTO;
return WeatherConfig(
initialValue: weatherDTO,
onChanged: (WeatherDTO updatedWeather) {
onChanged(updatedWeather);
},
);
}
}

View File

@ -0,0 +1,394 @@
import 'package:flutter/material.dart';
import 'package:manager_app/Components/fetch_section_icon.dart';
import 'package:manager_app/Components/message_notification.dart';
import 'package:manager_app/Components/multi_string_input_container.dart';
import 'package:manager_app/Components/resource_input_container.dart';
import 'package:manager_app/Components/string_input_container.dart';
import 'package:manager_app/Models/managerContext.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Agenda/agenda_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Article/article_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Game/game_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Map/map_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/PDF/PDF_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Quizz/quizz_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Slider/slider_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Video/video_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Event/event_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/Weather/weather_config.dart';
import 'package:manager_app/Screens/Configurations/Section/SubSection/WebOrVideo/web_config.dart';
import 'package:manager_app/app_context.dart';
import 'package:manager_app/constants.dart';
import 'package:manager_app/l10n/app_localizations.dart';
import 'package:manager_api_new/api.dart';
import 'package:provider/provider.dart';
class SubSectionEditScreen extends StatefulWidget {
final SectionDTO subSectionDTO;
final Object rawData;
const SubSectionEditScreen({
Key? key,
required this.subSectionDTO,
required this.rawData,
}) : super(key: key);
@override
_SubSectionEditScreenState createState() => _SubSectionEditScreenState();
}
class _SubSectionEditScreenState extends State<SubSectionEditScreen> {
late SectionDTO subSectionDTO;
Object? sectionDetailDTO;
@override
void initState() {
super.initState();
subSectionDTO = widget.subSectionDTO;
_initializeDetailDTO();
}
void _initializeDetailDTO() {
final raw = widget.rawData;
switch (subSectionDTO.type) {
case SectionType.Map:
sectionDetailDTO = MapDTO.fromJson(raw)!;
break;
case SectionType.Slider:
sectionDetailDTO = SliderDTO.fromJson(raw)!;
break;
case SectionType.Video:
sectionDetailDTO = VideoDTO.fromJson(raw)!;
break;
case SectionType.Web:
sectionDetailDTO = WebDTO.fromJson(raw)!;
break;
case SectionType.Quiz:
sectionDetailDTO = QuizDTO.fromJson(raw)!;
break;
case SectionType.Article:
sectionDetailDTO = ArticleDTO.fromJson(raw)!;
break;
case SectionType.Pdf:
sectionDetailDTO = PdfDTO.fromJson(raw)!;
break;
case SectionType.Game:
sectionDetailDTO = GameDTO.fromJson(raw)!;
break;
case SectionType.Agenda:
sectionDetailDTO = AgendaDTO.fromJson(raw)!;
break;
case SectionType.Weather:
sectionDetailDTO = WeatherDTO.fromJson(raw)!;
break;
case SectionType.Event:
sectionDetailDTO = SectionEventDTO.fromJson(raw)!;
break;
default:
sectionDetailDTO = null;
}
}
@override
Widget build(BuildContext context) {
final l = AppLocalizations.of(context)!;
return Column(
children: [
_buildHeader(l),
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_cardIdentity(l),
if (sectionDetailDTO != null) ...[
const SizedBox(height: 12),
_cardTypeConfig(),
],
const SizedBox(height: 80),
],
),
),
),
_buildFooter(l),
],
);
}
void _goBack() {
final appContext = Provider.of<AppContext>(context, listen: false);
final ctx = appContext.getContext() as ManagerAppContext;
ctx.selectedSubSection = null;
ctx.selectedSubSectionRawData = null;
appContext.setContext(ctx);
}
Widget _buildHeader(AppLocalizations l) {
final typeName = getSectionTypeName(subSectionDTO.type);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: kWhite,
border: Border(bottom: BorderSide(color: kSecond, width: 1)),
),
child: Row(
children: [
IconButton(
icon: const Icon(Icons.arrow_back, color: kPrimaryColor),
onPressed: _goBack,
),
const SizedBox(width: 8),
Icon(getSectionIcon(subSectionDTO.type), color: kPrimaryColor, size: 22),
const SizedBox(width: 8),
Expanded(
child: Text(
subSectionDTO.label ?? '',
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
),
),
Chip(
label: Text(typeName.toUpperCase()),
backgroundColor: kPrimaryColor.withValues(alpha: 0.1),
labelStyle: const TextStyle(
color: kPrimaryColor, fontWeight: FontWeight.w600, fontSize: 11),
side: BorderSide.none,
visualDensity: VisualDensity.compact,
),
],
),
);
}
Widget _cardIdentity(AppLocalizations l) {
return Card(
elevation: 0,
color: kWhite,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l.identifierLabel.replaceAll(':', '').trim(),
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
color: kTitleTextColor),
),
const SizedBox(height: 12),
StringInputContainer(
label: l.identifierLabel,
initialValue: subSectionDTO.label,
onChanged: (value) => subSectionDTO.label = value,
),
const SizedBox(height: 12),
ResourceInputContainer(
label: l.imageLabel,
initialValue: subSectionDTO.imageId,
color: kPrimaryColor,
onChanged: (ResourceDTO resource) {
if (resource.id == null) {
subSectionDTO.imageId = null;
subSectionDTO.imageSource = null;
} else {
subSectionDTO.imageId = resource.id;
subSectionDTO.imageSource = resource.url;
}
},
),
const SizedBox(height: 12),
MultiStringInputContainer(
label: l.displayTitleLabel,
modalLabel: l.messageTitle,
color: kPrimaryColor,
initialValue: subSectionDTO.title ?? [],
onGetResult: (value) {
if (subSectionDTO.title != value) subSectionDTO.title = value;
},
maxLines: 1,
isHTML: true,
isTitle: true,
),
const SizedBox(height: 12),
MultiStringInputContainer(
label: l.displayedDescriptionLabel,
modalLabel: "Description",
color: kPrimaryColor,
initialValue: subSectionDTO.description ?? [],
isMandatory: false,
onGetResult: (value) {
if (subSectionDTO.description != value) {
subSectionDTO.description = value;
}
},
maxLines: 1,
isHTML: true,
isTitle: false,
),
],
),
),
);
}
Widget _cardTypeConfig() {
final typeName = getSectionTypeName(subSectionDTO.type);
return Card(
elevation: 0,
color: kWhite,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Configuration $typeName",
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
color: kTitleTextColor),
),
const SizedBox(height: 12),
_getSpecificConfig(),
],
),
),
);
}
Widget _getSpecificConfig() {
final l = AppLocalizations.of(context)!;
switch (subSectionDTO.type) {
case SectionType.Map:
return MapConfig(
initialValue: sectionDetailDTO as MapDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Slider:
return SliderConfig(
initialValue: sectionDetailDTO as SliderDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Video:
return VideoConfig(
label: l.videoUrlLabel,
initialValue: sectionDetailDTO as VideoDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Web:
return WebConfig(
label: l.webUrlLabel,
initialValue: sectionDetailDTO as WebDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Quiz:
return QuizzConfig(
initialValue: sectionDetailDTO as QuizDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Article:
return ArticleConfig(
initialValue: sectionDetailDTO as ArticleDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Pdf:
return PDFConfig(
initialValue: sectionDetailDTO as PdfDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Game:
return GameConfig(
initialValue: sectionDetailDTO as GameDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Agenda:
return AgendaConfig(
initialValue: sectionDetailDTO as AgendaDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Weather:
return WeatherConfig(
initialValue: sectionDetailDTO as WeatherDTO,
onChanged: (v) => sectionDetailDTO = v,
);
case SectionType.Event:
return EventConfig(
initialValue: sectionDetailDTO as SectionEventDTO,
onChanged: (v) => sectionDetailDTO = v,
);
default:
return const SizedBox.shrink();
}
}
Widget _buildFooter(AppLocalizations l) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: const BoxDecoration(
color: kWhite,
boxShadow: [
BoxShadow(color: kSecond, blurRadius: 8, offset: Offset(0, -2))
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton.icon(
icon: const Icon(Icons.undo, size: 16),
label: Text(l.cancel),
onPressed: _goBack,
),
const SizedBox(width: 8),
ElevatedButton.icon(
icon: const Icon(Icons.done, size: 16, color: kWhite),
label: Text(l.save, style: const TextStyle(color: kWhite)),
style: ElevatedButton.styleFrom(backgroundColor: kPrimaryColor),
onPressed: _save,
),
],
),
);
}
Future<void> _save() async {
final appContext = Provider.of<AppContext>(context, listen: false);
final l = AppLocalizations.of(context)!;
try {
final detailToSave = _buildDetailDTOWithFields();
await (appContext.getContext() as ManagerAppContext)
.clientAPI!
.sectionApi!
.sectionUpdate(detailToSave);
showNotification(kSuccess, kWhite, l.subSectionUpdatedSuccess, context, null);
if (mounted) _goBack();
} catch (e) {
showNotification(kError, kWhite, l.subSectionUpdateError, context, null);
}
}
dynamic _buildDetailDTOWithFields() {
dynamic detail = sectionDetailDTO;
detail.id = subSectionDTO.id;
detail.order = subSectionDTO.order;
detail.dateCreation = subSectionDTO.dateCreation;
detail.type = subSectionDTO.type;
detail.instanceId = subSectionDTO.instanceId;
detail.configurationId = subSectionDTO.configurationId;
detail.isSubSection = subSectionDTO.isSubSection;
detail.parentId = subSectionDTO.parentId;
detail.label = subSectionDTO.label;
detail.title = subSectionDTO.title;
detail.description = subSectionDTO.description;
detail.imageId = subSectionDTO.imageId;
detail.imageSource = subSectionDTO.imageSource;
detail.isBeacon = subSectionDTO.isBeacon;
detail.beaconId = subSectionDTO.beaconId;
detail.latitude = subSectionDTO.latitude;
detail.longitude = subSectionDTO.longitude;
detail.meterZoneGPS = subSectionDTO.meterZoneGPS;
return detail;
}
}

View File

@ -142,7 +142,7 @@ class _SectionDetailScreenState extends State<SectionDetailScreen> {
// Header // Header
Widget _buildHeader(AppContext appContext, AppLocalizations l) { Widget _buildHeader(AppContext appContext, AppLocalizations l) {
final typeName = sectionDTO.type?.toString().split('.').last ?? ''; final typeName = getSectionTypeName(sectionDTO.type);
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
@ -404,7 +404,7 @@ class _SectionDetailScreenState extends State<SectionDetailScreen> {
// Card Type Config // Card Type Config
Widget _cardTypeConfig(Object? rawSectionData, AppContext appContext) { Widget _cardTypeConfig(Object? rawSectionData, AppContext appContext) {
final typeName = sectionDTO.type?.toString().split('.').last ?? 'Section'; final typeName = getSectionTypeName(sectionDTO.type);
return Card( return Card(
elevation: 0, elevation: 0,
color: kWhite, color: kWhite,

View File

@ -14,6 +14,7 @@ import 'package:provider/provider.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'Section/section_detail_screen.dart'; import 'Section/section_detail_screen.dart';
import 'Section/SubSection/Menu/sub_section_edit_screen.dart';
class ConfigurationsScreen extends StatefulWidget { class ConfigurationsScreen extends StatefulWidget {
ConfigurationsScreen({Key? key}) : super(key: key); ConfigurationsScreen({Key? key}) : super(key: key);
@ -35,6 +36,12 @@ class _ConfigurationsScreenState extends State<ConfigurationsScreen> {
final Size size = MediaQuery.of(context).size; final Size size = MediaQuery.of(context).size;
final ManagerAppContext managerAppContext = appContext.getContext(); final ManagerAppContext managerAppContext = appContext.getContext();
if (managerAppContext.selectedSubSection != null) {
return SubSectionEditScreen(
subSectionDTO: managerAppContext.selectedSubSection!,
rawData: managerAppContext.selectedSubSectionRawData!,
);
}
if (managerAppContext.selectedSection != null) { if (managerAppContext.selectedSection != null) {
return SectionDetailScreen(id: managerAppContext.selectedSection!.id!); return SectionDetailScreen(id: managerAppContext.selectedSection!.id!);
} }

View File

@ -62,7 +62,7 @@ class _MainScreenState extends State<MainScreen> {
resources = MenuSection(name: "Ressources", type: "resources", menuId: 6, subMenu: []); resources = MenuSection(name: "Ressources", type: "resources", menuId: 6, subMenu: []);
menu.sections = [devices, configurations, resources]; menu.sections = [devices, configurations, resources];
if (widget.instance.isStatistic == true) { if (widget.instance.hasStats == true) {
menu.sections!.add(MenuSection(name: "Statistiques", type: "statistics", menuId: 7, subMenu: [])); menu.sections!.add(MenuSection(name: "Statistiques", type: "statistics", menuId: 7, subMenu: []));
} }
@ -143,7 +143,8 @@ class _MainScreenState extends State<MainScreen> {
name: instanceDetail?.name, name: instanceDetail?.name,
pinCode: instanceDetail?.pinCode, pinCode: instanceDetail?.pinCode,
isPushNotification: instanceDetail?.isPushNotification, isPushNotification: instanceDetail?.isPushNotification,
isStatistic: instanceDetail?.isStatistic, hasStats: instanceDetail?.hasStats,
hasAdvancedStats: instanceDetail?.hasAdvancedStats,
isMobile: instanceDetail?.isMobile, isMobile: instanceDetail?.isMobile,
isTablet: instanceDetail?.isTablet, isTablet: instanceDetail?.isTablet,
isWeb: instanceDetail?.isWeb, isWeb: instanceDetail?.isWeb,

View File

@ -28,6 +28,7 @@ class _StatisticsScreenState extends State<StatisticsScreen> {
} }
void _load() { void _load() {
if (_managerAppContext.instanceDTO?.hasStats != true) return;
final days = _selectedDays; final days = _selectedDays;
final appType = _selectedAppType; final appType = _selectedAppType;
setState(() { setState(() {

View File

@ -1,4 +1,4 @@
// Openapi Generator last run: : 2026-03-13T16:08:54.634997 // Openapi Generator last run: : 2026-05-07T21:23:24.036284
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart'; import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';
@Openapi( @Openapi(

View File

@ -6172,7 +6172,7 @@
"isAssistant": { "isAssistant": {
"type": "boolean" "type": "boolean"
}, },
"isStatistic": { "hasStats": {
"type": "boolean" "type": "boolean"
} }
} }
@ -7937,9 +7937,6 @@
"isPushNotification": { "isPushNotification": {
"type": "boolean" "type": "boolean"
}, },
"isStatistic": {
"type": "boolean"
},
"isMobile": { "isMobile": {
"type": "boolean" "type": "boolean"
}, },
@ -7981,9 +7978,6 @@
"isPushNotification": { "isPushNotification": {
"type": "boolean" "type": "boolean"
}, },
"isStatistic": {
"type": "boolean"
},
"isMobile": { "isMobile": {
"type": "boolean" "type": "boolean"
}, },

View File

@ -21,6 +21,7 @@ import 'app_context.dart';
import 'client.dart'; import 'client.dart';
import 'constants.dart'; import 'constants.dart';
import 'package:flutter_web_plugins/url_strategy.dart'; import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:toastification/toastification.dart';
import 'dart:html' as html; import 'dart:html' as html;
//import 'package:window_size/window_size.dart'; //import 'package:window_size/window_size.dart';
@ -237,7 +238,8 @@ class _MyAppState extends State<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final locale = Provider.of<AppContext>(context).getContext()?.locale ?? const Locale('fr'); final locale = Provider.of<AppContext>(context).getContext()?.locale ?? const Locale('fr');
return MaterialApp.router( return ToastificationWrapper(
child: MaterialApp.router(
routerConfig: widget.router, routerConfig: widget.router,
key: mainKey, key: mainKey,
builder: (context, child) => ResponsiveBreakpoints.builder( builder: (context, child) => ResponsiveBreakpoints.builder(
@ -289,6 +291,7 @@ class _MyAppState extends State<MyApp> {
onUnknownRoute: (settings) => MaterialPageRoute( onUnknownRoute: (settings) => MaterialPageRoute(
builder: (context) => Container(child: Center(child: Text("Not found"))), builder: (context) => Container(child: Center(child: Text("Not found"))),
),*/ ),*/
),
); );
} }
} }

View File

@ -28,7 +28,7 @@ class ApplicationInstanceDTO {
this.sectionEventId, this.sectionEventId,
this.sectionEventDTO, this.sectionEventDTO,
this.isAssistant, this.isAssistant,
this.isStatistic, this.hasStats,
}); });
String? id; String? id;
@ -73,7 +73,7 @@ class ApplicationInstanceDTO {
bool? isAssistant; bool? isAssistant;
bool? isStatistic; bool? hasStats;
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
@ -94,7 +94,7 @@ class ApplicationInstanceDTO {
other.sectionEventId == sectionEventId && other.sectionEventId == sectionEventId &&
other.sectionEventDTO == sectionEventDTO && other.sectionEventDTO == sectionEventDTO &&
other.isAssistant == isAssistant && other.isAssistant == isAssistant &&
other.isStatistic == isStatistic; other.hasStats == hasStats;
@override @override
int get hashCode => int get hashCode =>
@ -114,11 +114,11 @@ class ApplicationInstanceDTO {
(sectionEventId == null ? 0 : sectionEventId!.hashCode) + (sectionEventId == null ? 0 : sectionEventId!.hashCode) +
(sectionEventDTO == null ? 0 : sectionEventDTO!.hashCode) + (sectionEventDTO == null ? 0 : sectionEventDTO!.hashCode) +
(isAssistant == null ? 0 : isAssistant!.hashCode) + (isAssistant == null ? 0 : isAssistant!.hashCode) +
(isStatistic == null ? 0 : isStatistic!.hashCode); (hasStats == null ? 0 : hasStats!.hashCode);
@override @override
String toString() => String toString() =>
'ApplicationInstanceDTO[id=$id, instanceId=$instanceId, appType=$appType, configurations=$configurations, mainImageId=$mainImageId, mainImageUrl=$mainImageUrl, loaderImageId=$loaderImageId, loaderImageUrl=$loaderImageUrl, primaryColor=$primaryColor, secondaryColor=$secondaryColor, layoutMainPage=$layoutMainPage, languages=$languages, sectionEventId=$sectionEventId, sectionEventDTO=$sectionEventDTO, isAssistant=$isAssistant, isStatistic=$isStatistic]'; 'ApplicationInstanceDTO[id=$id, instanceId=$instanceId, appType=$appType, configurations=$configurations, mainImageId=$mainImageId, mainImageUrl=$mainImageUrl, loaderImageId=$loaderImageId, loaderImageUrl=$loaderImageUrl, primaryColor=$primaryColor, secondaryColor=$secondaryColor, layoutMainPage=$layoutMainPage, languages=$languages, sectionEventId=$sectionEventId, sectionEventDTO=$sectionEventDTO, isAssistant=$isAssistant, hasStats=$hasStats]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -197,10 +197,10 @@ class ApplicationInstanceDTO {
} else { } else {
json[r'isAssistant'] = null; json[r'isAssistant'] = null;
} }
if (this.isStatistic != null) { if (this.hasStats != null) {
json[r'isStatistic'] = this.isStatistic; json[r'hasStats'] = this.hasStats;
} else { } else {
json[r'isStatistic'] = null; json[r'hasStats'] = null;
} }
return json; return json;
} }
@ -246,7 +246,7 @@ class ApplicationInstanceDTO {
sectionEventId: mapValueOfType<String>(json, r'sectionEventId'), sectionEventId: mapValueOfType<String>(json, r'sectionEventId'),
sectionEventDTO: SectionEventDTO.fromJson(json[r'sectionEventDTO']), sectionEventDTO: SectionEventDTO.fromJson(json[r'sectionEventDTO']),
isAssistant: mapValueOfType<bool>(json, r'isAssistant'), isAssistant: mapValueOfType<bool>(json, r'isAssistant'),
isStatistic: mapValueOfType<bool>(json, r'isStatistic'), hasStats: mapValueOfType<bool>(json, r'hasStats'),
); );
} }
return null; return null;

View File

@ -0,0 +1,175 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class DayStatDTO {
/// Returns a new [DayStatDTO] instance.
DayStatDTO({
this.date,
this.total,
this.mobile,
this.tablet,
});
String? date;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? total;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? mobile;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? tablet;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is DayStatDTO &&
other.date == date &&
other.total == total &&
other.mobile == mobile &&
other.tablet == tablet;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(date == null ? 0 : date!.hashCode) +
(total == null ? 0 : total!.hashCode) +
(mobile == null ? 0 : mobile!.hashCode) +
(tablet == null ? 0 : tablet!.hashCode);
@override
String toString() =>
'DayStatDTO[date=$date, total=$total, mobile=$mobile, tablet=$tablet]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.date != null) {
json[r'date'] = this.date;
} else {
json[r'date'] = null;
}
if (this.total != null) {
json[r'total'] = this.total;
} else {
json[r'total'] = null;
}
if (this.mobile != null) {
json[r'mobile'] = this.mobile;
} else {
json[r'mobile'] = null;
}
if (this.tablet != null) {
json[r'tablet'] = this.tablet;
} else {
json[r'tablet'] = null;
}
return json;
}
/// Returns a new [DayStatDTO] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static DayStatDTO? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key),
'Required key "DayStatDTO[$key]" is missing from JSON.');
assert(json[key] != null,
'Required key "DayStatDTO[$key]" has a null value in JSON.');
});
return true;
}());
return DayStatDTO(
date: mapValueOfType<String>(json, r'date'),
total: mapValueOfType<int>(json, r'total'),
mobile: mapValueOfType<int>(json, r'mobile'),
tablet: mapValueOfType<int>(json, r'tablet'),
);
}
return null;
}
static List<DayStatDTO> listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <DayStatDTO>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = DayStatDTO.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, DayStatDTO> mapFromJson(dynamic json) {
final map = <String, DayStatDTO>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = DayStatDTO.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of DayStatDTO-objects as value to a dart map
static Map<String, List<DayStatDTO>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<DayStatDTO>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = DayStatDTO.listFromJson(
entry.value,
growable: growable,
);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

View File

@ -0,0 +1,158 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class GameStatDTO {
/// Returns a new [GameStatDTO] instance.
GameStatDTO({
this.gameType,
this.completions,
this.avgDurationSeconds,
});
String? gameType;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? completions;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? avgDurationSeconds;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is GameStatDTO &&
other.gameType == gameType &&
other.completions == completions &&
other.avgDurationSeconds == avgDurationSeconds;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(gameType == null ? 0 : gameType!.hashCode) +
(completions == null ? 0 : completions!.hashCode) +
(avgDurationSeconds == null ? 0 : avgDurationSeconds!.hashCode);
@override
String toString() =>
'GameStatDTO[gameType=$gameType, completions=$completions, avgDurationSeconds=$avgDurationSeconds]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.gameType != null) {
json[r'gameType'] = this.gameType;
} else {
json[r'gameType'] = null;
}
if (this.completions != null) {
json[r'completions'] = this.completions;
} else {
json[r'completions'] = null;
}
if (this.avgDurationSeconds != null) {
json[r'avgDurationSeconds'] = this.avgDurationSeconds;
} else {
json[r'avgDurationSeconds'] = null;
}
return json;
}
/// Returns a new [GameStatDTO] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static GameStatDTO? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key),
'Required key "GameStatDTO[$key]" is missing from JSON.');
assert(json[key] != null,
'Required key "GameStatDTO[$key]" has a null value in JSON.');
});
return true;
}());
return GameStatDTO(
gameType: mapValueOfType<String>(json, r'gameType'),
completions: mapValueOfType<int>(json, r'completions'),
avgDurationSeconds: mapValueOfType<int>(json, r'avgDurationSeconds'),
);
}
return null;
}
static List<GameStatDTO> listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <GameStatDTO>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = GameStatDTO.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, GameStatDTO> mapFromJson(dynamic json) {
final map = <String, GameStatDTO>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = GameStatDTO.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of GameStatDTO-objects as value to a dart map
static Map<String, List<GameStatDTO>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<GameStatDTO>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = GameStatDTO.listFromJson(
entry.value,
growable: growable,
);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

View File

@ -18,7 +18,6 @@ class InstanceDTO {
this.dateCreation, this.dateCreation,
this.pinCode, this.pinCode,
this.isPushNotification, this.isPushNotification,
this.isStatistic,
this.isMobile, this.isMobile,
this.isTablet, this.isTablet,
this.isWeb, this.isWeb,
@ -60,7 +59,6 @@ class InstanceDTO {
/// source code must fall back to having a nullable type. /// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note. /// Consider adding a "default:" property in the specification file to hide this note.
/// ///
bool? isStatistic;
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// Please note: This property should have been non-nullable! Since the specification file
@ -129,7 +127,6 @@ class InstanceDTO {
other.dateCreation == dateCreation && other.dateCreation == dateCreation &&
other.pinCode == pinCode && other.pinCode == pinCode &&
other.isPushNotification == isPushNotification && other.isPushNotification == isPushNotification &&
other.isStatistic == isStatistic &&
other.isMobile == isMobile && other.isMobile == isMobile &&
other.isTablet == isTablet && other.isTablet == isTablet &&
other.isWeb == isWeb && other.isWeb == isWeb &&
@ -155,7 +152,6 @@ class InstanceDTO {
(dateCreation == null ? 0 : dateCreation!.hashCode) + (dateCreation == null ? 0 : dateCreation!.hashCode) +
(pinCode == null ? 0 : pinCode!.hashCode) + (pinCode == null ? 0 : pinCode!.hashCode) +
(isPushNotification == null ? 0 : isPushNotification!.hashCode) + (isPushNotification == null ? 0 : isPushNotification!.hashCode) +
(isStatistic == null ? 0 : isStatistic!.hashCode) +
(isMobile == null ? 0 : isMobile!.hashCode) + (isMobile == null ? 0 : isMobile!.hashCode) +
(isTablet == null ? 0 : isTablet!.hashCode) + (isTablet == null ? 0 : isTablet!.hashCode) +
(isWeb == null ? 0 : isWeb!.hashCode) + (isWeb == null ? 0 : isWeb!.hashCode) +
@ -169,7 +165,7 @@ class InstanceDTO {
@override @override
String toString() => String toString() =>
'InstanceDTO[id=$id, name=$name, dateCreation=$dateCreation, pinCode=$pinCode, isPushNotification=$isPushNotification, isStatistic=$isStatistic, isMobile=$isMobile, isTablet=$isTablet, isWeb=$isWeb, isVR=$isVR, isAssistant=$isAssistant, subscriptionPlanId=$subscriptionPlanId, subscriptionPlan=$subscriptionPlan, aiRequestsThisMonth=$aiRequestsThisMonth, aiUsageMonthKey=$aiUsageMonthKey, applicationInstanceDTOs=$applicationInstanceDTOs]'; 'InstanceDTO[id=$id, name=$name, dateCreation=$dateCreation, pinCode=$pinCode, isPushNotification=$isPushNotification, isMobile=$isMobile, isTablet=$isTablet, isWeb=$isWeb, isVR=$isVR, isAssistant=$isAssistant, subscriptionPlanId=$subscriptionPlanId, subscriptionPlan=$subscriptionPlan, aiRequestsThisMonth=$aiRequestsThisMonth, aiUsageMonthKey=$aiUsageMonthKey, applicationInstanceDTOs=$applicationInstanceDTOs]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -198,11 +194,6 @@ class InstanceDTO {
} else { } else {
json[r'isPushNotification'] = null; json[r'isPushNotification'] = null;
} }
if (this.isStatistic != null) {
json[r'isStatistic'] = this.isStatistic;
} else {
json[r'isStatistic'] = null;
}
if (this.isMobile != null) { if (this.isMobile != null) {
json[r'isMobile'] = this.isMobile; json[r'isMobile'] = this.isMobile;
} else { } else {
@ -317,7 +308,6 @@ class InstanceDTO {
dateCreation: mapDateTime(json, r'dateCreation', r''), dateCreation: mapDateTime(json, r'dateCreation', r''),
pinCode: mapValueOfType<String>(json, r'pinCode'), pinCode: mapValueOfType<String>(json, r'pinCode'),
isPushNotification: mapValueOfType<bool>(json, r'isPushNotification'), isPushNotification: mapValueOfType<bool>(json, r'isPushNotification'),
isStatistic: mapValueOfType<bool>(json, r'isStatistic'),
isMobile: mapValueOfType<bool>(json, r'isMobile'), isMobile: mapValueOfType<bool>(json, r'isMobile'),
isTablet: mapValueOfType<bool>(json, r'isTablet'), isTablet: mapValueOfType<bool>(json, r'isTablet'),
isWeb: mapValueOfType<bool>(json, r'isWeb'), isWeb: mapValueOfType<bool>(json, r'isWeb'),

View File

@ -0,0 +1,169 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class PoiStatDTO {
/// Returns a new [PoiStatDTO] instance.
PoiStatDTO({
this.geoPointId,
this.title,
this.taps,
this.sectionId,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? geoPointId;
String? title;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? taps;
String? sectionId;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PoiStatDTO &&
other.geoPointId == geoPointId &&
other.title == title &&
other.taps == taps &&
other.sectionId == sectionId;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(geoPointId == null ? 0 : geoPointId!.hashCode) +
(title == null ? 0 : title!.hashCode) +
(taps == null ? 0 : taps!.hashCode) +
(sectionId == null ? 0 : sectionId!.hashCode);
@override
String toString() =>
'PoiStatDTO[geoPointId=$geoPointId, title=$title, taps=$taps, sectionId=$sectionId]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.geoPointId != null) {
json[r'geoPointId'] = this.geoPointId;
} else {
json[r'geoPointId'] = null;
}
if (this.title != null) {
json[r'title'] = this.title;
} else {
json[r'title'] = null;
}
if (this.taps != null) {
json[r'taps'] = this.taps;
} else {
json[r'taps'] = null;
}
if (this.sectionId != null) {
json[r'sectionId'] = this.sectionId;
} else {
json[r'sectionId'] = null;
}
return json;
}
/// Returns a new [PoiStatDTO] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static PoiStatDTO? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key),
'Required key "PoiStatDTO[$key]" is missing from JSON.');
assert(json[key] != null,
'Required key "PoiStatDTO[$key]" has a null value in JSON.');
});
return true;
}());
return PoiStatDTO(
geoPointId: mapValueOfType<int>(json, r'geoPointId'),
title: mapValueOfType<String>(json, r'title'),
taps: mapValueOfType<int>(json, r'taps'),
sectionId: mapValueOfType<String>(json, r'sectionId'),
);
}
return null;
}
static List<PoiStatDTO> listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <PoiStatDTO>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = PoiStatDTO.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, PoiStatDTO> mapFromJson(dynamic json) {
final map = <String, PoiStatDTO>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PoiStatDTO.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of PoiStatDTO-objects as value to a dart map
static Map<String, List<PoiStatDTO>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<PoiStatDTO>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = PoiStatDTO.listFromJson(
entry.value,
growable: growable,
);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

View File

@ -0,0 +1,186 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class QuizStatDTO {
/// Returns a new [QuizStatDTO] instance.
QuizStatDTO({
this.sectionId,
this.sectionTitle,
this.avgScore,
this.totalQuestions,
this.completions,
});
String? sectionId;
String? sectionTitle;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
double? avgScore;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? totalQuestions;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? completions;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is QuizStatDTO &&
other.sectionId == sectionId &&
other.sectionTitle == sectionTitle &&
other.avgScore == avgScore &&
other.totalQuestions == totalQuestions &&
other.completions == completions;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(sectionId == null ? 0 : sectionId!.hashCode) +
(sectionTitle == null ? 0 : sectionTitle!.hashCode) +
(avgScore == null ? 0 : avgScore!.hashCode) +
(totalQuestions == null ? 0 : totalQuestions!.hashCode) +
(completions == null ? 0 : completions!.hashCode);
@override
String toString() =>
'QuizStatDTO[sectionId=$sectionId, sectionTitle=$sectionTitle, avgScore=$avgScore, totalQuestions=$totalQuestions, completions=$completions]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.sectionId != null) {
json[r'sectionId'] = this.sectionId;
} else {
json[r'sectionId'] = null;
}
if (this.sectionTitle != null) {
json[r'sectionTitle'] = this.sectionTitle;
} else {
json[r'sectionTitle'] = null;
}
if (this.avgScore != null) {
json[r'avgScore'] = this.avgScore;
} else {
json[r'avgScore'] = null;
}
if (this.totalQuestions != null) {
json[r'totalQuestions'] = this.totalQuestions;
} else {
json[r'totalQuestions'] = null;
}
if (this.completions != null) {
json[r'completions'] = this.completions;
} else {
json[r'completions'] = null;
}
return json;
}
/// Returns a new [QuizStatDTO] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static QuizStatDTO? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key),
'Required key "QuizStatDTO[$key]" is missing from JSON.');
assert(json[key] != null,
'Required key "QuizStatDTO[$key]" has a null value in JSON.');
});
return true;
}());
return QuizStatDTO(
sectionId: mapValueOfType<String>(json, r'sectionId'),
sectionTitle: mapValueOfType<String>(json, r'sectionTitle'),
avgScore: mapValueOfType<double>(json, r'avgScore'),
totalQuestions: mapValueOfType<int>(json, r'totalQuestions'),
completions: mapValueOfType<int>(json, r'completions'),
);
}
return null;
}
static List<QuizStatDTO> listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <QuizStatDTO>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = QuizStatDTO.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, QuizStatDTO> mapFromJson(dynamic json) {
final map = <String, QuizStatDTO>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = QuizStatDTO.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of QuizStatDTO-objects as value to a dart map
static Map<String, List<QuizStatDTO>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<QuizStatDTO>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = QuizStatDTO.listFromJson(
entry.value,
growable: growable,
);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

View File

@ -0,0 +1,169 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class SectionStatDTO {
/// Returns a new [SectionStatDTO] instance.
SectionStatDTO({
this.sectionId,
this.sectionTitle,
this.views,
this.avgDurationSeconds,
});
String? sectionId;
String? sectionTitle;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? views;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? avgDurationSeconds;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is SectionStatDTO &&
other.sectionId == sectionId &&
other.sectionTitle == sectionTitle &&
other.views == views &&
other.avgDurationSeconds == avgDurationSeconds;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(sectionId == null ? 0 : sectionId!.hashCode) +
(sectionTitle == null ? 0 : sectionTitle!.hashCode) +
(views == null ? 0 : views!.hashCode) +
(avgDurationSeconds == null ? 0 : avgDurationSeconds!.hashCode);
@override
String toString() =>
'SectionStatDTO[sectionId=$sectionId, sectionTitle=$sectionTitle, views=$views, avgDurationSeconds=$avgDurationSeconds]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.sectionId != null) {
json[r'sectionId'] = this.sectionId;
} else {
json[r'sectionId'] = null;
}
if (this.sectionTitle != null) {
json[r'sectionTitle'] = this.sectionTitle;
} else {
json[r'sectionTitle'] = null;
}
if (this.views != null) {
json[r'views'] = this.views;
} else {
json[r'views'] = null;
}
if (this.avgDurationSeconds != null) {
json[r'avgDurationSeconds'] = this.avgDurationSeconds;
} else {
json[r'avgDurationSeconds'] = null;
}
return json;
}
/// Returns a new [SectionStatDTO] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static SectionStatDTO? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key),
'Required key "SectionStatDTO[$key]" is missing from JSON.');
assert(json[key] != null,
'Required key "SectionStatDTO[$key]" has a null value in JSON.');
});
return true;
}());
return SectionStatDTO(
sectionId: mapValueOfType<String>(json, r'sectionId'),
sectionTitle: mapValueOfType<String>(json, r'sectionTitle'),
views: mapValueOfType<int>(json, r'views'),
avgDurationSeconds: mapValueOfType<int>(json, r'avgDurationSeconds'),
);
}
return null;
}
static List<SectionStatDTO> listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <SectionStatDTO>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = SectionStatDTO.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, SectionStatDTO> mapFromJson(dynamic json) {
final map = <String, SectionStatDTO>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = SectionStatDTO.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of SectionStatDTO-objects as value to a dart map
static Map<String, List<SectionStatDTO>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<SectionStatDTO>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = SectionStatDTO.listFromJson(
entry.value,
growable: growable,
);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

View File

@ -813,6 +813,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.2"
iconsax_flutter:
dependency: transitive
description:
name: iconsax_flutter
sha256: d14b4cec8586025ac15276bdd40f6eea308cb85748135965bb6255f14beb2564
url: "https://pub.dev"
source: hosted
version: "1.0.1"
image: image:
dependency: transitive dependency: transitive
description: description:
@ -1164,6 +1172,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.1" version: "2.2.1"
pausable_timer:
dependency: transitive
description:
name: pausable_timer
sha256: "6ef1a95441ec3439de6fb63f39a011b67e693198e7dae14e20675c3c00e86074"
url: "https://pub.dev"
source: hosted
version: "3.1.0+3"
pdf: pdf:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1385,14 +1401,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.0" version: "1.10.0"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
sqflite: sqflite:
dependency: transitive dependency: transitive
description: description:
@ -1481,6 +1489,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
toastification:
dependency: "direct main"
description:
name: toastification
sha256: "4d97fbfa463dfe83691044cba9f37cb185a79bb9205cfecb655fa1f6be126a13"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -1565,10 +1581,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.4.0" version: "4.5.3"
vector_graphics: vector_graphics:
dependency: transitive dependency: transitive
description: description:

View File

@ -80,6 +80,7 @@ dependencies:
firebase_storage: ^12.0.1 firebase_storage: ^12.0.1
firebase_core: ^3.1.0 firebase_core: ^3.1.0
fl_chart: ^0.69.0 fl_chart: ^0.69.0
toastification: ^2.3.0
#another_flushbar: ^1.12.30 #another_flushbar: ^1.12.30
dependency_overrides: dependency_overrides: