- Implemented ContactProfileResponse and related models for handling contact details. - Created ContactTagResponse and ContactTag models for managing contact tags. - Added DirectoryCommentResponse and DirectoryComment models for comment management. - Developed DirectoryFilterBottomSheet for filtering contacts. - Introduced OrganizationListModel for organization data handling. - Updated routes to include DirectoryMainScreen. - Enhanced DashboardScreen to navigate to the new directory page. - Created ContactDetailScreen for displaying detailed contact information. - Developed DirectoryMainScreen for managing and displaying contacts. - Added dependencies for font_awesome_flutter and flutter_html in pubspec.yaml.
163 lines
4.2 KiB
Dart
163 lines
4.2 KiB
Dart
import 'dart:ui';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
|
import 'package:marco/images.dart';
|
|
import 'package:marco/helpers/widgets/my_card.dart';
|
|
import 'package:marco/helpers/widgets/my_spacing.dart';
|
|
import 'package:marco/helpers/utils/my_shadow.dart';
|
|
class LoadingComponent extends StatelessWidget {
|
|
final bool isLoading;
|
|
final Widget child;
|
|
final Color overlayColor;
|
|
final double overlayOpacity;
|
|
final double imageSize;
|
|
final bool showDots;
|
|
final String loadingText;
|
|
|
|
const LoadingComponent({
|
|
Key? key,
|
|
required this.isLoading,
|
|
required this.child,
|
|
this.overlayColor = Colors.black,
|
|
this.overlayOpacity = 0.2,
|
|
this.imageSize = 100,
|
|
this.showDots = true,
|
|
this.loadingText = 'Loading...',
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Stack(
|
|
children: [
|
|
child,
|
|
if (isLoading) _buildLoadingOverlay(),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildLoadingOverlay() {
|
|
return Positioned.fill(
|
|
child: Semantics(
|
|
label: 'Loading...',
|
|
child: Stack(
|
|
children: [
|
|
BackdropFilter(
|
|
filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
|
|
child: Container(
|
|
color: overlayColor.withOpacity(overlayOpacity),
|
|
),
|
|
),
|
|
Center(
|
|
child: _LoadingAnimation(
|
|
imageSize: imageSize,
|
|
showDots: showDots,
|
|
loadingText: loadingText,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
Widget contactSkeletonCard() {
|
|
return MyCard.bordered(
|
|
margin: MySpacing.only(bottom: 12),
|
|
paddingAll: 16,
|
|
borderRadiusAll: 16,
|
|
shadow: MyShadow(
|
|
elevation: 1.5,
|
|
position: MyShadowPosition.bottom,
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Container(
|
|
height: 40,
|
|
width: 40,
|
|
decoration: BoxDecoration(
|
|
color: Colors.grey.shade300,
|
|
shape: BoxShape.circle,
|
|
),
|
|
),
|
|
MySpacing.width(12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
height: 12,
|
|
width: 100,
|
|
color: Colors.grey.shade300,
|
|
),
|
|
MySpacing.height(6),
|
|
Container(
|
|
height: 10,
|
|
width: 60,
|
|
color: Colors.grey.shade300,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
MySpacing.height(16),
|
|
Container(height: 10, width: 150, color: Colors.grey.shade300),
|
|
MySpacing.height(8),
|
|
Container(height: 10, width: 100, color: Colors.grey.shade300),
|
|
MySpacing.height(8),
|
|
Container(height: 10, width: 120, color: Colors.grey.shade300),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
class _LoadingAnimation extends StatelessWidget {
|
|
final double imageSize;
|
|
final bool showDots;
|
|
final String loadingText;
|
|
|
|
const _LoadingAnimation({
|
|
Key? key,
|
|
required this.imageSize,
|
|
required this.showDots,
|
|
required this.loadingText,
|
|
}) : super(key: key);
|
|
|
|
static const _textStyle = TextStyle(
|
|
fontSize: 12,
|
|
color: Colors.white,
|
|
);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Image.asset(
|
|
Images.loadingLogo,
|
|
height: imageSize,
|
|
width: imageSize,
|
|
fit: BoxFit.contain,
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
loadingText,
|
|
style: _textStyle,
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 4),
|
|
if (showDots)
|
|
LoadingAnimationWidget.waveDots(
|
|
color: const Color(0xFFEF0000),
|
|
size: 50,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|