mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
Merge pull request #126 from SyncrowIOT/fix_routine_popup
Refactor routine creation UI for improved code organization
This commit is contained in:
@ -1,16 +1,16 @@
|
|||||||
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
|
||||||
|
|
||||||
class CommunityDropdown extends StatelessWidget {
|
class CommunityDropdown extends StatelessWidget {
|
||||||
final String? selectedValue;
|
final String? selectedValue;
|
||||||
final Function(String?) onChanged;
|
final Function(String?) onChanged;
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
|
||||||
const CommunityDropdown({
|
CommunityDropdown({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.selectedValue,
|
required this.selectedValue,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
@ -34,59 +34,125 @@ class CommunityDropdown extends StatelessWidget {
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
|
BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
List<CommunityModel> communities = state.isSearching
|
|
||||||
? state.filteredCommunity
|
|
||||||
: state.communityList;
|
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
child: DropdownButtonFormField<String>(
|
child: Container(
|
||||||
dropdownColor: ColorsManager.whiteColors,
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: DropdownButton2<String>(
|
||||||
|
underline: SizedBox(),
|
||||||
value: selectedValue,
|
value: selectedValue,
|
||||||
items: communities.map((community) {
|
items: state.communityList.map((community) {
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: community.uuid,
|
value: community.uuid,
|
||||||
child: Text(' ${community.name}'),
|
child: Text(
|
||||||
|
' ${community.name}',
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
icon: const SizedBox.shrink(),
|
style: TextStyle(color: Colors.black),
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
|
||||||
hint: Padding(
|
hint: Padding(
|
||||||
padding: EdgeInsets.only(left: 10),
|
padding: EdgeInsets.only(left: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Please Select",
|
" Please Select",
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
color: ColorsManager.textGray,
|
color: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
decoration: inputTextFormDeco().copyWith(
|
customButton: Container(
|
||||||
contentPadding: EdgeInsets.zero,
|
height: 45,
|
||||||
suffixIcon: Container(
|
decoration: BoxDecoration(
|
||||||
padding: EdgeInsets.zero,
|
border:
|
||||||
width: 70,
|
Border.all(color: ColorsManager.textGray, width: 1.0),
|
||||||
height: 45,
|
borderRadius: BorderRadius.circular(10),
|
||||||
decoration: BoxDecoration(
|
),
|
||||||
color: Colors.grey[100],
|
child: Row(
|
||||||
borderRadius: const BorderRadius.only(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
bottomRight: Radius.circular(10),
|
children: [
|
||||||
topRight: Radius.circular(10),
|
Expanded(
|
||||||
|
flex: 5,
|
||||||
|
child: Text(
|
||||||
|
selectedValue != null
|
||||||
|
? " ${state.communityList.firstWhere((element) => element.uuid == selectedValue).name}"
|
||||||
|
: ' Please Select',
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: selectedValue != null
|
||||||
|
? Colors.black
|
||||||
|
: ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
border: Border.all(
|
Expanded(
|
||||||
color: ColorsManager.textGray,
|
child: Container(
|
||||||
width: 1.0,
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[100],
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: Radius.circular(10),
|
||||||
|
bottomRight: Radius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: 45,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
child: const Center(
|
),
|
||||||
child: Icon(
|
),
|
||||||
Icons.keyboard_arrow_down,
|
dropdownStyleData: DropdownStyleData(
|
||||||
color: ColorsManager.textGray,
|
maxHeight: MediaQuery.of(context).size.height * 0.4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dropdownSearchData: DropdownSearchData(
|
||||||
|
searchController: _searchController,
|
||||||
|
searchInnerWidgetHeight: 50,
|
||||||
|
searchInnerWidget: Container(
|
||||||
|
height: 50,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8, vertical: 4),
|
||||||
|
child: TextFormField(
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
controller: _searchController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 10,
|
||||||
|
vertical: 12,
|
||||||
|
),
|
||||||
|
hintText: 'Search for community...',
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
searchMatchFn: (item, searchValue) {
|
||||||
|
final communityName =
|
||||||
|
(item.child as Text).data?.toLowerCase() ?? '';
|
||||||
|
return communityName
|
||||||
|
.contains(searchValue.toLowerCase().trim());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
onMenuStateChange: (isOpen) {
|
||||||
|
if (!isOpen) {
|
||||||
|
_searchController.clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
menuItemStyleData: const MenuItemStyleData(
|
||||||
|
height: 40,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -62,28 +62,34 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
const Divider(),
|
const Divider(),
|
||||||
CommunityDropdown(
|
Padding(
|
||||||
selectedValue: _selectedCommunity,
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
onChanged: (String? newValue) {
|
child: CommunityDropdown(
|
||||||
setState(() {
|
selectedValue: _selectedCommunity,
|
||||||
_selectedCommunity = newValue;
|
onChanged: (String? newValue) {
|
||||||
_selectedSpace = null;
|
setState(() {
|
||||||
});
|
_selectedCommunity = newValue;
|
||||||
if (newValue != null) {
|
_selectedSpace = null;
|
||||||
_fetchSpaces(newValue);
|
});
|
||||||
}
|
if (newValue != null) {
|
||||||
},
|
_fetchSpaces(newValue);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 5),
|
||||||
SpaceDropdown(
|
Padding(
|
||||||
hintMessage: spaceHint,
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
spaces: spaces,
|
child: SpaceDropdown(
|
||||||
selectedValue: _selectedSpace,
|
hintMessage: spaceHint,
|
||||||
onChanged: (String? newValue) {
|
spaces: spaces,
|
||||||
setState(() {
|
selectedValue: _selectedSpace,
|
||||||
_selectedSpace = newValue;
|
onChanged: (String? newValue) {
|
||||||
});
|
setState(() {
|
||||||
},
|
_selectedSpace = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
Row(
|
Row(
|
||||||
@ -96,7 +102,6 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
|
|||||||
),
|
),
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -139,6 +144,7 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
|
||||||
|
|
||||||
class SpaceDropdown extends StatelessWidget {
|
class SpaceDropdown extends StatelessWidget {
|
||||||
final List<SpaceModel> spaces;
|
final List<SpaceModel> spaces;
|
||||||
@ -33,62 +34,108 @@ class SpaceDropdown extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
DropdownButtonFormField<String>(
|
SizedBox(
|
||||||
value: selectedValue,
|
child: Container(
|
||||||
items: spaces.map((space) {
|
decoration: BoxDecoration(
|
||||||
return DropdownMenuItem<String>(
|
borderRadius: BorderRadius.circular(10),
|
||||||
value: space.uuid,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
' ${space.name}',
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
|
||||||
fontSize: 12,
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
' ${space.lastThreeParents}',
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}).toList(),
|
|
||||||
onChanged: onChanged,
|
|
||||||
icon: const SizedBox.shrink(),
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
|
||||||
hint: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 10),
|
|
||||||
child: Text(
|
|
||||||
hintMessage,
|
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
|
||||||
color: ColorsManager.textGray,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
child: DropdownButton2<String>(
|
||||||
decoration: inputTextFormDeco().copyWith(
|
underline: const SizedBox(),
|
||||||
contentPadding: EdgeInsets.zero,
|
value: selectedValue,
|
||||||
suffixIcon: Container(
|
items: spaces.map((space) {
|
||||||
width: 70,
|
return DropdownMenuItem<String>(
|
||||||
height: 45,
|
value: space.uuid,
|
||||||
decoration: BoxDecoration(
|
child: Column(
|
||||||
color: Colors.grey[200],
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
borderRadius: const BorderRadius.only(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
bottomRight: Radius.circular(10),
|
children: [
|
||||||
topRight: Radius.circular(10),
|
Text(
|
||||||
),
|
' ${space.name}',
|
||||||
border: Border.all(
|
style:
|
||||||
color: ColorsManager.textGray,
|
Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
width: 1.0,
|
fontSize: 12,
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
' ${space.lastThreeParents}',
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: onChanged,
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
hint: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: Text(
|
||||||
|
hintMessage,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Icon(
|
customButton: Container(
|
||||||
Icons.keyboard_arrow_down,
|
height: 45,
|
||||||
color: ColorsManager.textGray,
|
decoration: BoxDecoration(
|
||||||
|
border:
|
||||||
|
Border.all(color: ColorsManager.textGray, width: 1.0),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 5,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: Text(
|
||||||
|
selectedValue != null
|
||||||
|
? spaces
|
||||||
|
.firstWhere((e) => e.uuid == selectedValue)
|
||||||
|
.name
|
||||||
|
: hintMessage,
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: selectedValue != null
|
||||||
|
? Colors.black
|
||||||
|
: ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[200],
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: Radius.circular(10),
|
||||||
|
bottomRight: Radius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: 45,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dropdownStyleData: DropdownStyleData(
|
||||||
|
maxHeight: MediaQuery.of(context).size.height * 0.4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
menuItemStyleData: const MenuItemStyleData(
|
||||||
|
height: 60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -33,8 +33,6 @@ class _RoutinesViewState extends State<RoutinesView> {
|
|||||||
communityID: communityId, spaceID: spaceId));
|
communityID: communityId, spaceID: spaceId));
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
routineBloc.add(const CreateNewRoutineViewEvent(createRoutineView: true));
|
routineBloc.add(const CreateNewRoutineViewEvent(createRoutineView: true));
|
||||||
await Future.delayed(const Duration(milliseconds:500));
|
|
||||||
_bloc.add(const ResetSelectedEvent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
Reference in New Issue
Block a user