사용하지 않는 파일 정리 전 백업 (Phase 10 완료 후 상태)

This commit is contained in:
JiWoong Sul
2025-08-29 15:11:59 +09:00
parent a740ff10c8
commit d916b281a7
333 changed files with 53617 additions and 22574 deletions

View File

@@ -4,14 +4,27 @@ import 'package:provider/provider.dart';
import 'package:superport/screens/common/theme_shadcn.dart';
import 'package:superport/screens/common/components/shadcn_components.dart';
import 'package:superport/screens/overview/overview_screen.dart';
import 'package:superport/screens/vendor/vendor_list_screen.dart';
import 'package:superport/screens/vendor/controllers/vendor_controller.dart';
import 'package:superport/screens/model/model_list_screen.dart';
import 'package:superport/screens/zipcode/zipcode_search_screen.dart';
import 'package:superport/screens/zipcode/controllers/zipcode_controller.dart';
import 'package:superport/screens/equipment/equipment_list.dart';
import 'package:superport/screens/company/company_list.dart';
import 'package:superport/screens/user/user_list.dart';
import 'package:superport/screens/license/license_list.dart';
import 'package:superport/screens/warehouse_location/warehouse_location_list.dart';
import 'package:superport/screens/inventory/inventory_history_screen.dart';
import 'package:superport/screens/inventory/inventory_dashboard.dart';
import 'package:superport/screens/maintenance/maintenance_schedule_screen.dart';
import 'package:superport/screens/maintenance/maintenance_alert_dashboard.dart';
import 'package:superport/screens/maintenance/maintenance_history_screen.dart' as maint;
import 'package:superport/screens/maintenance/controllers/maintenance_controller.dart';
import 'package:superport/screens/rent/rent_list_screen.dart';
import 'package:superport/screens/rent/rent_dashboard.dart';
import 'package:superport/screens/rent/controllers/rent_controller.dart';
import 'package:superport/services/auth_service.dart';
import 'package:superport/services/dashboard_service.dart';
import 'package:superport/core/services/lookups_service.dart';
import 'package:superport/injection_container.dart' as di;
import 'package:superport/utils/constants.dart';
import 'package:superport/data/models/auth/auth_user.dart';
@@ -21,8 +34,7 @@ import 'package:superport/data/models/auth/auth_user.dart';
class AppLayout extends StatefulWidget {
final String initialRoute;
const AppLayout({Key? key, this.initialRoute = Routes.home})
: super(key: key);
const AppLayout({super.key, this.initialRoute = Routes.home});
@override
State<AppLayout> createState() => _AppLayoutState();
@@ -35,10 +47,9 @@ class _AppLayoutState extends State<AppLayout>
late AnimationController _sidebarAnimationController;
AuthUser? _currentUser;
late final AuthService _authService;
late final DashboardService _dashboardService;
late final LookupsService _lookupsService;
late Animation<double> _sidebarAnimation;
int _expiringLicenseCount = 0; // 7일 내 만료 예정 라이선스
int _expiringMaintenanceCount = 0; // 30일 내 만료 예정 유지보수
// 레이아웃 상수 (1920x1080 최적화)
static const double _sidebarExpandedWidth = 260.0;
@@ -52,10 +63,9 @@ class _AppLayoutState extends State<AppLayout>
_currentRoute = widget.initialRoute;
_setupAnimations();
_authService = GetIt.instance<AuthService>();
_dashboardService = GetIt.instance<DashboardService>();
_lookupsService = GetIt.instance<LookupsService>();
_loadCurrentUser();
_loadLicenseExpirySummary();
_loadMaintenanceAlerts();
_initializeLookupData(); // Lookup 데이터 초기화
}
@@ -68,34 +78,19 @@ class _AppLayoutState extends State<AppLayout>
}
}
Future<void> _loadLicenseExpirySummary() async {
Future<void> _loadMaintenanceAlerts() async {
try {
print('[DEBUG] 라이선스 만료 정보 로드 시작...');
final result = await _dashboardService.getLicenseExpirySummary();
result.fold(
(failure) {
// 실패 시 0으로 유지
print('[ERROR] 라이선스 만료 정보 로드 실패: $failure');
},
(summary) {
print('[DEBUG] 라이선스 만료 정보 로드 성공!');
print('[DEBUG] 7일 내 만료: ${summary.expiring7Days}');
print('[DEBUG] 30일 내 만료: ${summary.expiring30Days}');
print('[DEBUG] 90일 내 만료: ${summary.expiring90Days}');
print('[DEBUG] 이미 만료: ${summary.expired}');
if (mounted) {
setState(() {
// 30일 내 만료 수를 표시 (7일 내 만료가 포함됨)
// expiring_30_days는 30일 이내의 모든 라이선스를 포함
_expiringLicenseCount = summary.expiring30Days;
print('[DEBUG] 상태 업데이트 완료: $_expiringLicenseCount (30일 내 만료)');
});
}
},
);
print('[DEBUG] 유지보수 알림 정보 로드 시작...');
// TODO: MaintenanceController를 통해 알림 정보 로드
// 현재는 임시로 0으로 설정
if (mounted) {
setState(() {
_expiringMaintenanceCount = 0;
print('[DEBUG] 유지보수 알림 상태 업데이트 완료: $_expiringMaintenanceCount');
});
}
} catch (e) {
print('[ERROR] 라이선스 만료 정보 로드 중 예외 발생: $e');
print('[ERROR] 유지보수 알림 정보 로드 중 예외 발생: $e');
print('[ERROR] 스택 트레이스: ${StackTrace.current}');
}
}
@@ -155,6 +150,13 @@ class _AppLayoutState extends State<AppLayout>
switch (route) {
case Routes.home:
return const OverviewScreen();
case Routes.vendor:
return ChangeNotifierProvider(
create: (context) => di.sl<VendorController>(),
child: const VendorListScreen(),
);
case Routes.model:
return const ModelListScreen();
case Routes.equipment:
case Routes.equipmentInList:
case Routes.equipmentOutList:
@@ -164,10 +166,45 @@ class _AppLayoutState extends State<AppLayout>
return const CompanyList();
case Routes.user:
return const UserList();
case Routes.license:
return const LicenseList();
// License 시스템이 Maintenance로 대체됨
case Routes.maintenance:
case Routes.maintenanceSchedule:
return ChangeNotifierProvider(
create: (_) => GetIt.instance<MaintenanceController>(),
child: const MaintenanceScheduleScreen(),
);
case Routes.maintenanceAlert:
return ChangeNotifierProvider(
create: (_) => GetIt.instance<MaintenanceController>(),
child: const MaintenanceAlertDashboard(),
);
case Routes.maintenanceHistory:
return ChangeNotifierProvider(
create: (_) => GetIt.instance<MaintenanceController>(),
child: const maint.MaintenanceHistoryScreen(),
);
case Routes.warehouseLocation:
return const WarehouseLocationList();
case Routes.zipcode:
return ChangeNotifierProvider(
create: (context) => di.sl<ZipcodeController>(),
child: const ZipcodeSearchScreen(),
);
case Routes.inventory:
case Routes.inventoryHistory:
return const InventoryHistoryScreen();
case Routes.inventoryDashboard:
return const InventoryDashboard();
case Routes.rent:
return ChangeNotifierProvider(
create: (_) => GetIt.instance<RentController>(),
child: const RentListScreen(),
);
case Routes.rentDashboard:
return ChangeNotifierProvider(
create: (_) => GetIt.instance<RentController>(),
child: const RentDashboard(),
);
case '/test/api':
// Navigator를 사용하여 별도 화면으로 이동
WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -184,9 +221,9 @@ class _AppLayoutState extends State<AppLayout>
setState(() {
_currentRoute = route;
});
// 라이선스 화면으로 이동할 때 만료 정보 새로고침
if (route == Routes.license) {
_loadLicenseExpirySummary();
// 유지보수 화면으로 이동할 때 알림 정보 새로고침
if (route == Routes.maintenance || route == Routes.maintenanceAlert) {
_loadMaintenanceAlerts();
}
}
@@ -204,57 +241,7 @@ class _AppLayoutState extends State<AppLayout>
}
/// 현재 페이지 제목 가져오기
String _getPageTitle() {
switch (_currentRoute) {
case Routes.home:
return '대시보드';
case Routes.equipment:
case Routes.equipmentInList:
case Routes.equipmentOutList:
case Routes.equipmentRentList:
return '장비 관리';
case Routes.company:
return '회사 관리';
case Routes.user:
return '사용자 관리';
case Routes.license:
return '유지보수 관리';
case Routes.warehouseLocation:
return '입고지 관리';
case '/test/api':
return 'API 테스트';
default:
return '대시보드';
}
}
/// 브레드크럼 경로 가져오기
List<String> _getBreadcrumbs() {
switch (_currentRoute) {
case Routes.home:
return ['', '대시보드'];
case Routes.equipment:
return ['', '장비 관리', '전체'];
case Routes.equipmentInList:
return ['', '장비 관리', '입고'];
case Routes.equipmentOutList:
return ['', '장비 관리', '출고'];
case Routes.equipmentRentList:
return ['', '장비 관리', '대여'];
case Routes.company:
return ['', '회사 관리'];
case Routes.user:
return ['', '사용자 관리'];
case Routes.license:
return ['', '유지보수 관리'];
case Routes.warehouseLocation:
return ['', '입고지 관리'];
case '/test/api':
return ['', '개발자 도구', 'API 테스트'];
default:
return ['', '대시보드'];
}
}
@override
Widget build(BuildContext context) {
@@ -560,122 +547,12 @@ class _AppLayoutState extends State<AppLayout>
currentRoute: _currentRoute,
onRouteChanged: _navigateTo,
collapsed: _sidebarCollapsed,
expiringLicenseCount: _expiringLicenseCount,
expiringMaintenanceCount: _expiringMaintenanceCount,
);
}
/// F-Pattern 2차 시선: 페이지 헤더 (간소화된 제목)
Widget _buildPageHeader() {
final breadcrumbs = _getBreadcrumbs(); // 변수는 유지 (향후 사용 가능)
return Container(
// BaseListScreen과 동일한 폭을 위해 마진 추가
margin: const EdgeInsets.symmetric(horizontal: ShadcnTheme.spacing6), // 24px 마진 추가
padding: const EdgeInsets.all(ShadcnTheme.spacing3), // 12px 내부 패딩
decoration: BoxDecoration(
color: ShadcnTheme.background,
borderRadius: BorderRadius.circular(ShadcnTheme.radiusLg),
border: Border.all(
color: ShadcnTheme.border,
width: 1,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 페이지 제목 (좌측 패딩 + 작은 텍스트)
Padding(
padding: const EdgeInsets.only(left: ShadcnTheme.spacing2), // 좌측 패딩 추가
child: Text(
_getPageTitle(),
style: ShadcnTheme.bodySmall.copyWith(
fontWeight: FontWeight.w500, // 약간 두껴게
),
),
),
// 브레드크럼 (주석처리)
/*
const SizedBox(height: ShadcnTheme.spacing1),
// 브레드크럼
Row(
children: [
for (int i = 0; i < breadcrumbs.length; i++) ...[
if (i > 0) ...[
const SizedBox(width: ShadcnTheme.spacing1),
Icon(
Icons.chevron_right,
size: 14,
color: ShadcnTheme.foregroundSubtle,
),
const SizedBox(width: ShadcnTheme.spacing1),
],
Text(
breadcrumbs[i],
style: i == breadcrumbs.length - 1
? ShadcnTheme.bodySmall.copyWith(
color: ShadcnTheme.foreground,
fontWeight: FontWeight.w500,
)
: ShadcnTheme.bodySmall.copyWith(
color: ShadcnTheme.foregroundMuted,
),
),
],
],
),
*/
],
),
);
}
/// 리스트 페이지 여부 확인
bool _isListPage() {
return [
Routes.equipment,
Routes.equipmentInList,
Routes.equipmentOutList,
Routes.equipmentRentList,
Routes.company,
Routes.user,
Routes.license,
Routes.warehouseLocation,
].contains(_currentRoute);
}
/// 추가 액션 처리
void _handleAddAction() {
String addRoute = '';
switch (_currentRoute) {
case Routes.equipment:
case Routes.equipmentInList:
addRoute = '/equipment/in';
break;
case Routes.equipmentOutList:
addRoute = '/equipment/out';
break;
case Routes.company:
addRoute = '/company/add';
break;
case Routes.user:
addRoute = '/user/add';
break;
case Routes.license:
addRoute = '/license/add';
break;
case Routes.warehouseLocation:
addRoute = '/warehouse-location/add';
break;
}
if (addRoute.isNotEmpty) {
Navigator.pushNamed(context, addRoute).then((result) {
if (result == true) {
setState(() {});
}
});
}
}
/// 프로필 메뉴 표시
void _showProfileMenu(BuildContext context) {
@@ -862,15 +739,15 @@ class SidebarMenu extends StatelessWidget {
final String currentRoute;
final Function(String) onRouteChanged;
final bool collapsed;
final int expiringLicenseCount;
final int expiringMaintenanceCount;
const SidebarMenu({
Key? key,
super.key,
required this.currentRoute,
required this.onRouteChanged,
required this.collapsed,
required this.expiringLicenseCount,
}) : super(key: key);
required this.expiringMaintenanceCount,
});
@override
Widget build(BuildContext context) {
@@ -910,6 +787,22 @@ class SidebarMenu extends StatelessWidget {
badge: null,
),
_buildMenuItem(
icon: Icons.factory_outlined,
title: '벤더 관리',
route: Routes.vendor,
isActive: currentRoute == Routes.vendor,
badge: null,
),
_buildMenuItem(
icon: Icons.category_outlined,
title: '모델 관리',
route: Routes.model,
isActive: currentRoute == Routes.model,
badge: null,
),
_buildMenuItem(
icon: Icons.inventory_2_outlined,
title: '장비 관리',
@@ -923,6 +816,25 @@ class SidebarMenu extends StatelessWidget {
badge: null,
),
_buildMenuItem(
icon: Icons.history,
title: '재고 이력',
route: Routes.inventoryHistory,
isActive: [
Routes.inventory,
Routes.inventoryHistory,
].contains(currentRoute),
badge: null,
),
_buildMenuItem(
icon: Icons.analytics_outlined,
title: '재고 대시보드',
route: Routes.inventoryDashboard,
isActive: currentRoute == Routes.inventoryDashboard,
badge: null,
),
_buildMenuItem(
icon: Icons.warehouse_outlined,
title: '입고지 관리',
@@ -931,6 +843,14 @@ class SidebarMenu extends StatelessWidget {
badge: null,
),
_buildMenuItem(
icon: Icons.location_on_outlined,
title: '우편번호 검색',
route: Routes.zipcode,
isActive: currentRoute == Routes.zipcode,
badge: null,
),
_buildMenuItem(
icon: Icons.business_outlined,
title: '회사 관리',
@@ -948,12 +868,34 @@ class SidebarMenu extends StatelessWidget {
),
_buildMenuItem(
icon: Icons.support_outlined,
icon: Icons.build_circle_outlined,
title: '유지보수 관리',
route: Routes.license,
isActive: currentRoute == Routes.license,
badge: expiringLicenseCount > 0 ? expiringLicenseCount.toString() : null,
route: Routes.maintenance,
isActive: currentRoute == Routes.maintenance ||
currentRoute == Routes.maintenanceSchedule ||
currentRoute == Routes.maintenanceAlert ||
currentRoute == Routes.maintenanceHistory,
badge: null,
hasSubMenu: true,
subMenuItems: collapsed ? [] : [
_buildSubMenuItem(
title: '일정 관리',
route: Routes.maintenanceSchedule,
isActive: currentRoute == Routes.maintenanceSchedule,
),
_buildSubMenuItem(
title: '알림 대시보드',
route: Routes.maintenanceAlert,
isActive: currentRoute == Routes.maintenanceAlert,
),
_buildSubMenuItem(
title: '이력 조회',
route: Routes.maintenanceHistory,
isActive: currentRoute == Routes.maintenanceHistory,
),
],
),
if (!collapsed) ...[
const SizedBox(height: ShadcnTheme.spacing4),
@@ -1024,51 +966,55 @@ class SidebarMenu extends StatelessWidget {
required String route,
required bool isActive,
String? badge,
bool hasSubMenu = false,
List<Widget> subMenuItems = const [],
}) {
return AnimatedContainer(
duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.only(bottom: ShadcnTheme.spacing1),
child: InkWell(
onTap: () => onRouteChanged(route),
borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd),
child: Container(
padding: EdgeInsets.symmetric(
horizontal: collapsed ? ShadcnTheme.spacing3 : ShadcnTheme.spacing3,
vertical: ShadcnTheme.spacing2 + 2,
),
decoration: BoxDecoration(
color: isActive
? ShadcnTheme.primaryLight
: Colors.transparent,
return Column(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.only(bottom: ShadcnTheme.spacing1),
child: InkWell(
onTap: () => onRouteChanged(route),
borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd),
),
child: Row(
children: [
Icon(
isActive ? _getFilledIcon(icon) : icon,
size: 20,
color: isActive
? ShadcnTheme.primary
: ShadcnTheme.foregroundSecondary,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: collapsed ? ShadcnTheme.spacing3 : ShadcnTheme.spacing3,
vertical: ShadcnTheme.spacing2 + 2,
),
if (!collapsed) ...[
const SizedBox(width: ShadcnTheme.spacing3),
Expanded(
child: Text(
title,
style: ShadcnTheme.bodyMedium.copyWith(
color: isActive
? ShadcnTheme.primary
: ShadcnTheme.foreground,
fontWeight: isActive ? FontWeight.w600 : FontWeight.w400,
),
decoration: BoxDecoration(
color: isActive
? ShadcnTheme.primaryLight
: Colors.transparent,
borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd),
),
child: Row(
children: [
Icon(
isActive ? _getFilledIcon(icon) : icon,
size: 20,
color: isActive
? ShadcnTheme.primary
: ShadcnTheme.foregroundSecondary,
),
),
if (badge != null) ...[
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
if (!collapsed) ...[
const SizedBox(width: ShadcnTheme.spacing3),
Expanded(
child: Text(
title,
style: ShadcnTheme.bodyMedium.copyWith(
color: isActive
? ShadcnTheme.primary
: ShadcnTheme.foreground,
fontWeight: isActive ? FontWeight.w600 : FontWeight.w400,
),
),
),
if (badge != null) ...[
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
decoration: BoxDecoration(
color: Colors.orange,
@@ -1102,6 +1048,62 @@ class SidebarMenu extends StatelessWidget {
),
),
),
),
if (hasSubMenu && subMenuItems.isNotEmpty) ...subMenuItems,
],
);
}
Widget _buildSubMenuItem({
required String title,
required String route,
required bool isActive,
}) {
return AnimatedContainer(
duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.only(left: 40, bottom: 4),
child: InkWell(
onTap: () => onRouteChanged(route),
borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: ShadcnTheme.spacing3,
vertical: ShadcnTheme.spacing2,
),
decoration: BoxDecoration(
color: isActive
? ShadcnTheme.primaryLight.withValues(alpha: 0.5)
: Colors.transparent,
borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd),
),
child: Row(
children: [
Container(
width: 4,
height: 4,
decoration: BoxDecoration(
color: isActive
? ShadcnTheme.primary
: ShadcnTheme.foregroundSecondary,
shape: BoxShape.circle,
),
),
const SizedBox(width: ShadcnTheme.spacing3),
Expanded(
child: Text(
title,
style: ShadcnTheme.bodySmall.copyWith(
color: isActive
? ShadcnTheme.primary
: ShadcnTheme.foreground,
fontWeight: isActive ? FontWeight.w600 : FontWeight.w400,
),
),
),
],
),
),
),
);
}
@@ -1114,14 +1116,24 @@ class SidebarMenu extends StatelessWidget {
return Icons.inventory_2;
case Icons.warehouse_outlined:
return Icons.warehouse;
case Icons.location_on_outlined:
return Icons.location_on;
case Icons.business_outlined:
return Icons.business;
case Icons.people_outlined:
return Icons.people;
case Icons.support_outlined:
return Icons.support;
case Icons.build_circle_outlined:
return Icons.build_circle;
case Icons.bug_report_outlined:
return Icons.bug_report;
case Icons.analytics_outlined:
return Icons.analytics;
case Icons.factory_outlined:
return Icons.factory;
case Icons.category_outlined:
return Icons.category;
default:
return outlinedIcon;
}

View File

@@ -15,7 +15,7 @@ class ShadcnCard extends StatefulWidget {
final bool elevated;
const ShadcnCard({
Key? key,
super.key,
required this.child,
this.padding,
this.margin,
@@ -24,7 +24,7 @@ class ShadcnCard extends StatefulWidget {
this.onTap,
this.hoverable = true,
this.elevated = false,
}) : super(key: key);
});
@override
State<ShadcnCard> createState() => _ShadcnCardState();
@@ -89,7 +89,7 @@ class ShadcnButton extends StatefulWidget {
final Color? textColor;
const ShadcnButton({
Key? key,
super.key,
required this.text,
this.onPressed,
this.variant = ShadcnButtonVariant.primary,
@@ -99,7 +99,7 @@ class ShadcnButton extends StatefulWidget {
this.loading = false,
this.backgroundColor,
this.textColor,
}) : super(key: key);
});
@override
State<ShadcnButton> createState() => _ShadcnButtonState();
@@ -336,7 +336,7 @@ class ShadcnInput extends StatefulWidget {
final bool required;
const ShadcnInput({
Key? key,
super.key,
this.label,
this.placeholder,
this.errorText,
@@ -352,7 +352,7 @@ class ShadcnInput extends StatefulWidget {
this.enabled = true,
this.maxLines = 1,
this.required = false,
}) : super(key: key);
});
@override
State<ShadcnInput> createState() => _ShadcnInputState();
@@ -480,12 +480,12 @@ class ShadcnBadge extends StatelessWidget {
final Widget? icon;
const ShadcnBadge({
Key? key,
super.key,
required this.text,
this.variant = ShadcnBadgeVariant.primary,
this.size = ShadcnBadgeSize.medium,
this.icon,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -663,12 +663,12 @@ class ShadcnSeparator extends StatelessWidget {
final EdgeInsetsGeometry? margin;
const ShadcnSeparator({
Key? key,
super.key,
this.direction = Axis.horizontal,
this.thickness = 1.0,
this.color,
this.margin,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -691,14 +691,14 @@ class ShadcnAvatar extends StatelessWidget {
final bool showBorder;
const ShadcnAvatar({
Key? key,
super.key,
this.imageUrl,
this.initials,
this.size = 40,
this.backgroundColor,
this.textColor,
this.showBorder = true,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -752,14 +752,14 @@ class ShadcnChip extends StatelessWidget {
final bool selected;
const ShadcnChip({
Key? key,
super.key,
required this.label,
this.backgroundColor,
this.textColor,
this.onDeleted,
this.avatar,
this.selected = false,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -821,13 +821,13 @@ class ShadcnProgress extends StatelessWidget {
final bool showLabel;
const ShadcnProgress({
Key? key,
super.key,
required this.value,
this.height = 8,
this.backgroundColor,
this.valueColor,
this.showLabel = false,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -17,7 +17,7 @@ class AutocompleteDropdown extends StatelessWidget {
final Widget emptyWidget;
const AutocompleteDropdown({
Key? key,
super.key,
required this.items,
required this.inputText,
required this.onSelect,
@@ -27,7 +27,7 @@ class AutocompleteDropdown extends StatelessWidget {
padding: EdgeInsets.all(12.0),
child: Text('검색 결과가 없습니다'),
),
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -12,13 +12,13 @@ class CategorySelectionField extends StatefulWidget {
final bool isRequired;
const CategorySelectionField({
Key? key,
super.key,
required this.category,
required this.subCategory,
required this.subSubCategory,
required this.onCategoryChanged,
this.isRequired = false,
}) : super(key: key);
});
@override
State<CategorySelectionField> createState() => _CategorySelectionFieldState();

View File

@@ -10,12 +10,12 @@ class DatePickerField extends StatelessWidget {
final bool isRequired;
const DatePickerField({
Key? key,
super.key,
required this.selectedDate,
required this.onDateChanged,
this.allowFutureDate = false,
this.isRequired = false,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -7,11 +7,11 @@ class FormFieldWrapper extends StatelessWidget {
final bool isRequired;
const FormFieldWrapper({
Key? key,
super.key,
required this.label,
required this.child,
this.isRequired = false,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -12,12 +12,12 @@ class HighlightText extends StatelessWidget {
final TextStyle? style;
const HighlightText({
Key? key,
super.key,
required this.text,
required this.highlight,
this.highlightColor = Colors.blue,
this.style,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -18,7 +18,7 @@ class BaseListScreen extends StatelessWidget {
final IconData emptyIcon;
const BaseListScreen({
Key? key,
super.key,
this.headerSection,
required this.searchBar,
this.filterSection,
@@ -30,7 +30,7 @@ class BaseListScreen extends StatelessWidget {
this.onRefresh,
this.emptyMessage = '데이터가 없습니다',
this.emptyIcon = Icons.inbox_outlined,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -13,7 +13,7 @@ class FormLayoutTemplate extends StatelessWidget {
final Widget? customActions;
const FormLayoutTemplate({
Key? key,
super.key,
required this.title,
required this.child,
this.onSave,
@@ -22,7 +22,7 @@ class FormLayoutTemplate extends StatelessWidget {
this.isLoading = false,
this.showBottomButtons = true,
this.customActions,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -108,12 +108,12 @@ class FormSection extends StatelessWidget {
final EdgeInsetsGeometry? padding;
const FormSection({
Key? key,
super.key,
this.title,
this.subtitle,
required this.children,
this.padding,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -157,7 +157,7 @@ class FormSection extends StatelessWidget {
} else {
return child;
}
}).toList(),
}),
],
),
);
@@ -172,12 +172,12 @@ class FormFieldWrapper extends StatelessWidget {
final Widget child;
const FormFieldWrapper({
Key? key,
super.key,
required this.label,
this.hint,
this.required = false,
required this.child,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -27,13 +27,13 @@ class AddressInput extends StatefulWidget {
final bool isRequired;
const AddressInput({
Key? key,
super.key,
this.initialZipCode = '',
this.initialRegion = '',
this.initialDetailAddress = '',
required this.onAddressChanged,
this.isRequired = false,
}) : super(key: key);
});
@override
State<AddressInput> createState() => _AddressInputState();

View File

@@ -18,7 +18,7 @@ class AutocompleteDropdownField extends StatefulWidget {
final bool enabled;
const AutocompleteDropdownField({
Key? key,
super.key,
required this.label,
required this.value,
required this.items,
@@ -27,7 +27,7 @@ class AutocompleteDropdownField extends StatefulWidget {
this.isRequired = false,
this.hintText = '',
this.enabled = true,
}) : super(key: key);
});
@override
State<AutocompleteDropdownField> createState() =>

View File

@@ -19,7 +19,7 @@ class CategoryAutocompleteField extends StatefulWidget {
final bool enabled;
const CategoryAutocompleteField({
Key? key,
super.key,
required this.hintText,
required this.value,
required this.items,
@@ -27,7 +27,7 @@ class CategoryAutocompleteField extends StatefulWidget {
this.isRequired = false,
this.onChanged,
this.enabled = true,
}) : super(key: key);
});
@override
State<CategoryAutocompleteField> createState() =>

View File

@@ -13,12 +13,12 @@ class Pagination extends StatelessWidget {
final ValueChanged<int> onPageChanged;
const Pagination({
Key? key,
super.key,
required this.totalCount,
required this.currentPage,
required this.pageSize,
required this.onPageChanged,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -12,7 +12,7 @@ class RemarkInput extends StatelessWidget {
final bool enabled;
const RemarkInput({
Key? key,
super.key,
required this.controller,
this.label = '비고',
this.hint = '비고를 입력하세요',
@@ -20,7 +20,7 @@ class RemarkInput extends StatelessWidget {
this.minLines = 4,
this.maxLines,
this.enabled = true,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -14,14 +14,14 @@ class StandardActionBar extends StatelessWidget {
final String? statusMessage; // 추가 상태 메시지
const StandardActionBar({
Key? key,
super.key,
this.leftActions = const [],
this.rightActions = const [],
this.selectedCount,
required this.totalCount,
this.onRefresh,
this.statusMessage,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -204,12 +204,12 @@ class StandardFilterDropdown<T> extends StatelessWidget {
final String? hint;
const StandardFilterDropdown({
Key? key,
super.key,
required this.value,
required this.items,
required this.onChanged,
this.hint,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -33,7 +33,7 @@ class StandardDataTable extends StatelessWidget {
final bool applyZebraStripes; // 짝수 행 배경색 적용 여부
const StandardDataTable({
Key? key,
super.key,
required this.columns,
required this.rows,
this.showCheckbox = false,
@@ -43,7 +43,7 @@ class StandardDataTable extends StatelessWidget {
this.horizontalScrollController,
this.emptyWidget,
this.applyZebraStripes = true,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -178,7 +178,7 @@ class StandardDataRow extends StatelessWidget {
final List<DataColumn> columns;
const StandardDataRow({
Key? key,
super.key,
required this.index,
required this.cells,
this.showCheckbox = false,
@@ -186,7 +186,7 @@ class StandardDataRow extends StatelessWidget {
this.onSelect,
this.applyZebraStripes = true,
required this.columns,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -254,13 +254,13 @@ class StandardActionButtons extends StatelessWidget {
final double buttonSize;
const StandardActionButtons({
Key? key,
super.key,
this.onView,
this.onEdit,
this.onDelete,
this.customButtons,
this.buttonSize = 32,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -7,9 +7,9 @@ class StandardLoadingState extends StatelessWidget {
final String message;
const StandardLoadingState({
Key? key,
super.key,
this.message = '데이터를 불러오는 중...',
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -40,12 +40,12 @@ class StandardErrorState extends StatelessWidget {
final IconData icon;
const StandardErrorState({
Key? key,
super.key,
this.title = '오류가 발생했습니다',
this.message,
this.onRetry,
this.icon = Icons.error_outline,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -99,12 +99,12 @@ class StandardEmptyState extends StatelessWidget {
final IconData icon;
const StandardEmptyState({
Key? key,
super.key,
this.title = '데이터가 없습니다',
this.message,
this.action,
this.icon = Icons.inbox_outlined,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -154,12 +154,12 @@ class StandardInfoMessage extends StatelessWidget {
final VoidCallback? onClose;
const StandardInfoMessage({
Key? key,
super.key,
required this.message,
this.icon = Icons.info_outline,
this.color,
this.onClose,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@@ -220,13 +220,13 @@ class StandardStatCard extends StatelessWidget {
final String? subtitle;
const StandardStatCard({
Key? key,
super.key,
required this.title,
required this.value,
required this.icon,
required this.color,
this.subtitle,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@@ -16,7 +16,7 @@ class UnifiedSearchBar extends StatelessWidget {
final bool showSearchButton;
const UnifiedSearchBar({
Key? key,
super.key,
required this.controller,
this.placeholder = '검색어를 입력하세요...',
required this.onSearch,
@@ -25,7 +25,7 @@ class UnifiedSearchBar extends StatelessWidget {
this.suffixButton,
this.filters,
this.showSearchButton = true,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {