overwrite dialog and progress indicator and success dialog

This commit is contained in:
mohammad
2025-02-18 12:37:00 +03:00
parent 00a9cb1188
commit 009ede7d08
12 changed files with 337 additions and 203 deletions

View File

@ -0,0 +1,3 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.2614 20.4808C44.1769 21.3963 44.1769 22.8804 43.2614 23.7955L27.5381 39.5192C26.6226 40.4343 25.139 40.4343 24.2235 39.5192L16.7386 32.0338C15.8231 31.1188 15.8231 29.6347 16.7386 28.7196C17.6537 27.8041 19.1377 27.8041 20.0528 28.7196L25.8806 34.5474L39.9467 20.4808C40.8623 19.5657 42.3463 19.5657 43.2614 20.4808ZM60 30C60 46.5825 46.5802 60 30 60C13.4175 60 0 46.5802 0 30C0 13.4175 13.4198 0 30 0C46.5825 0 60 13.4198 60 30ZM55.3125 30C55.3125 16.0085 43.9897 4.6875 30 4.6875C16.0085 4.6875 4.6875 16.0103 4.6875 30C4.6875 43.9915 16.0103 55.3125 30 55.3125C43.9915 55.3125 55.3125 43.9897 55.3125 30Z" fill="#023DFE" fill-opacity="0.7"/>
</svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@ -24,7 +24,8 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) => AcBloc(deviceId: device.uuid!)..add(AcFetchDeviceStatusEvent(device.uuid!)),
create: (context) => AcBloc(deviceId: device.uuid!)
..add(AcFetchDeviceStatusEvent(device.uuid!)),
child: BlocBuilder<AcBloc, AcsState>(
builder: (context, state) {
if (state is ACStatusLoaded) {
@ -98,7 +99,8 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
),
Text(
'h',
style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
style: context.textTheme.bodySmall!
.copyWith(color: ColorsManager.blackColor),
),
Text(
'30',
@ -107,7 +109,9 @@ class AcDeviceControlsView extends StatelessWidget with HelperResponsiveLayout {
fontWeight: FontWeight.bold,
),
),
Text('m', style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor)),
Text('m',
style: context.textTheme.bodySmall!
.copyWith(color: ColorsManager.blackColor)),
IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {},

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/common/widgets/search_bar.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
@ -8,11 +9,14 @@ import 'package:syncrow_web/pages/space_tree/view/custom_expansion.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_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/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/style.dart';
class SpaceTreeView extends StatefulWidget {
final bool? isSide;
final Function onSelect;
const SpaceTreeView({required this.onSelect, super.key});
const SpaceTreeView({required this.onSelect, this.isSide, super.key});
@override
State<SpaceTreeView> createState() => _SpaceTreeViewState();
@ -29,20 +33,77 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
@override
Widget build(BuildContext context) {
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>(builder: (context, state) {
List<CommunityModel> list = state.isSearching ? state.filteredCommunity : state.communityList;
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
builder: (context, state) {
List<CommunityModel> list =
state.isSearching ? state.filteredCommunity : state.communityList;
return Container(
height: MediaQuery.sizeOf(context).height,
decoration: subSectionContainerDecoration,
decoration:
widget.isSide == true ? subSectionContainerDecoration : null,
child: state is SpaceTreeLoadingState
? const Center(child: CircularProgressIndicator())
: Column(
children: [
CustomSearchBar(
onSearchChanged: (query) {
context.read<SpaceTreeBloc>().add(SearchQueryEvent(query));
},
),
widget.isSide == true
? Container(
decoration: const BoxDecoration(
color: ColorsManager.circleRolesBackground,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(20)),
border: Border.all(
color: ColorsManager.grayBorder)),
child: TextFormField(
style:
const TextStyle(color: Colors.black),
onChanged: (value) {
context
.read<SpaceTreeBloc>()
.add(SearchQueryEvent(value));
},
decoration: textBoxDecoration(radios: 20)!
.copyWith(
fillColor: Colors.white,
suffixIcon: Padding(
padding:
const EdgeInsets.only(right: 16),
child: SvgPicture.asset(
Assets.textFieldSearch,
width: 24,
height: 24,
),
),
hintStyle: context.textTheme.bodyMedium
?.copyWith(
fontWeight: FontWeight.w400,
fontSize: 12,
color: ColorsManager.textGray),
),
),
),
),
],
),
),
)
: CustomSearchBar(
onSearchChanged: (query) {
context
.read<SpaceTreeBloc>()
.add(SearchQueryEvent(query));
},
),
const SizedBox(height: 16),
Expanded(
child: ListView(
@ -56,14 +117,18 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
? Center(
child: Text(
'No results found',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.lightGrayColor,
fontWeight: FontWeight.w400,
),
),
)
: Scrollbar(
scrollbarOrientation: ScrollbarOrientation.left,
scrollbarOrientation:
ScrollbarOrientation.left,
thumbVisibility: true,
controller: _scrollController,
child: Padding(
@ -73,47 +138,68 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
shrinkWrap: true,
children: list
.map(
(community) => CustomExpansionTileSpaceTree(
(community) =>
CustomExpansionTileSpaceTree(
title: community.name,
isSelected: state.selectedCommunities
isSelected: state
.selectedCommunities
.contains(community.uuid),
isSoldCheck: state.selectedCommunities
isSoldCheck: state
.selectedCommunities
.contains(community.uuid),
onExpansionChanged: () {
context
.read<SpaceTreeBloc>()
.add(OnCommunityExpanded(community.uuid));
.add(OnCommunityExpanded(
community.uuid));
},
isExpanded: state.expandedCommunities
isExpanded: state
.expandedCommunities
.contains(community.uuid),
onItemSelected: () {
context.read<SpaceTreeBloc>().add(
OnCommunitySelected(
community.uuid, community.spaces));
context
.read<SpaceTreeBloc>()
.add(OnCommunitySelected(
community.uuid,
community.spaces));
widget.onSelect();
},
children: community.spaces.map((space) {
children:
community.spaces.map((space) {
return CustomExpansionTileSpaceTree(
title: space.name,
isExpanded:
state.expandedSpaces.contains(space.uuid),
isExpanded: state
.expandedSpaces
.contains(space.uuid),
onItemSelected: () {
context.read<SpaceTreeBloc>().add(
OnSpaceSelected(community.uuid,
space.uuid ?? '', space.children));
context
.read<SpaceTreeBloc>()
.add(OnSpaceSelected(
community.uuid,
space.uuid ?? '',
space.children));
widget.onSelect();
},
onExpansionChanged: () {
context.read<SpaceTreeBloc>().add(
OnSpaceExpanded(
community.uuid, space.uuid ?? ''));
context
.read<SpaceTreeBloc>()
.add(OnSpaceExpanded(
community.uuid,
space.uuid ?? ''));
},
isSelected:
state.selectedSpaces.contains(space.uuid) ||
state.soldCheck.contains(space.uuid),
isSoldCheck: state.soldCheck.contains(space.uuid),
isSelected: state
.selectedSpaces
.contains(
space.uuid) ||
state.soldCheck
.contains(space.uuid),
isSoldCheck: state.soldCheck
.contains(space.uuid),
children: _buildNestedSpaces(
context, state, space, community.uuid),
context,
state,
space,
community.uuid),
);
}).toList(),
),
@ -195,23 +281,24 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
});
}
List<Widget> _buildNestedSpaces(
BuildContext context, SpaceTreeState state, SpaceModel space, String communityId) {
List<Widget> _buildNestedSpaces(BuildContext context, SpaceTreeState state,
SpaceModel space, String communityId) {
return space.children.map((child) {
return CustomExpansionTileSpaceTree(
isSelected:
state.selectedSpaces.contains(child.uuid) || state.soldCheck.contains(child.uuid),
isSelected: state.selectedSpaces.contains(child.uuid) ||
state.soldCheck.contains(child.uuid),
isSoldCheck: state.soldCheck.contains(child.uuid),
title: child.name,
isExpanded: state.expandedSpaces.contains(child.uuid),
onItemSelected: () {
context
.read<SpaceTreeBloc>()
.add(OnSpaceSelected(communityId, child.uuid ?? '', child.children));
context.read<SpaceTreeBloc>().add(
OnSpaceSelected(communityId, child.uuid ?? '', child.children));
widget.onSelect();
},
onExpansionChanged: () {
context.read<SpaceTreeBloc>().add(OnSpaceExpanded(communityId, child.uuid ?? ''));
context
.read<SpaceTreeBloc>()
.add(OnSpaceExpanded(communityId, child.uuid ?? ''));
},
children: _buildNestedSpaces(context, state, child, communityId),
);

View File

@ -11,7 +11,7 @@ class SpaceTemplateModel extends Equatable {
List<SubspaceTemplateModel>? subspaceModels;
final List<TagModel>? tags;
String internalId;
DateTime? createdAt;
String? createdAt;
@override
List<Object?> get props => [modelName, subspaceModels, tags];

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class ConfirmOverwriteDialog extends StatelessWidget {
@ -56,7 +57,16 @@ class ConfirmOverwriteDialog extends StatelessWidget {
const SizedBox(width: 10),
Expanded(
child: ElevatedButton(
onPressed: () {},
onPressed: () {
Navigator.pop(context);
showDialog(
context: context,
builder: (BuildContext dialogContext) {
return const LinkingSuccessful();
},
);
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 14),
backgroundColor: ColorsManager.secondaryColor,

View File

@ -1,42 +1,7 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart';
void showCustomLoadingDialog(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false, // Prevent closing by tapping outside
builder: (BuildContext context) {
Future.delayed(Duration(seconds: 3), () {
Navigator.of(context).pop(); // Auto-close after 3 seconds
});
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
elevation: 10,
backgroundColor: Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 30, horizontal: 50),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Custom loader
CustomLoadingIndicator(),
SizedBox(height: 20),
Text(
"Linking in progress",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
],
),
),
);
},
);
}
class CustomLoadingIndicator extends StatefulWidget {
@override
@ -52,8 +17,8 @@ class _CustomLoadingIndicatorState extends State<CustomLoadingIndicator>
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 1), // Rotation speed
)..repeat(); // Infinite animation
duration: const Duration(seconds: 1),
)..repeat();
}
@override
@ -71,7 +36,7 @@ class _CustomLoadingIndicatorState extends State<CustomLoadingIndicator>
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * pi, // Full rotation
angle: _controller.value * 2 * pi,
child: CustomPaint(
painter: LoadingPainter(),
),

View File

@ -1,11 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/add_user_dialog/view/build_tree_view.dart';
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/style.dart';
class LinkSpaceModelSpacesDialog extends StatelessWidget {
final SpaceTemplateModel spaceModel;
@ -16,114 +14,69 @@ class LinkSpaceModelSpacesDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AlertDialog(
contentPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
backgroundColor: Colors.white,
contentPadding: const EdgeInsets.all(20),
content: SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
const Center(
child: Text(
"Link Space Model to Spaces",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.blueAccent,
),
),
),
const Divider(),
const SizedBox(height: 16),
// Details Section
_buildDetailRow("Space model name:", spaceModel.modelName),
_buildDetailRow("Creation date and time:", spaceModel.modelName),
_buildDetailRow("Created by:", "Admin"),
const SizedBox(height: 12),
// Link to Section
const Text(
"Link to:",
style: TextStyle(fontWeight: FontWeight.bold),
),
const Text(
"Please select all the spaces where you would like to link the Routine.",
style: TextStyle(fontSize: 12, color: Colors.grey),
),
const SizedBox(height: 8),
// Spaces List
Expanded(
child: SizedBox(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 2,
child: Container(
decoration: const BoxDecoration(
color: ColorsManager.circleRolesBackground,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(20)),
border: Border.all(
color: ColorsManager.grayBorder)),
child: TextFormField(
style: const TextStyle(color: Colors.black),
// controller: _blocRole.firstNameController,
onChanged: (value) {
// _blocRole.add(SearchAnode(
// nodes: _blocRole.updatedCommunities,
// searchTerm: value));
},
decoration:
textBoxDecoration(radios: 20)!.copyWith(
fillColor: Colors.white,
suffixIcon: Padding(
padding:
const EdgeInsets.only(right: 16),
child: SvgPicture.asset(
Assets.textFieldSearch,
width: 24,
height: 24,
),
),
hintStyle: context.textTheme.bodyMedium
?.copyWith(
fontWeight: FontWeight.w400,
fontSize: 12,
color: ColorsManager.textGray),
),
),
),
),
],
),
const Center(
child: Text(
"Link Space Model to Spaces",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.blueAccent,
),
),
),
const Divider(),
const SizedBox(height: 16),
_buildDetailRow("Space model name:",
spaceModel.modelName),
_buildDetailRow("Creation date and time:",
spaceModel.createdAt.toString()),
_buildDetailRow("Created by:", "Admin"),
const SizedBox(height: 12),
const Text(
"Link to:",
style: TextStyle(fontWeight: FontWeight.bold),
),
const Text(
"Please select all the spaces where you would like to link the Routine.",
style: TextStyle(fontSize: 12, color: Colors.grey),
),
const SizedBox(height: 8),
Expanded(
flex: 7,
child: Container(
color: ColorsManager.circleRolesBackground,
padding: const EdgeInsets.all(8.0),
child: Container(
color: ColorsManager.whiteColors,
child: TreeView(userId: ''))))
child: SizedBox(
child: Column(
children: [
Expanded(
flex: 7,
child: Container(
color: ColorsManager.whiteColors,
child: SpaceTreeView(
isSide: true, onSelect: () {
}))
)
],
),
),
),
const SizedBox(
height: 20,
),
],
),
),
@ -131,14 +84,98 @@ class LinkSpaceModelSpacesDialog extends StatelessWidget {
// Buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildButton("Cancel", Colors.grey, () {
Navigator.of(context).pop();
}),
_buildButton("Confirm", Colors.blueAccent, () {
Navigator.of(context).pop();
}),
Expanded(
child: Container(
height: 50,
decoration: const BoxDecoration(
border: Border(
right: BorderSide(
color: ColorsManager.grayColor,
width: 0.5,
),
top: BorderSide(
color: ColorsManager.grayColor,
width: 1,
),
),
),
child: _buildButton("Cancel", Colors.grey, () {
Navigator.of(context).pop();
}),
),
),
Expanded(
child: Container(
height: 50,
decoration: const BoxDecoration(
border: Border(
left: BorderSide(
color: ColorsManager.grayColor,
width: 0.5,
),
top: BorderSide(
color: ColorsManager.grayColor,
width: 1.0,
),
),
),
child: _buildButton(
"Confirm", ColorsManager.onSecondaryColor, () {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
elevation: 10,
backgroundColor: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 30, horizontal: 50),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CustomLoadingIndicator(),
const SizedBox(height: 20),
const Text(
"Linking in progress",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
],
),
),
);
},
).then(
(value) {},
);
Future.delayed(const Duration(seconds: 3), () {
Navigator.of(context).pop();
Navigator.of(context).pop();
// showDialog(
// context: context,
// builder: (BuildContext dialogContext) {
// return const LinkingSuccessful();
// },
// );
showDialog(
context: context,
builder: (BuildContext dialogContext) {
return const ConfirmOverwriteDialog();
},
);
});
}),
),
),
],
),
],
@ -176,14 +213,10 @@ class LinkSpaceModelSpacesDialog extends StatelessWidget {
Widget _buildButton(String text, Color color, VoidCallback onPressed) {
return TextButton(
onPressed: onPressed,
style: TextButton.styleFrom(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
backgroundColor: color.withOpacity(0.2),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
child: Text(
text,
style: TextStyle(color: color, fontWeight: FontWeight.bold),
style:
TextStyle(color: color, fontWeight: FontWeight.w400, fontSize: 14),
),
);
}

View File

@ -67,7 +67,6 @@ class LinkingAttentionDialog extends StatelessWidget {
.textTheme
.bodyMedium
?.copyWith(fontWeight: FontWeight.w400, fontSize: 16),
),
),
),

