사용하지 않는 파일 정리 전 백업 (Phase 10 완료 후 상태)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user