import 'package:flutter/material.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 SkeletonLoaders { static Widget buildLoadingSkeleton() { return SizedBox( height: 360, child: Column( children: List.generate(5, (index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: List.generate(6, (i) { return Container( margin: const EdgeInsets.symmetric(horizontal: 4), width: 48, height: 16, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ); }), ), ), ); }), ), ); } // Date Skeleton Loader static Widget dateSkeletonLoader() { return Container( height: 14, width: 90, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ); } // Chart Skeleton Loader static Widget chartSkeletonLoader() { 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: [ // Chart Title Placeholder Container( height: 14, width: 120, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ), MySpacing.height(20), // Chart Bars (variable height for realism) SizedBox( height: 180, child: Row( crossAxisAlignment: CrossAxisAlignment.end, children: List.generate(6, (index) { return Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: Container( height: (60 + (index * 20)).toDouble(), // fake chart shape decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ), ), ); }), ), ), MySpacing.height(16), // X-Axis Labels Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: List.generate(6, (index) { return Container( height: 10, width: 30, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(4), ), ); }), ), ], ), ); } // Document List Skeleton Loader static Widget documentSkeletonLoader() { return Column( children: List.generate(5, (index) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Date placeholder Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), child: Container( height: 12, width: 80, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ), ), // Document Card Skeleton Container( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Icon Placeholder Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(8), ), child: const Icon(Icons.description, color: Colors.transparent), // invisible icon ), const SizedBox(width: 12), // Text placeholders Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 12, width: 80, color: Colors.grey.shade300, ), MySpacing.height(6), Container( height: 14, width: double.infinity, color: Colors.grey.shade300, ), MySpacing.height(6), Container( height: 12, width: 100, color: Colors.grey.shade300, ), ], ), ), // Action icon placeholder Container( width: 20, height: 20, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), ], ), ), ], ); }), ); } // Document Details Card Skeleton Loader static Widget documentDetailsSkeletonLoader() { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Details Card Container( constraints: const BoxConstraints(maxWidth: 460), padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.06), blurRadius: 16, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Row( children: [ Container( width: 56, height: 56, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 16, width: 180, color: Colors.grey.shade300, ), const SizedBox(height: 8), Container( height: 12, width: 120, color: Colors.grey.shade300, ), ], ), ), ], ), const SizedBox(height: 12), // Tags placeholder Wrap( spacing: 6, runSpacing: 6, children: List.generate(3, (index) { return Container( height: 20, width: 60, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(12), ), ); }), ), const SizedBox(height: 16), // Info rows placeholders Column( children: List.generate(10, (index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Row( children: [ Container( height: 12, width: 120, color: Colors.grey.shade300, ), const SizedBox(width: 12), Expanded( child: Container( height: 12, color: Colors.grey.shade300, ), ), ], ), ); }), ), ], ), ), const SizedBox(height: 20), // Versions section skeleton Container( margin: const EdgeInsets.symmetric(horizontal: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: List.generate(3, (index) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Row( children: [ Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(8), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 12, width: 180, color: Colors.grey.shade300, ), const SizedBox(height: 6), Container( height: 10, width: 120, color: Colors.grey.shade300, ), ], ), ), Container( width: 24, height: 24, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), ], ), ); }), ), ), ], ), ); } // Employee List - Card Style static Widget employeeListSkeletonLoader() { return Column( children: List.generate(4, (index) { return MyCard.bordered( borderRadiusAll: 12, paddingAll: 10, margin: MySpacing.bottom(12), shadow: MyShadow(elevation: 3), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Avatar Container( width: 41, height: 41, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), MySpacing.width(16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( height: 14, width: 100, color: Colors.grey.shade300), MySpacing.width(8), Container( height: 12, width: 60, color: Colors.grey.shade300), ], ), MySpacing.height(8), Row( children: [ Icon(Icons.email, size: 16, color: Colors.grey.shade300), MySpacing.width(4), Container( height: 10, width: 140, color: Colors.grey.shade300), ], ), MySpacing.height(8), Row( children: [ Icon(Icons.phone, size: 16, color: Colors.grey.shade300), MySpacing.width(4), Container( height: 10, width: 100, color: Colors.grey.shade300), ], ), ], ), ), ], ), ); }), ); } // Employee List - Compact Collapsed Style static Widget employeeListCollapsedSkeletonLoader() { return MyCard.bordered( borderRadiusAll: 4, paddingAll: 8, child: Column( children: List.generate(4, (index) { return Column( children: [ Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( children: [ // Avatar Container( width: 31, height: 31, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), MySpacing.width(16), // Name, Designation & Buttons Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 12, width: 100, color: Colors.grey.shade300), MySpacing.height(8), Container( height: 10, width: 80, color: Colors.grey.shade300), MySpacing.height(12), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( height: 28, width: 60, color: Colors.grey.shade300), MySpacing.width(8), Container( height: 28, width: 60, color: Colors.grey.shade300), ], ), ], ), ), ], ), ), if (index != 3) Divider( color: Colors.grey.withOpacity(0.3), thickness: 1, height: 1, ), ], ); }), ), ); } // Daily Progress Report Header Loader static Widget dailyProgressReportSkeletonLoader() { return MyCard.bordered( borderRadiusAll: 4, border: Border.all(color: Colors.grey.withOpacity(0.2)), shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom), paddingAll: 8, child: Column( children: List.generate(3, (index) { return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( height: 14, width: 120, color: Colors.grey.shade300), Icon(Icons.add_circle, color: Colors.grey.shade300), ], ), if (index != 2) ...[ MySpacing.height(12), Divider(color: Colors.grey.withOpacity(0.3), thickness: 1), MySpacing.height(12), ], ], ); }), ), ); } // Daily Progress Planning (Collapsed View) static Widget dailyProgressPlanningSkeletonCollapsedOnly() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: List.generate(3, (index) { return MyCard.bordered( borderRadiusAll: 12, paddingAll: 16, margin: MySpacing.bottom(12), shadow: MyShadow(elevation: 3), child: Row( children: [ // Icon placeholder Container( width: 40, height: 40, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), MySpacing.width(12), // Text line Expanded( child: Container(height: 16, color: Colors.grey.shade300), ), MySpacing.width(12), // Expand button placeholder Container( width: 28, height: 28, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.grey.shade300, ), ), ], ), ); }), ); } static Widget expenseListSkeletonLoader() { return ListView.separated( padding: const EdgeInsets.fromLTRB(12, 12, 12, 80), itemCount: 6, // Show 6 skeleton items separatorBuilder: (_, __) => Divider(color: Colors.grey.shade300, height: 20), itemBuilder: (context, index) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Title and Amount Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( height: 14, width: 120, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ), Container( height: 14, width: 80, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ), ], ), const SizedBox(height: 6), // Date and Status Row( children: [ Container( height: 12, width: 100, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ), const Spacer(), Container( height: 12, width: 50, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(6), ), ), ], ), ], ); }, ); } static Widget employeeSkeletonCard() { return MyCard.bordered( margin: MySpacing.only(bottom: 12), paddingAll: 12, borderRadiusAll: 12, shadow: MyShadow( elevation: 1.5, position: MyShadowPosition.bottom, ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Avatar Container( height: 35, width: 35, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), MySpacing.width(12), // Name, org, email, phone Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container(height: 12, width: 120, color: Colors.grey.shade300), MySpacing.height(6), Container(height: 10, width: 80, color: Colors.grey.shade300), MySpacing.height(8), // Email placeholder Row( children: [ Icon(Icons.email_outlined, size: 14, color: Colors.grey.shade300), MySpacing.width(4), Container( height: 10, width: 140, color: Colors.grey.shade300), ], ), MySpacing.height(8), // Phone placeholder Row( children: [ Icon(Icons.phone_outlined, size: 14, color: Colors.grey.shade300), MySpacing.width(4), Container( height: 10, width: 100, color: Colors.grey.shade300), MySpacing.width(8), Container( height: 16, width: 16, decoration: BoxDecoration( color: Colors.grey.shade300, shape: BoxShape.circle, ), ), ], ), MySpacing.height(8), // Tags placeholder Container(height: 8, width: 80, color: Colors.grey.shade300), ], ), ), // Arrow Icon(Icons.arrow_forward_ios, size: 14, color: Colors.grey.shade300), ], ), ); } static 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), ], ), ); } }