No content changes: git diff --ignore-all-space over these files is empty. The churn came from editing on Windows against a repo checked out with LF.
126 lines
4.2 KiB
Dart
126 lines
4.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../config/app_config.dart';
|
|
import 'scan_mode_provider.dart';
|
|
|
|
/// DO / Product Scan mode toggle pill rendered in the [CameraDrawer].
|
|
///
|
|
/// Extracted from [CameraDrawer] to keep that file under the 256-line §3
|
|
/// threshold (AGENTS.md §3, touched during task 8.1). Reads and writes
|
|
/// [scanModeProvider] directly — the global source of truth shared with
|
|
/// [DocumentsScreen] (task 8.1, docs/api-contract-map.md G11).
|
|
///
|
|
/// Color convention:
|
|
/// - DO active → [AppConfig.doModeColor] (orange)
|
|
/// - Product active → [AppConfig.primaryColor] (green)
|
|
class CameraDrawerModeToggle extends ConsumerWidget {
|
|
const CameraDrawerModeToggle({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final activeMode = ref.watch(scanModeProvider);
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Mode',
|
|
style: AppConfig.bodySmall.copyWith(
|
|
color: Colors.grey.shade500,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: 0.5,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Container(
|
|
height: 48,
|
|
decoration: BoxDecoration(
|
|
color: Colors.grey.shade100,
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(4.0),
|
|
child: Row(
|
|
children: [
|
|
_buildSegment(
|
|
ref: ref,
|
|
value: 'DO',
|
|
label: 'DO Scan',
|
|
activeIcon: Icons.description,
|
|
inactiveIcon: Icons.description_outlined,
|
|
activeMode: activeMode,
|
|
activeColor: AppConfig.doModeColor,
|
|
),
|
|
_buildSegment(
|
|
ref: ref,
|
|
value: 'Product',
|
|
label: 'Product Scan',
|
|
activeIcon: Icons.inventory_2,
|
|
inactiveIcon: Icons.inventory_2_outlined,
|
|
activeMode: activeMode,
|
|
activeColor: AppConfig.primaryColor,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildSegment({
|
|
required WidgetRef ref,
|
|
required String value,
|
|
required String label,
|
|
required IconData activeIcon,
|
|
required IconData inactiveIcon,
|
|
required String activeMode,
|
|
required Color activeColor,
|
|
}) {
|
|
final isActive = activeMode == value;
|
|
return Expanded(
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: () => ref.read(scanModeProvider.notifier).state = value,
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: isActive ? activeColor : Colors.transparent,
|
|
borderRadius: BorderRadius.circular(8),
|
|
boxShadow: isActive
|
|
? [
|
|
BoxShadow(
|
|
color: activeColor.withOpacity(0.2),
|
|
blurRadius: 4,
|
|
offset: const Offset(0, 2),
|
|
)
|
|
]
|
|
: [],
|
|
),
|
|
alignment: Alignment.center,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
isActive ? activeIcon : inactiveIcon,
|
|
size: 16,
|
|
color: isActive ? Colors.white : Colors.grey.shade500,
|
|
),
|
|
const SizedBox(width: 6),
|
|
Text(
|
|
label,
|
|
style: AppConfig.bodyMedium.copyWith(
|
|
fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
|
|
color: isActive ? Colors.white : Colors.grey.shade600,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|