import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; import '../theme.dart'; class SkeletonBox extends StatelessWidget { final double? width; final double height; final double radius; const SkeletonBox({ super.key, this.width, required this.height, this.radius = 6, }); @override Widget build(BuildContext context) { return Container( width: width, height: height, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(radius), ), ); } } class SkeletonShimmer extends StatelessWidget { final Widget child; const SkeletonShimmer({super.key, required this.child}); @override Widget build(BuildContext context) { final base = AppColors.isDark ? const Color(0xFF334155) : const Color(0xFFE2E8F0); final highlight = AppColors.isDark ? const Color(0xFF475569) : const Color(0xFFF1F5F9); return Shimmer.fromColors( baseColor: base, highlightColor: highlight, period: const Duration(milliseconds: 1400), child: child, ); } } class EventCardSkeleton extends StatelessWidget { const EventCardSkeleton({super.key}); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 12), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.03), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: SkeletonShimmer( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SkeletonBox(width: 44, height: 44, radius: 12), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: const [ Expanded(child: SkeletonBox(height: 16, radius: 6)), SizedBox(width: 8), SkeletonBox(width: 48, height: 18, radius: 10), ], ), const SizedBox(height: 10), const SkeletonBox(height: 12, radius: 4), const SizedBox(height: 6), const SkeletonBox(width: 180, height: 12, radius: 4), ], ), ), ], ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: const [ SkeletonBox(width: 160, height: 12, radius: 4), ], ), ), ], ), ), ); } } class WorkOrderCardSkeleton extends StatelessWidget { const WorkOrderCardSkeleton({super.key}); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.03), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: SkeletonShimmer( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: const [ Expanded(child: SkeletonBox(height: 16, radius: 6)), SizedBox(width: 8), SkeletonBox(width: 56, height: 18, radius: 10), ], ), const SizedBox(height: 12), const SkeletonBox(height: 12, radius: 4), const SizedBox(height: 6), const SkeletonBox(width: 220, height: 12, radius: 4), const SizedBox(height: 14), Row( children: const [ SkeletonBox(width: 80, height: 12, radius: 4), SizedBox(width: 12), SkeletonBox(width: 100, height: 12, radius: 4), Spacer(), SkeletonBox(width: 36, height: 16, radius: 4), ], ), ], ), ), ); } } class OrderCardSkeleton extends StatelessWidget { const OrderCardSkeleton({super.key}); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.03), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: SkeletonShimmer( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: const [ SkeletonBox(width: 140, height: 14, radius: 4), Spacer(), SkeletonBox(width: 56, height: 18, radius: 10), ], ), const SizedBox(height: 14), const SkeletonBox(height: 15, width: 200, radius: 4), const SizedBox(height: 10), Row( children: const [ SkeletonBox(width: 90, height: 12, radius: 4), SizedBox(width: 16), SkeletonBox(width: 50, height: 12, radius: 4), ], ), const SizedBox(height: 14), Row( children: const [ SkeletonBox(width: 100, height: 12, radius: 4), Spacer(), SkeletonBox(width: 70, height: 16, radius: 4), ], ), ], ), ), ); } } class DetailPageSkeleton extends StatelessWidget { const DetailPageSkeleton({super.key}); @override Widget build(BuildContext context) { return SkeletonShimmer( child: SingleChildScrollView( padding: const EdgeInsets.all(20), physics: const NeverScrollableScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: const [ SkeletonBox(width: 100, height: 14, radius: 4), SizedBox(height: 12), SkeletonBox(height: 22, radius: 6), SizedBox(height: 10), SkeletonBox(width: 220, height: 14, radius: 4), ], ), ), const SizedBox(height: 20), _block(height: 130), const SizedBox(height: 20), _block(height: 130), const SizedBox(height: 20), _block(height: 100), ], ), ), ); } Widget _block({required double height}) { return Container( width: double.infinity, height: height, decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), ), child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: const [ SkeletonBox(width: 80, height: 14, radius: 4), SizedBox(height: 14), SkeletonBox(height: 14, radius: 4), SizedBox(height: 8), SkeletonBox(width: 200, height: 14, radius: 4), ], ), ), ); } } class SkeletonList extends StatelessWidget { final WidgetBuilder itemBuilder; final int count; final EdgeInsetsGeometry padding; const SkeletonList({ super.key, required this.itemBuilder, this.count = 5, this.padding = const EdgeInsets.all(16), }); @override Widget build(BuildContext context) { return ListView.builder( padding: padding, itemCount: count, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, _) => itemBuilder(context), ); } }