From 4501aaac9c017bf409d9c7546ed9b9d8926391e3 Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Wed, 20 Aug 2025 18:15:00 +0200 Subject: [PATCH] clean code (main screen) + support routes navigation (not yet detail) --- lib/Screens/Main/components/background.dart | 47 --- lib/Screens/Main/components/body.dart | 282 ---------------- lib/Screens/Main/main_screen.dart | 339 ++++++++++++++++---- lib/Screens/login_screen.dart | 26 +- lib/main.dart | 189 +++++++++-- pubspec.lock | 76 +++-- pubspec.yaml | 3 +- 7 files changed, 520 insertions(+), 442 deletions(-) delete mode 100644 lib/Screens/Main/components/background.dart delete mode 100644 lib/Screens/Main/components/body.dart diff --git a/lib/Screens/Main/components/background.dart b/lib/Screens/Main/components/background.dart deleted file mode 100644 index 034aad3..0000000 --- a/lib/Screens/Main/components/background.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:manager_app/constants.dart'; - -class Background extends StatelessWidget { - final Widget child; - const Background({ - Key? key, - required this.child, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - Size size = MediaQuery.of(context).size; - //final notchInset = MediaQuery.of(context).padding; - return Container( - width: double.infinity, - height: size.height, - color: kTextLightColor, - child: Stack( - alignment: Alignment.center, - children: [ - /*Positioned( - top: - 15, - left: -1, - child: SvgPicture.asset( - 'assets/images/hungry/top_bar2.svg', - width: size.width * 1.01, - ) - ),*/ - /*Positioned.fill( - child: Padding( - padding: EdgeInsets.only(top: (size.height - notchInset.top) * 0.14, left: size.width * 0.025), - child: Align( - alignment: Alignment.topLeft, - child: Text( - "Étape 1", - style: kSubTitleTextStyle, - ), - ), - ), - ),*/ - child, - ], - ), - ); - } -} \ No newline at end of file diff --git a/lib/Screens/Main/components/body.dart b/lib/Screens/Main/components/body.dart deleted file mode 100644 index 024b4ab..0000000 --- a/lib/Screens/Main/components/body.dart +++ /dev/null @@ -1,282 +0,0 @@ -import 'dart:html'; - -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:manager_app/Models/managerContext.dart'; -import 'package:manager_app/Models/menu.dart'; -import 'package:manager_app/Models/menuSection.dart'; -import 'package:manager_app/Screens/Configurations/configurations_screen.dart'; -import 'package:manager_app/Screens/Kiosk_devices/kiosk_screen.dart'; -import 'package:manager_app/Screens/Main/components/background.dart'; -import 'package:manager_app/Screens/Resources/resources_screen.dart'; -import 'package:manager_app/Screens/Applications/app_configuration_link_screen.dart'; -import 'package:manager_app/Screens/login_screen.dart'; -import 'package:manager_app/app_context.dart'; -import 'package:manager_app/constants.dart'; -import 'package:manager_app/main.dart'; -import 'package:manager_api_new/api.dart'; -import 'package:provider/provider.dart'; - -class Body extends StatefulWidget { - final InstanceDTO instance; - Body({Key? key, required this.instance}) : super(key: key); - - @override - _BodyState createState() => _BodyState(); -} - -class _BodyState extends State { - late MenuSection devices; - late MenuSection configurations; - late MenuSection resources; - - Menu menu = Menu(title: "MyInfoMate"); - Widget? selectedElement = null; - - final ValueNotifier currentPosition = ValueNotifier(null); - - @override - void initState() { - super.initState(); - devices = MenuSection(name: "Applications", type: "devices", menuId: 0, subMenu: []); - if (widget.instance.isMobile!) devices.subMenu.add(MenuSection(name: "Mobile", type: "mobile", menuId: 1, subMenu: [])); - if (widget.instance.isTablet!) devices.subMenu.add(MenuSection(name: "Kiosk", type: "kiosk", menuId: 2, subMenu: [])); - if (widget.instance.isWeb!) devices.subMenu.add(MenuSection(name: "Web", type: "web", menuId: 3, subMenu: [])); - if (widget.instance.isVR!) devices.subMenu.add(MenuSection(name: "VR", type: "vr", menuId: 4, subMenu: [])); - - configurations = MenuSection(name: "Configurations", type: "configurations", menuId: 5, subMenu: []); - resources = MenuSection(name: "Ressources", type: "resources", menuId: 6, subMenu: []); - - menu.sections = [devices, configurations, resources]; - - if(currentPosition.value == null) { - if (widget.instance.isMobile!) { - currentPosition.value = 1; - } else if (widget.instance.isTablet!) { - currentPosition.value = 2; - } else if (widget.instance.isWeb!) { - currentPosition.value = 3; - } else { - currentPosition.value = 4; - } - } else { - //currentPosition = managerAppContext.currentPositionMenu!; - } - - selectedElement = initElementToShow(currentPosition.value!, menu, widget.instance); - } - - Widget buildMenu(BuildContext context, AppContext appContext, ManagerAppContext managerAppContext, bool isDrawer) { - return Container( - width: isDrawer ? null : 250, // fixed width on sidebar, null on drawer for full width - color: kSecond, - child: Column( - children: [ - DrawerHeader( - child: Text( - menu.title, - style: TextStyle(color: kPrimaryColor, fontSize: 30, fontWeight: FontWeight.w400, fontFamily: "Helvetica"), - ), - ), - Expanded( - child: ListView( - padding: EdgeInsets.zero, - children: menu.sections!.map((section) { - if (section.subMenu.isEmpty) { - return ListTile( - title: Text(section.name, style: TextStyle(color: section.menuId == currentPosition.value ? kPrimaryColor : kBodyTextColor, fontSize: 20)), - selected: currentPosition == section.menuId, - onTap: () { - currentPosition.value = section.menuId; - if (isDrawer) Navigator.of(context).pop(); // Close drawer on mobile - }, - ); - } else { - return ExpansionTile( - iconColor: currentPosition.value! >= 1 && currentPosition.value! <= 4 ? kPrimaryColor : kBodyTextColor, - collapsedIconColor: currentPosition.value! >= 1 && currentPosition.value! <= 4 ? kPrimaryColor : kBodyTextColor, - title: Text(section.name, style: TextStyle(color: currentPosition.value! >= 1 && currentPosition.value! <= 4 ? kPrimaryColor : kBodyTextColor, fontSize: 20)), - children: section.subMenu.map((subSection) { - return ListTile( - title: Padding( - padding: const EdgeInsets.only(left: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - subSection.type == "mobile" ? Icon(Icons.phone_iphone, color: currentPosition.value == subSection.menuId ? kPrimaryColor : kBodyTextColor, size: 20) : - subSection.type == "kiosk" ? Icon(Icons.tablet_rounded, color: currentPosition.value == subSection.menuId ? kPrimaryColor : kBodyTextColor, size: 20) : - subSection.type == "web" ? Icon(Icons.public_outlined, color: currentPosition.value == subSection.menuId ? kPrimaryColor : kBodyTextColor, size: 20) : - subSection.type == "vr" ? Icon(Icons.panorama_photosphere, color: currentPosition.value == subSection.menuId ? kPrimaryColor : kBodyTextColor, size: 20) : SizedBox(), - Padding( - padding: const EdgeInsets.all(8.0), - child: Text(subSection.name, style: TextStyle(color: subSection.menuId == currentPosition.value! ? kPrimaryColor : kBodyTextColor, fontSize: 18)), - ) - ], - ), - ), - selected: currentPosition.value == subSection.menuId, - onTap: () { - currentPosition.value = subSection.menuId; - if (isDrawer) Navigator.of(context).pop(); - }, - ); - }).toList(), - ); - } - }).toList(), - ), - ), - // Footer: Email + Logout button - Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - AutoSizeText( - (appContext.getContext() as ManagerAppContext).email ?? "", - style: TextStyle(color: kBodyTextColor, fontSize: 16, fontWeight: FontWeight.w300, fontFamily: "Helvetica"), - maxLines: 1, - ), - IconButton( - icon: Icon(Icons.logout, color: kPrimaryColor), - onPressed: () async { - var session = await loadJsonSessionFile(); - setState(() { - Storage localStorage = window.localStorage; - localStorage.clear(); - ManagerAppContext managerAppContext = appContext.getContext(); - managerAppContext.accessToken = null; - appContext.setContext(managerAppContext); - Navigator.pushNamedAndRemoveUntil( - context, - '/login', - (Route route) => false, - ); - /*Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute(builder: (context) => LoginScreen(session: session)), - (route) => false, - );*/ - }); - }, - ) - ], - ), - ), - ], - ), - ); - } - - - @override - Widget build(BuildContext context) { - final appContext = Provider.of(context); - ManagerAppContext managerAppContext = appContext.getContext(); - - Size size = MediaQuery.of(context).size; - bool isMobile = size.width < 700; - - return Scaffold( - appBar: isMobile - ? AppBar( - title: Text(menu.title, style: TextStyle(color: kPrimaryColor)), - backgroundColor: kSecond, - leading: Builder( - builder: (context) => IconButton( - icon: Icon(Icons.menu, color: kPrimaryColor), - onPressed: () => Scaffold.of(context).openDrawer(), - ), - ), - ) - : null, - drawer: isMobile ? ValueListenableBuilder( - valueListenable: currentPosition, - builder: (context, value, _) { - return Drawer(child: buildMenu(context, appContext, managerAppContext, true)); - } - ) : null, - body: Row( - children: [ - if (!isMobile) - ValueListenableBuilder( - valueListenable: currentPosition, - builder: (context, value, _) { - return buildMenu(context, appContext, managerAppContext, false); - } - ), - Expanded( - child: ValueListenableBuilder( - valueListenable: currentPosition, - builder: (context, value, _) { - selectedElement = initElementToShow(currentPosition.value!, menu, widget.instance); - return Padding( - padding: const EdgeInsets.all(8.0), - child: selectedElement, - ); - } - ), - ), - ], - ), - ); - } -} - - initElementToShow(int currentPosition, Menu menu, InstanceDTO instanceDTO) { - MenuSection? elementToShow = menu.sections!.firstWhereOrNull((s) => s.menuId == currentPosition); - - if(elementToShow == null) { - elementToShow = menu.sections![0].subMenu.where((s) => s.menuId == currentPosition).first; - } - - switch (elementToShow.type) { - case 'mobile' : - var applicationInstanceMobile = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.Mobile); - return Padding( - padding: const EdgeInsets.all(8.0), - child: AppConfigurationLinkScreen(applicationInstanceDTO: applicationInstanceMobile) - ); - case 'kiosk' : - var applicationInstanceTablet = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.Tablet); - return Padding( - padding: const EdgeInsets.all(8.0), - child: KioskScreen(applicationInstanceDTO: applicationInstanceTablet) - ); - case 'web' : - var applicationInstanceWeb = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.Web); - return Padding( - padding: const EdgeInsets.all(8.0), - child: Text("TODO web") - ); - case 'vr' : - var applicationInstanceVR = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.VR); - return Padding( - padding: const EdgeInsets.all(8.0), - child: Text("TODO vr") - ); - case 'configurations' : - return Padding( - padding: const EdgeInsets.all(8.0), - child: ConfigurationsScreen() - ); - case 'resources' : - return Padding( - padding: const EdgeInsets.all(8.0), - child: ResourcesScreen( - resourceTypes: [ - ResourceType.Audio, - ResourceType.Image, - ResourceType.ImageUrl, - ResourceType.Video, - ResourceType.VideoUrl, - ResourceType.Pdf, - ResourceType.Json, - ResourceType.JsonUrl - ] - ) - ); - default: - return Text('Hellow default'); - } -} \ No newline at end of file diff --git a/lib/Screens/Main/main_screen.dart b/lib/Screens/Main/main_screen.dart index 45c5557..d6e2d0c 100644 --- a/lib/Screens/Main/main_screen.dart +++ b/lib/Screens/Main/main_screen.dart @@ -1,88 +1,311 @@ +import 'dart:html'; + +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:manager_api_new/api.dart'; -import 'package:manager_app/Components/common_loader.dart'; +import 'package:go_router/go_router.dart'; import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/Models/menu.dart'; import 'package:manager_app/Models/menuSection.dart'; -import 'package:manager_app/Screens/Main/components/body.dart'; +import 'package:manager_app/Screens/Configurations/configurations_screen.dart'; +import 'package:manager_app/Screens/Kiosk_devices/kiosk_screen.dart'; +import 'package:manager_app/Screens/Resources/resources_screen.dart'; +import 'package:manager_app/Screens/Applications/app_configuration_link_screen.dart'; import 'package:manager_app/app_context.dart'; -import 'package:manager_app/client.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_app/main.dart'; +import 'package:manager_api_new/api.dart'; import 'package:provider/provider.dart'; -import 'package:responsive_framework/responsive_framework.dart'; class MainScreen extends StatefulWidget { - MainScreen({Key? key}) : super(key: key); + final InstanceDTO instance; + final String? view; + MainScreen({Key? key, required this.instance, required this.view}) : super(key: key); @override _MainScreenState createState() => _MainScreenState(); } class _MainScreenState extends State { + late MenuSection devices; + late MenuSection configurations; + late MenuSection resources; + + Menu menu = Menu(title: "MyInfoMate"); + Widget? selectedElement = null; + + final ValueNotifier currentPosition = ValueNotifier(null); + @override - Widget build(BuildContext context) { - final GlobalKey<_MainScreenState> key = GlobalKey(); - final appContext = Provider.of(context); - Size size = MediaQuery.of(context).size; + void initState() { + super.initState(); + devices = MenuSection(name: "Applications", type: "devices", menuId: 0, subMenu: []); + if (widget.instance.isMobile!) devices.subMenu.add(MenuSection(name: "Mobile", type: "mobile", menuId: 1, subMenu: [])); + if (widget.instance.isTablet!) devices.subMenu.add(MenuSection(name: "Kiosk", type: "kiosk", menuId: 2, subMenu: [])); + if (widget.instance.isWeb!) devices.subMenu.add(MenuSection(name: "Web", type: "web", menuId: 3, subMenu: [])); + if (widget.instance.isVR!) devices.subMenu.add(MenuSection(name: "VR", type: "vr", menuId: 4, subMenu: [])); - //var isFortSt = managerAppContext.instanceId == "633ee379d9405f32f166f047"; + configurations = MenuSection(name: "Configurations", type: "configurations", menuId: 5, subMenu: []); + resources = MenuSection(name: "Ressources", type: "resources", menuId: 6, subMenu: []); - return FutureBuilder( - future: getInstanceInfo(appContext), - builder: (context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - if (snapshot.data != null) { - var instanceDTO = snapshot.data; - return Scaffold( - key: key, - body: Body(instance: instanceDTO!), - ); - } else { - return Text("No data"); - } - } else if (snapshot.connectionState == ConnectionState.none) { - return Text("No data"); - } else { - return Center( - child: Container( - height: size.height * 0.1, - child: CommonLoader() + menu.sections = [devices, configurations, resources]; + + if(currentPosition.value == null) { + if (widget.instance.isMobile!) { + currentPosition.value = 1; + } else if (widget.instance.isTablet!) { + currentPosition.value = 2; + } else if (widget.instance.isWeb!) { + currentPosition.value = 3; + } else { + currentPosition.value = 4; + } + } else { + //currentPosition = managerAppContext.currentPositionMenu!; + } + + selectedElement = initElementToShow(context, widget.view, currentPosition.value!, menu, widget.instance); + } + + Widget buildMenu(BuildContext context, AppContext appContext, ManagerAppContext managerAppContext, bool isDrawer) { + return Container( + width: isDrawer ? null : 250, // fixed width on sidebar, null on drawer for full width + color: kSecond, + child: Column( + children: [ + DrawerHeader( + child: Text( + menu.title, + style: TextStyle(color: kPrimaryColor, fontSize: 30, fontWeight: FontWeight.w400, fontFamily: "Helvetica"), + ), + ), + Expanded( + child: ListView( + padding: EdgeInsets.zero, + children: menu.sections!.map((section) { + final router = GoRouter.of(context); + final routeMatchList = router.routerDelegate.currentConfiguration; + var currentPath = routeMatchList.isNotEmpty ? routeMatchList.matches.first.matchedLocation : null; + + if (section.subMenu.isEmpty) { + return ListTile( + title: Text(section.name, style: TextStyle(color: currentPath!.contains(section.type) ? kPrimaryColor : kBodyTextColor, fontSize: 20)), + selected: currentPosition == section.menuId, + onTap: () { + //currentPosition.value = section.menuId; + context.go('/main/${section.type}'); + if (isDrawer) Navigator.of(context).pop(); // Close drawer on mobile + }, + ); + } else { + return ExpansionTile( + iconColor: currentPath!.contains("mobile") || currentPath.contains("kiosk") || currentPath.contains("web") || currentPath.contains("vr") ? kPrimaryColor : kBodyTextColor, + collapsedIconColor: currentPath.contains("mobile") || currentPath.contains("kiosk") || currentPath.contains("web") || currentPath.contains("vr") ? kPrimaryColor : kBodyTextColor, + title: Text(section.name, style: TextStyle(color: currentPath.contains("mobile") || currentPath.contains("kiosk") || currentPath.contains("web") || currentPath.contains("vr") ? kPrimaryColor : kBodyTextColor, fontSize: 20)), + children: section.subMenu.map((subSection) { + return ListTile( + title: Padding( + padding: const EdgeInsets.only(left: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + subSection.type == "mobile" ? Icon(Icons.phone_iphone, color: currentPath.contains(subSection.type) ? kPrimaryColor : kBodyTextColor, size: 20) : + subSection.type == "kiosk" ? Icon(Icons.tablet_rounded, color: currentPath.contains(subSection.type) ? kPrimaryColor : kBodyTextColor, size: 20) : + subSection.type == "web" ? Icon(Icons.public_outlined, color: currentPath.contains(subSection.type) ? kPrimaryColor : kBodyTextColor, size: 20) : + subSection.type == "vr" ? Icon(Icons.panorama_photosphere, color: currentPath.contains(subSection.type)? kPrimaryColor : kBodyTextColor, size: 20) : SizedBox(), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(subSection.name, style: TextStyle(color: currentPath.contains(subSection.type) ? kPrimaryColor : kBodyTextColor, fontSize: 18)), + ) + ], + ), + ), + selected: currentPosition.value == subSection.menuId, + onTap: () { + + + if(currentPath != null && currentPath.contains(subSection.type)) { + // DO NOTHING, we are already display the correct interface + } else { + context.go('/main/${subSection.type}'); + } + if (isDrawer) Navigator.of(context).pop(); + }, + ); + }).toList(), + ); + } + }).toList(), + ), + ), + // Footer: Email + Logout button + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + AutoSizeText( + (appContext.getContext() as ManagerAppContext).email ?? "", + style: TextStyle(color: kBodyTextColor, fontSize: 16, fontWeight: FontWeight.w300, fontFamily: "Helvetica"), + maxLines: 1, + ), + IconButton( + icon: Icon(Icons.logout, color: kPrimaryColor), + onPressed: () async { + var session = await loadJsonSessionFile(); + setState(() { + Storage localStorage = window.localStorage; + localStorage.clear(); + ManagerAppContext managerAppContext = appContext.getContext(); + managerAppContext.accessToken = null; + managerAppContext.instanceId = null; + managerAppContext.instanceDTO = null; + appContext.setContext(managerAppContext); + + context.go('/login'); + }); + }, ) - ); - } - } + ], + ), + ), + ], + ), ); } - Future getInstanceInfo(AppContext appContext) async { - var session = await loadJsonSessionFile(); + @override + Widget build(BuildContext context) { + final appContext = Provider.of(context); + ManagerAppContext managerAppContext = appContext.getContext(); - try { - ManagerAppContext managerAppContext = appContext.getContext() as ManagerAppContext; - managerAppContext.instanceId = managerAppContext.instanceId ?? session.instanceId; - managerAppContext.host = managerAppContext.host ?? session.host; - managerAppContext.accessToken = managerAppContext.accessToken ?? session.token; - managerAppContext.email = managerAppContext.email ?? session.email; + Size size = MediaQuery.of(context).size; + bool isMobile = size.width < 700; - if(managerAppContext.clientAPI == null) { - managerAppContext.clientAPI = Client(session.host!); - managerAppContext.clientAPI!.apiApi!.addDefaultHeader('authorization', 'Bearer '+ managerAppContext.accessToken!); - } - - InstanceDTO? instance = await managerAppContext.clientAPI!.instanceApi!.instanceGetDetail(managerAppContext.instanceId!); - managerAppContext.instanceDTO = instance; - return instance; - } catch(e) { - Navigator.pushNamedAndRemoveUntil( - context, - '/login', - (Route route) => false, - ); - return null; - } + return Scaffold( + appBar: isMobile + ? AppBar( + title: Text(menu.title, style: TextStyle(color: kPrimaryColor)), + backgroundColor: kSecond, + leading: Builder( + builder: (context) => IconButton( + icon: Icon(Icons.menu, color: kPrimaryColor), + onPressed: () => Scaffold.of(context).openDrawer(), + ), + ), + ) + : null, + drawer: isMobile ? ValueListenableBuilder( + valueListenable: currentPosition, + builder: (context, value, _) { + return Drawer(child: buildMenu(context, appContext, managerAppContext, true)); + } + ) : null, + body: Row( + children: [ + if (!isMobile) + ValueListenableBuilder( + valueListenable: currentPosition, + builder: (context, value, _) { + return buildMenu(context, appContext, managerAppContext, false); + } + ), + Expanded( + child: ValueListenableBuilder( + valueListenable: currentPosition, + builder: (context, value, _) { + selectedElement = initElementToShow(context, widget.view, currentPosition.value!, menu, widget.instance); + return Padding( + padding: const EdgeInsets.all(8.0), + child: selectedElement, + ); + } + ), + ), + ], + ), + ); } } + initElementToShow(BuildContext context, String? view, int currentPosition, Menu menu, InstanceDTO instanceDTO) { + if(view != null) { + switch (view) { + case "mobile": + currentPosition = 1; + break; + case "kiosk": + currentPosition = 2; + break; + case "web": + currentPosition = 3; + break; + case "vr": + currentPosition = 4; + break; + case "configurations": + currentPosition = 5; + break; + case "resources": + currentPosition = 6; + break; + } + } + + MenuSection? elementToShow = menu.sections!.firstWhereOrNull((s) => s.menuId == currentPosition); + + if(elementToShow == null) { + elementToShow = menu.sections![0].subMenu.where((s) => s.menuId == currentPosition).first; + } + + switch (elementToShow.type) { + case 'mobile' : + var applicationInstanceMobile = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.Mobile); + return Padding( + padding: const EdgeInsets.all(8.0), + child: AppConfigurationLinkScreen(applicationInstanceDTO: applicationInstanceMobile) + ); + case 'kiosk' : + var applicationInstanceTablet = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.Tablet); + return Padding( + padding: const EdgeInsets.all(8.0), + child: KioskScreen(applicationInstanceDTO: applicationInstanceTablet) + ); + case 'web' : + var applicationInstanceWeb = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.Web); + return Padding( + padding: const EdgeInsets.all(8.0), + child: Text("TODO web") + ); + case 'vr' : + var applicationInstanceVR = instanceDTO.applicationInstanceDTOs!.firstWhere((ai) => ai.appType == AppType.VR); + return Padding( + padding: const EdgeInsets.all(8.0), + child: Text("TODO vr") + ); + case 'configurations' : + return Padding( + padding: const EdgeInsets.all(8.0), + child: ConfigurationsScreen() + ); + case 'resources' : + return Padding( + padding: const EdgeInsets.all(8.0), + child: ResourcesScreen( + resourceTypes: [ + ResourceType.Audio, + ResourceType.Image, + ResourceType.ImageUrl, + ResourceType.Video, + ResourceType.VideoUrl, + ResourceType.Pdf, + ResourceType.Json, + ResourceType.JsonUrl + ] + ) + ); + default: + return Text('Hellow default'); + } +} \ No newline at end of file diff --git a/lib/Screens/login_screen.dart b/lib/Screens/login_screen.dart index 4a1ddf8..be55531 100644 --- a/lib/Screens/login_screen.dart +++ b/lib/Screens/login_screen.dart @@ -3,6 +3,7 @@ import 'dart:html'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:go_router/go_router.dart'; import 'package:manager_app/Components/common_loader.dart'; import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/Components/rounded_button.dart'; @@ -122,19 +123,40 @@ class _LoginScreenState extends State { managerAppContext.accessToken = accessToken; managerAppContext.clientAPI = clientAPI; setAccessToken(accessToken); + + InstanceDTO? instance = await managerAppContext.clientAPI!.instanceApi!.instanceGetDetail(managerAppContext.instanceId!); + managerAppContext.instanceDTO = instance; + FileHelper().writeSession(new Session(rememberMe: true, instanceId: instanceId, host: host, token: accessToken, password: password, email: email)); appContext.setContext(managerAppContext); + if(instance!.isMobile!) { + context.go('/main/mobile'); + } else { + if(instance.isTablet!) { + context.go('/main/tablet'); + } else { + if(instance.isWeb!) { + context.go('/main/web'); + } else { + if(instance.isVR!) { + context.go('/main/vr'); + } + } + } + } + if(fromClick) { setState(() { isLoading = false; }); } - Navigator.pushNamedAndRemoveUntil( + + /*Navigator.pushNamedAndRemoveUntil( context, '/main', // <- correspond à ta route définie (Route route) => false, - ); + );*/ /*Navigator.pushAndRemoveUntil( context, MaterialPageRoute( diff --git a/lib/main.dart b/lib/main.dart index 6ee3c45..b97a331 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,39 +1,34 @@ import 'dart:ui'; import 'package:firebase_core/firebase_core.dart'; +import 'package:go_router/go_router.dart'; +import 'package:manager_api_new/api.dart'; import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/Screens/Main/main_screen.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:responsive_framework/responsive_framework.dart'; +import 'Components/common_loader.dart'; import 'Helpers/FileHelper.dart'; import 'Models/session.dart'; +import 'Screens/Main/main_screen.dart'; import 'Screens/login_screen.dart'; import 'Screens/Policy/policy_screen.dart'; import 'app_context.dart'; +import 'client.dart'; import 'constants.dart'; import 'package:flutter_web_plugins/url_strategy.dart'; +import 'dart:html' as html; //import 'package:window_size/window_size.dart'; Future main() async { - String initialRoute; - WidgetsFlutterBinding.ensureInitialized(); - initialRoute = '/login'; - var session = await loadJsonSessionFile(); ManagerAppContext managerAppContext = ManagerAppContext(); managerAppContext.instanceId = session.instanceId; - final MyApp myApp = MyApp( - initialRoute: initialRoute, - session: session, - managerAppContext: managerAppContext - //context: localContext, - ); - await Firebase.initializeApp( // Replace with actual values options: FirebaseOptions( @@ -47,16 +42,173 @@ Future main() async { ), ); + String? currentPath = html.window.location.pathname; + usePathUrlStrategy(); - runApp(myApp); + runApp( + MaterialApp( + home: FutureBuilder( + future: getInstanceInfo(managerAppContext), + builder: (context, asyncSnapshot) { + if (asyncSnapshot.connectionState == ConnectionState.done) { + var instanceDTO = asyncSnapshot.data; + managerAppContext.instanceId = instanceDTO?.id; + managerAppContext.instanceDTO = instanceDTO; + + String initialRoute = currentPath!.isNotEmpty ? currentPath : '/login'; + + var _router = GoRouter( + initialLocation: initialRoute, + redirect: (context, state) { + var instanceId = managerAppContext.instanceId; + if (instanceId == null && state.fullPath != '/login') { + return '/login'; + } + + + if (instanceId != null) { + if(state.fullPath == '/login' || state.fullPath == "") { + if(managerAppContext.instanceDTO!.isMobile!) { + return '/main/mobile'; + } + if(managerAppContext.instanceDTO!.isTablet!) { + return '/main/tablet'; + } + if(managerAppContext.instanceDTO!.isWeb!) { + return '/main/web'; + } + if(managerAppContext.instanceDTO!.isVR!) { + return '/main/vr'; + } + } + return state.matchedLocation; + } + + return null; + }, + routes: [ + GoRoute( + path: '/login', + builder: (context, state) => LoginScreen(), + ), + GoRoute( + path: '/main/:view', + builder: (context, state) { + final view = state.pathParameters['view']; + return MainScreen( + instance: managerAppContext.instanceDTO!, + view: view, + ); + }, + ), + GoRoute( + path: '/policy', + builder: (context, state) => PolicyScreen(), + ), + GoRoute( + path: '/policy/mdlf', + builder: (context, state) => PolicyScreen(param: "mdlf"), + ), + GoRoute( + path: '/policy/fort', + builder: (context, state) => PolicyScreen(param: "fort"), + ), + ], + errorBuilder: (context, state) => MaterialApp( + home: Scaffold( + body: Center( + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.85, + child: Text( + "404 - Cette page n'existe pas", + textAlign: TextAlign.center, + style: TextStyle(color: kPrimaryColor, fontSize: 20.0), + ), + ), + ), + ), + ), + ); + + return MyApp( + session: session, + managerAppContext: managerAppContext, + router: _router + ); + } else if (asyncSnapshot.connectionState == ConnectionState.none) { + return MaterialApp( + home: Scaffold( + body: Center( + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.85, + child: Text( + "No data", + textAlign: TextAlign.center, + style: TextStyle(color: kPrimaryColor, fontSize: 20.0), + ), + ), + ), + ), + ); + } else { + return MaterialApp( + home: Scaffold( + body: Center( + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.85, + child: Container( + height: 250, + child: CommonLoader() + ), + ), + ), + ), + ); + } + } + ), + ) + ); +} + +Future getInstanceInfo(ManagerAppContext managerAppContext) async { + var session = await loadJsonSessionFile(); + + try { + managerAppContext.instanceId = managerAppContext.instanceId ?? session.instanceId; + managerAppContext.host = managerAppContext.host ?? session.host; + managerAppContext.accessToken = managerAppContext.accessToken ?? session.token; + managerAppContext.email = managerAppContext.email ?? session.email; + + if(session.instanceId != null) { + if(managerAppContext.clientAPI == null) { + managerAppContext.clientAPI = Client(session.host!); + managerAppContext.clientAPI!.apiApi!.addDefaultHeader('authorization', 'Bearer '+ managerAppContext.accessToken!); + } + + InstanceDTO? instance = await managerAppContext.clientAPI!.instanceApi!.instanceGetDetail(managerAppContext.instanceId!); + managerAppContext.instanceDTO = instance; + return instance; + } + + return null; + } catch(e) { + // todo + /*Navigator.pushNamedAndRemoveUntil( + context, + '/login', + (Route route) => false, + );*/ + return null; + } } class MyApp extends StatefulWidget { - final String initialRoute; final Session session; final ManagerAppContext managerAppContext; - MyApp({required this.initialRoute, required this.session, required this.managerAppContext}); + final GoRouter router; + MyApp({required this.session, required this.managerAppContext, required this.router}); // This widget is the root of your application. @override @@ -70,7 +222,8 @@ class _MyAppState extends State { Widget build(BuildContext context) { return ChangeNotifierProvider( create: (_) => AppContext(widget.managerAppContext), - child: MaterialApp( + child: MaterialApp.router( + routerConfig: widget.router, key: mainKey, builder: (context, child) => ResponsiveBreakpoints.builder( child: child!, @@ -84,7 +237,7 @@ class _MyAppState extends State { scrollBehavior: MyCustomScrollBehavior(), debugShowCheckedModeBanner: false, title: 'MyInfoMate - Manager', - initialRoute: widget.initialRoute, + //initialRoute: widget.initialRoute, /*supportedLocales: [ const Locale('en', 'US'), //const Locale('fr', 'FR'), @@ -97,7 +250,7 @@ class _MyAppState extends State { textTheme: TextTheme(bodyLarge: TextStyle(color: kBodyTextColor)), visualDensity: VisualDensity.adaptivePlatformDensity, ), - routes: { + /*routes: { '/login': (context) => LoginScreen(session: widget.session), '/main': (context) => MainScreen(), '/policy': (context) => PolicyScreen(), @@ -106,7 +259,7 @@ class _MyAppState extends State { }, onUnknownRoute: (settings) => MaterialPageRoute( builder: (context) => Container(child: Center(child: Text("Not found"))), - ), + ),*/ ), ); } diff --git a/pubspec.lock b/pubspec.lock index a95ec1c..6a1c37a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -189,10 +189,10 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -221,10 +221,10 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" code_builder: dependency: transitive description: @@ -237,10 +237,10 @@ packages: dependency: "direct main" description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.19.1" convert: dependency: "direct main" description: @@ -325,10 +325,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" ffi: dependency: transitive description: @@ -624,6 +624,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: ced3fdc143c1437234ac3b8e985f3286cf138968bb83ca9a6f94d22f2951c6b9 + url: "https://pub.dev" + source: hosted + version: "16.2.0" graphs: dependency: transitive description: @@ -740,26 +748,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lists: dependency: transitive description: @@ -803,10 +811,10 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -827,10 +835,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" mgrs_dart: dependency: transitive description: @@ -947,10 +955,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_parsing: dependency: transitive description: @@ -1232,18 +1240,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" stream_transform: dependency: transitive description: @@ -1288,10 +1296,10 @@ packages: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "0.7.6" timing: dependency: transitive description: @@ -1416,10 +1424,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" video_player: dependency: transitive description: @@ -1592,18 +1600,18 @@ packages: dependency: "direct main" description: name: youtube_player_iframe - sha256: d7aec9083430db4e5da83a3b5d7b7fcbb93cfa027d9f680ce3c7e7cd20724305 + sha256: c72145e67016577e229fbf3eb120e0dcfac9507d48a50354e7f321852a360e79 url: "https://pub.dev" source: hosted - version: "4.0.4" + version: "5.1.3" youtube_player_iframe_web: dependency: transitive description: name: youtube_player_iframe_web - sha256: c7020816031600349b56d2729d4e8be011fcb723ff7dc2dd0cdf72096a0e5ff4 + sha256: "743e8ce2ee77b8ea6e36ae986f0ef111b38c3119ae55ae813223ecddeb56b770" url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "3.0.2" sdks: - dart: ">=3.4.0 <4.0.0" - flutter: ">=3.22.0" + dart: ">=3.8.0-0 <4.0.0" + flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index ecd763e..d310352 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,8 +46,9 @@ dependencies: just_audio_web: ^0.4.13 pdf: ^3.10.4 multi_select_flutter: ^4.1.3 - youtube_player_iframe: ^4.0.4 + youtube_player_iframe: ^5.0.0 location_picker_flutter_map: ^3.0.1 + go_router: ^16.2.0 #msix: ^2.1.3 #window_size: