import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import 'controllers/equipment_history_controller.dart'; class InventoryDashboard extends StatefulWidget { const InventoryDashboard({super.key}); @override State createState() => _InventoryDashboardState(); } class _InventoryDashboardState extends State { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { final controller = context.read(); controller.loadStockStatus(); // 재고 현황 로드 }); } @override Widget build(BuildContext context) { final theme = ShadTheme.of(context); return Scaffold( backgroundColor: theme.colorScheme.background, body: Consumer( builder: (context, controller, child) { if (controller.isLoading) { return const Center( child: CircularProgressIndicator(), ); } return SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 헤더 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '재고 대시보드', style: theme.textTheme.h2, ), const SizedBox(height: 4), Text( '실시간 재고 현황 및 경고 알림', style: theme.textTheme.muted, ), ], ), Row( children: [ ShadButton.outline( child: const Row( children: [ Icon(Icons.refresh, size: 16), SizedBox(width: 8), Text('새로고침'), ], ), onPressed: () { controller.loadStockStatus(); controller.loadHistories(); }, ), const SizedBox(width: 8), ShadButton( child: const Row( children: [ Icon(Icons.download, size: 16), SizedBox(width: 8), Text('보고서 다운로드'), ], ), onPressed: () { // 보고서 다운로드 기능 }, ), ], ), ], ), const SizedBox(height: 24), // 통계 카드 GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: MediaQuery.of(context).size.width > 1200 ? 4 : 2, mainAxisSpacing: 16, crossAxisSpacing: 16, childAspectRatio: 1.5, children: [ _buildStatCard( theme, title: '총 입고', value: '${controller.getStockSummary()['totalIn']}', unit: '개', icon: Icons.input, color: Colors.green, ), _buildStatCard( theme, title: '총 출고', value: '${controller.getStockSummary()['totalOut']}', unit: '개', icon: Icons.output, color: Colors.red, ), _buildStatCard( theme, title: '현재 재고', value: '${controller.getStockSummary()['totalStock']}', unit: '개', icon: Icons.inventory_2, color: theme.colorScheme.primary, ), _buildStatCard( theme, title: '총 거래', value: '${controller.histories.length}', unit: '건', icon: Icons.history, color: Colors.blue, ), ], ), const SizedBox(height: 32), // 최근 거래 이력 (백엔드 스키마 기반) Text( '최근 거래 이력', style: theme.textTheme.h3, ), const SizedBox(height: 16), ShadCard( child: Padding( padding: const EdgeInsets.all(16), child: controller.histories.isEmpty ? const Center( child: Text('거래 이력이 없습니다.'), ) : Column( children: controller.histories.take(10).map((history) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ Expanded( flex: 2, child: Text( DateFormat('MM/dd HH:mm').format(history.transactedAt), style: theme.textTheme.small, ), ), Expanded( flex: 1, child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: history.transactionType == 'I' ? Colors.green : Colors.red, borderRadius: BorderRadius.circular(4), ), child: Text( history.transactionType == 'I' ? '입고' : '출고', style: const TextStyle(color: Colors.white, fontSize: 12), textAlign: TextAlign.center, ), ), ), Expanded( flex: 1, child: Text( '${history.quantity}개', style: theme.textTheme.small, textAlign: TextAlign.right, ), ), Expanded( flex: 2, child: Text( history.remark ?? '-', style: theme.textTheme.small, textAlign: TextAlign.right, overflow: TextOverflow.ellipsis, ), ), ], ), ); }).toList(), ), ), ), const SizedBox(height: 24), ], ), ); }, ), ); } Widget _buildStatCard( ShadThemeData theme, { required String title, required String value, required String unit, required IconData icon, required Color color, }) { return ShadCard( child: Padding( padding: const EdgeInsets.all(16), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Icon(icon, color: color, size: 24), Text( unit, style: theme.textTheme.muted, ), ], ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( value, style: theme.textTheme.h2, ), Text( title, style: theme.textTheme.small.copyWith( color: theme.colorScheme.mutedForeground, ), ), ], ), ], ), ), ); } }