View File

@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
class LinkingSuccessful extends StatelessWidget {
const LinkingSuccessful({super.key});
@override
Widget build(BuildContext context) {
return AlertDialog(
backgroundColor: ColorsManager.whiteColors,
title: Center(
child: SvgPicture.asset(
Assets.successIcon,
)),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Linking successful',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(fontWeight: FontWeight.w400, fontSize: 18),
),
const SizedBox(height: 25),
],
),
);
}
}

View File

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
void showOverwriteDialog(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false, // Prevent closing by tapping outside
barrierDismissible: false,
builder: (BuildContext context) {
return Container(
child: Dialog(
@ -19,7 +19,7 @@ void showOverwriteDialog(BuildContext context) {
mainAxisSize: MainAxisSize.min,
children: [
// Title
Text(
const Text(
"Overwrite",
style: TextStyle(
fontSize: 22,
@ -30,7 +30,7 @@ void showOverwriteDialog(BuildContext context) {
SizedBox(height: 15),
// Description
Text(
const Text(
"Are you sure you want to overwrite?",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
textAlign: TextAlign.center,

View File

@ -281,7 +281,6 @@ class CommunitySpaceManagementApi {
.replaceAll('{communityId}', communityId)
.replaceAll('{projectId}', TempConst.projectId),
expectedResponseModel: (json) {
print('json space=$json');
final spaceModels = (json['data'] as List)
.map((spaceJson) => SpaceModel.fromJson(spaceJson))
.toList();

View File

@ -405,5 +405,6 @@ class Assets {
static const String deleteSpaceLinkIcon =
'assets/icons/delete_space_link_icon.svg';
static const String spaceLinkIcon = 'assets/icons/space_link_icon.svg';
static const String successIcon = 'assets/icons/success_icon.svg';
}
//space_link_icon.svg