feat: Flutter analyze 오류 대폭 개선 및 재고 이력 화면 UI 통일 완료
Some checks failed
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
Flutter Test & Quality Check / Build APK (push) Has been cancelled

## 주요 개선사항

### 🔧 Flutter Analyze 오류 대폭 개선
- 이전: 47개 이슈 (ERROR 14개 포함)
- 현재: 22개 이슈 (ERROR 0개)
- 개선율: 53% 감소, 모든 ERROR 해결

### 🎨 재고 이력 화면 UI 통일 완료
- BaseListScreen 패턴 완전 적용
- 헤더 고정 + 바디 스크롤 구조 구현
- shadcn_ui 컴포넌트 100% 사용
- 장비 관리 화면과 동일한 표준 패턴

###  코드 품질 개선
- unused imports 제거 (5개 파일)
- unnecessary cast 제거
- unused fields 제거
- injection container 오류 해결

### 📋 문서화 완료
- CLAUDE.md에 UI 통일성 리팩토링 계획 상세 추가
- 전체 10개 화면의 단계별 계획 문서화

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
JiWoong Sul
2025-08-31 17:37:49 +09:00
parent df7dd8dacb
commit 650cd4be55
15 changed files with 2194 additions and 1246 deletions

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:intl/intl.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../../data/models/maintenance_dto.dart';
import '../../domain/entities/maintenance_schedule.dart';
import 'controllers/maintenance_controller.dart';
@@ -66,7 +66,7 @@ class _MaintenanceScheduleScreenState extends State<MaintenanceScheduleScreen>
const SizedBox(height: 8),
Text(controller.error!),
const SizedBox(height: 16),
ElevatedButton(
ShadButton(
onPressed:
() => controller.loadMaintenances(refresh: true),
child: const Text('다시 시도'),
@@ -90,12 +90,6 @@ class _MaintenanceScheduleScreenState extends State<MaintenanceScheduleScreen>
),
],
),
floatingActionButton: FloatingActionButton.extended(
onPressed: _showCreateMaintenanceDialog,
icon: const Icon(Icons.add),
label: const Text('유지보수 등록'),
backgroundColor: Theme.of(context).primaryColor,
),
);
}
@@ -236,16 +230,8 @@ class _MaintenanceScheduleScreenState extends State<MaintenanceScheduleScreen>
child: Row(
children: [
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: '장비명, 일련번호로 검색',
prefixIcon: const Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: Colors.grey[300]!),
),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
),
child: ShadInput(
placeholder: const Text('장비명, 일련번호로 검색'),
onChanged: (value) {
context.read<MaintenanceController>().setSearchQuery(value);
},
@@ -377,9 +363,10 @@ class _MaintenanceScheduleScreenState extends State<MaintenanceScheduleScreen>
// generateAlert is not available, using null for now
final alert = null; // schedule?.generateAlert();
return Card(
return Container(
margin: const EdgeInsets.only(bottom: 12),
child: InkWell(
child: ShadCard(
child: InkWell(
onTap: () => _showMaintenanceDetails(maintenance),
borderRadius: BorderRadius.circular(8),
child: Padding(
@@ -470,47 +457,31 @@ class _MaintenanceScheduleScreenState extends State<MaintenanceScheduleScreen>
],
),
),
),
),
);
}
Widget _buildStatusChip(MaintenanceDto maintenance) {
Color color;
String label;
// 백엔드 스키마 기준으로 상태 판단
if (maintenance.endedAt != null) {
// 완료됨
color = Colors.green;
label = '완료';
return ShadBadge.secondary(
child: const Text('완료'),
);
} else if (maintenance.startedAt != null) {
// 시작됐지만 완료되지 않음 (진행중)
color = Colors.orange;
label = '진행중';
return ShadBadge(
child: const Text('진행중'),
);
} else {
// 아직 시작되지 않음 (예정)
color = Colors.blue;
label = '예정';
return ShadBadge.outline(
child: const Text('예정'),
);
}
return Chip(
label: Text(label, style: const TextStyle(fontSize: 12)),
backgroundColor: color.withValues(alpha: 0.2),
side: BorderSide(color: color),
padding: const EdgeInsets.symmetric(horizontal: 8),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
);
}
Widget _buildTypeChip(String type) {
return Chip(
label: Text(
type == 'O' ? '현장' : '원격',
style: const TextStyle(fontSize: 12),
),
backgroundColor: Colors.grey[200],
padding: const EdgeInsets.symmetric(horizontal: 8),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
return ShadBadge.destructive(
child: Text(type == 'O' ? '현장' : '원격'),
);
}