mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-25 15:07:55 +00:00
Progress towards 1493.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/enums/analytics_page_tab.dart';
|
||||
|
||||
part 'analytics_tab_event.dart';
|
||||
part 'analytics_tab_state.dart';
|
||||
|
||||
class AnalyticsTabBloc extends Bloc<AnalyticsTabEvent, AnalyticsTabState> {
|
||||
AnalyticsTabBloc() : super(const AnalyticsTabState()) {
|
||||
on<UpdateAnalyticsTabEvent>(_onUpdateAnalyticsTabEvent);
|
||||
}
|
||||
|
||||
void _onUpdateAnalyticsTabEvent(
|
||||
UpdateAnalyticsTabEvent event,
|
||||
Emitter<AnalyticsTabState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedTab: event.analyticsTab));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
part of 'analytics_tab_bloc.dart';
|
||||
|
||||
sealed class AnalyticsTabEvent extends Equatable {
|
||||
const AnalyticsTabEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class UpdateAnalyticsTabEvent extends AnalyticsTabEvent {
|
||||
const UpdateAnalyticsTabEvent(this.analyticsTab);
|
||||
|
||||
final AnalyticsPageTab analyticsTab;
|
||||
|
||||
@override
|
||||
List<Object> get props => [analyticsTab];
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
part of 'analytics_tab_bloc.dart';
|
||||
|
||||
final class AnalyticsTabState extends Equatable {
|
||||
const AnalyticsTabState({
|
||||
this.selectedTab = AnalyticsPageTab.energyManagement,
|
||||
});
|
||||
|
||||
final AnalyticsPageTab selectedTab;
|
||||
|
||||
AnalyticsTabState copyWith({
|
||||
AnalyticsPageTab? selectedTab,
|
||||
}) {
|
||||
return AnalyticsTabState(
|
||||
selectedTab: selectedTab ?? this.selectedTab,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedTab];
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/views/analytics_energy_management_view.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/occupancy/views/analytics_occupancy_view.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/overview/views/analytics_overview_view.dart';
|
||||
|
||||
enum AnalyticsPageTab {
|
||||
overview(
|
||||
title: 'Overview',
|
||||
child: AnalyticsOverviewView(),
|
||||
),
|
||||
energyManagement(
|
||||
title: 'Energy Management',
|
||||
child: AnalyticsEnergyManagementView(),
|
||||
),
|
||||
occupancy(
|
||||
title: 'Occupancy',
|
||||
child: AnalyticsOccupancyView(),
|
||||
);
|
||||
|
||||
const AnalyticsPageTab({
|
||||
required this.title,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
final Widget child;
|
||||
final String title;
|
||||
}
|
||||
@@ -1,19 +1,41 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/bloc/analytics_tab_bloc.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_communities_sidebar.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_page_tabs_and_children.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
||||
import 'package:syncrow_web/utils/theme/responsive_text_theme.dart';
|
||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||
|
||||
class AnalyticsPage extends StatelessWidget {
|
||||
const AnalyticsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider<AnalyticsTabBloc>(
|
||||
create: (context) => AnalyticsTabBloc(),
|
||||
child: const AnalyticsPageForm(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AnalyticsPageForm extends StatelessWidget {
|
||||
const AnalyticsPageForm({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WebScaffold(
|
||||
rightBody: const NavigateHomeGridView(),
|
||||
appBarTitle: Text(
|
||||
'Syncrow Analytics',
|
||||
style: ResponsiveTextTheme.of(context).deviceManagementTitle,
|
||||
),
|
||||
scaffoldBody: const Center(
|
||||
child: Text('AnalyticsPage is Working!'),
|
||||
enableMenuSidebar: false,
|
||||
scaffoldBody: const Row(
|
||||
children: [
|
||||
AnalyticsCommunitiesSidebar(),
|
||||
Expanded(flex: 5, child: AnalyticsPageTabsAndChildren()),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||
|
||||
class AnalyticsCommunitiesSidebar extends StatelessWidget {
|
||||
const AnalyticsCommunitiesSidebar({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: SpaceTreeView(
|
||||
title: const Text('Communities'),
|
||||
shouldDisableDeselectingChildrenOfSelectedParent: true,
|
||||
onSelect: () {},
|
||||
isSide: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class AnalyticsDateFilterButton extends StatelessWidget {
|
||||
const AnalyticsDateFilterButton({super.key});
|
||||
|
||||
static final _color = ColorsManager.blackColor.withValues(alpha: 0.8);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton.icon(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: _color,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
side: const BorderSide(
|
||||
color: ColorsManager.greyColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
backgroundColor: ColorsManager.transparentColor,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
vertical: 16,
|
||||
),
|
||||
),
|
||||
icon: SvgPicture.asset(
|
||||
Assets.blankCalendar,
|
||||
height: 20,
|
||||
width: 20,
|
||||
colorFilter: ColorFilter.mode(_color, BlendMode.srcIn),
|
||||
),
|
||||
label: Text(
|
||||
_concatenateDate(DateTime(2024, 1), DateTime(2024, 12)),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
onPressed: () {},
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDate(DateTime date) {
|
||||
final formatter = DateFormat('MMM yyyy');
|
||||
final formattedDate = formatter.format(date);
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
String _concatenateDate(DateTime startDate, DateTime endDate) {
|
||||
final formattedStartDate = _formatDate(startDate);
|
||||
final formattedEndDate = _formatDate(endDate);
|
||||
return '$formattedStartDate - $formattedEndDate';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/bloc/analytics_tab_bloc.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/enums/analytics_page_tab.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class AnalyticsPageTabButton extends StatelessWidget {
|
||||
const AnalyticsPageTabButton({
|
||||
super.key,
|
||||
required this.tab,
|
||||
required this.isSelected,
|
||||
});
|
||||
|
||||
final AnalyticsPageTab tab;
|
||||
final bool isSelected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
onPressed: () => context.read<AnalyticsTabBloc>().add(
|
||||
UpdateAnalyticsTabEvent(tab),
|
||||
),
|
||||
child: Text(
|
||||
tab.title,
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: isSelected ? FontWeight.w700 : FontWeight.w400,
|
||||
fontSize: 16,
|
||||
color:
|
||||
isSelected ? ColorsManager.slidingBlueColor : ColorsManager.textGray,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/bloc/analytics_tab_bloc.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/enums/analytics_page_tab.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_date_filter_button.dart';
|
||||
import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_page_tab_button.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class AnalyticsPageTabsAndChildren extends StatelessWidget {
|
||||
const AnalyticsPageTabsAndChildren({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<AnalyticsTabBloc, AnalyticsTabState>(
|
||||
buildWhen: (previous, current) => previous.selectedTab != current.selectedTab,
|
||||
builder: (context, state) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width * 1,
|
||||
decoration: subSectionContainerDecoration,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
// vertical: 48,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
...AnalyticsPageTab.values.map(
|
||||
(tab) => Expanded(
|
||||
child: AnalyticsPageTabButton(
|
||||
tab: tab,
|
||||
isSelected: tab == state.selectedTab,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Expanded(
|
||||
flex: 2,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
child: AnalyticsDateFilterButton(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
child: AnimatedSwitcher(
|
||||
switchInCurve: Curves.easeIn,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: state.selectedTab.child,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AnalyticsEnergyManagementView extends StatelessWidget {
|
||||
const AnalyticsEnergyManagementView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Center(
|
||||
child: Text('EnergyManagementView is Working!'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AnalyticsOccupancyView extends StatelessWidget {
|
||||
const AnalyticsOccupancyView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Center(
|
||||
child: Text('AnalyticsOccupancyView is Working!'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AnalyticsOverviewView extends StatelessWidget {
|
||||
const AnalyticsOverviewView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Center(
|
||||
child: Text('Coming Soon!'),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user