- 입고/출고/대여 상태·대여구분 드롭다운에 제네릭 타입을 명시해 null 허용 옵션에서도 SDK 경고를 제거\n- 입고 목록 include 라벨에 customers→'고객 포함'을 추가해 UI 설명을 통일\n- WarehouseSelectField가 선택된 라벨과 동일한 검색어일 때 전체 옵션을 복원하고 suggestions를 초기화하도록 로직을 보강\n- FilterBar의 필터 적용 배지를 윤곽 스타일로 교체하고 테마 색상 대비를 조정\n- DatePicker 버튼을 outline 버튼 자체에서 정렬/아이콘 슬롯으로 구성해 긴 날짜 라벨이 잘리지 않도록 개선\n- 필터 배지/날짜 버튼 UI 변경에 맞춰 인벤토리 요약 골든 이미지를 갱신\n- flutter analyze, flutter test로 회귀를 검증
136 lines
4.1 KiB
Dart
136 lines
4.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:intl/intl.dart' as intl;
|
|
import 'package:lucide_icons_flutter/lucide_icons.dart' as lucide;
|
|
import 'package:shadcn_ui/shadcn_ui.dart';
|
|
|
|
/// 단일 날짜 선택을 위한 공통 버튼 위젯.
|
|
class SuperportDatePickerButton extends StatelessWidget {
|
|
const SuperportDatePickerButton({
|
|
super.key,
|
|
required this.value,
|
|
required this.onChanged,
|
|
this.firstDate,
|
|
this.lastDate,
|
|
this.dateFormat,
|
|
this.placeholder = '날짜 선택',
|
|
this.enabled = true,
|
|
this.initialDate,
|
|
});
|
|
|
|
final DateTime? value;
|
|
final ValueChanged<DateTime> onChanged;
|
|
final DateTime? firstDate;
|
|
final DateTime? lastDate;
|
|
final intl.DateFormat? dateFormat;
|
|
final String placeholder;
|
|
final bool enabled;
|
|
final DateTime? initialDate;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final format = dateFormat ?? intl.DateFormat('yyyy-MM-dd');
|
|
final displayText = value != null ? format.format(value!) : placeholder;
|
|
return ShadButton.outline(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
gap: 8,
|
|
onPressed: !enabled
|
|
? null
|
|
: () async {
|
|
final now = DateTime.now();
|
|
final baseFirst = firstDate ?? DateTime(now.year - 10);
|
|
final baseLast = lastDate ?? DateTime(now.year + 5);
|
|
final seed = value ?? initialDate ?? now;
|
|
final adjustedInitial = seed.clamp(baseFirst, baseLast);
|
|
final picked = await showDatePicker(
|
|
context: context,
|
|
initialDate: adjustedInitial,
|
|
firstDate: baseFirst,
|
|
lastDate: baseLast,
|
|
);
|
|
if (picked != null) {
|
|
onChanged(picked);
|
|
}
|
|
},
|
|
trailing: const Icon(lucide.LucideIcons.calendar, size: 16),
|
|
child: Text(
|
|
displayText,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
softWrap: false,
|
|
textAlign: TextAlign.left,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 날짜 범위 선택을 위한 공통 버튼 위젯.
|
|
class SuperportDateRangePickerButton extends StatelessWidget {
|
|
const SuperportDateRangePickerButton({
|
|
super.key,
|
|
required this.value,
|
|
required this.onChanged,
|
|
this.firstDate,
|
|
this.lastDate,
|
|
this.dateFormat,
|
|
this.placeholder = '기간 선택',
|
|
this.enabled = true,
|
|
this.initialDateRange,
|
|
});
|
|
|
|
final DateTimeRange? value;
|
|
final ValueChanged<DateTimeRange?> onChanged;
|
|
final DateTime? firstDate;
|
|
final DateTime? lastDate;
|
|
final intl.DateFormat? dateFormat;
|
|
final String placeholder;
|
|
final bool enabled;
|
|
final DateTimeRange? initialDateRange;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final format = dateFormat ?? intl.DateFormat('yyyy-MM-dd');
|
|
final label = value == null
|
|
? placeholder
|
|
: '${format.format(value!.start)} ~ ${format.format(value!.end)}';
|
|
return ShadButton.outline(
|
|
gap: 8,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
onPressed: !enabled
|
|
? null
|
|
: () async {
|
|
final now = DateTime.now();
|
|
final baseFirst = firstDate ?? DateTime(now.year - 10);
|
|
final baseLast = lastDate ?? DateTime(now.year + 5);
|
|
final initialRange = value ?? initialDateRange;
|
|
final currentDate = initialRange?.start ?? now;
|
|
final picked = await showDateRangePicker(
|
|
context: context,
|
|
firstDate: baseFirst,
|
|
lastDate: baseLast,
|
|
initialDateRange: initialRange,
|
|
currentDate: currentDate.clamp(baseFirst, baseLast),
|
|
);
|
|
if (picked != null) {
|
|
onChanged(picked);
|
|
}
|
|
},
|
|
leading: const Icon(lucide.LucideIcons.calendar, size: 16),
|
|
child: Text(
|
|
label,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
softWrap: false,
|
|
textAlign: TextAlign.left,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
extension _ClampDate on DateTime {
|
|
DateTime clamp(DateTime min, DateTime max) {
|
|
if (isBefore(min)) return min;
|
|
if (isAfter(max)) return max;
|
|
return this;
|
|
}
|
|
}
|