141 lines
4.3 KiB
Dart
141 lines
4.3 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:niogu_app/core/components/app_bar_with_tab.dart';
|
|
import 'package:niogu_app/core/providers/app_provider.dart';
|
|
import 'package:niogu_app/core/enums/user_role.dart';
|
|
import 'package:niogu_app/core/widgets/pop_up_notification.dart';
|
|
import 'package:niogu_app/features/goods/products/presentation/providers/product_provider.dart';
|
|
import 'package:niogu_app/features/goods/products/presentation/screens/product_choice_screen.dart';
|
|
import 'package:niogu_app/features/goods/raw_materials/presentation/providers/raw_material_provider.dart';
|
|
import 'package:niogu_app/features/goods/raw_materials/presentation/screens/raw_material_choice_screen.dart';
|
|
import 'package:sizer/sizer.dart';
|
|
|
|
class GoodChoiceScreen extends ConsumerStatefulWidget {
|
|
const GoodChoiceScreen({super.key});
|
|
|
|
@override
|
|
ConsumerState<GoodChoiceScreen> createState() => _GoodChoiceScreenState();
|
|
}
|
|
|
|
class _GoodChoiceScreenState extends ConsumerState<GoodChoiceScreen>
|
|
with SingleTickerProviderStateMixin {
|
|
late TabController _tabController;
|
|
|
|
final FocusNode _searchFocusNode = FocusNode();
|
|
|
|
Color _searchIconColor = Colors.grey;
|
|
|
|
Timer? _debounce;
|
|
|
|
int _tabIndex = 0;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
_tabController = TabController(length: 2, vsync: this);
|
|
|
|
_tabController.addListener(_handleTabSelection);
|
|
|
|
_searchFocusNode.addListener(() {
|
|
setState(() {
|
|
_searchIconColor = _searchFocusNode.hasFocus
|
|
? Colors.black
|
|
: Colors.grey;
|
|
});
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_searchFocusNode.dispose();
|
|
_tabController.removeListener(_handleTabSelection);
|
|
_tabController.dispose();
|
|
_debounce?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
void _handleTabSelection() {
|
|
if (_tabController.index != _tabIndex) {
|
|
setState(() {
|
|
_tabIndex = _tabController.index;
|
|
});
|
|
}
|
|
}
|
|
|
|
void _onSearchChanged(String value) {
|
|
if (_debounce?.isActive ?? false) _debounce?.cancel();
|
|
_debounce = Timer(const Duration(milliseconds: 800), () {
|
|
if (_tabIndex == 0) {
|
|
ref.read(productChoiceSearchProvider.notifier).state = value;
|
|
} else {
|
|
ref.read(rawMaterialChoiceSearchProvider.notifier).state = value;
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return LayoutBuilder(
|
|
builder: (context, constraints) {
|
|
final messageActivity = ref.watch(messageActivityProvider);
|
|
|
|
final currentUserRole = ref.watch(currentUserRoleProvider);
|
|
|
|
return SafeArea(
|
|
top: false,
|
|
bottom: true,
|
|
right: false,
|
|
left: false,
|
|
child: Stack(
|
|
children: [
|
|
Scaffold(
|
|
backgroundColor: Colors.white,
|
|
resizeToAvoidBottomInset: false,
|
|
appBar: AppBarWithTab(
|
|
hintText:
|
|
"Cari nama ${_tabIndex == 0 ? 'produk' : 'bahan baku'}...",
|
|
searchIconColor: _searchIconColor,
|
|
canPop: true,
|
|
onPop: () => context.pop(),
|
|
showSwitchOutlet: currentUserRole == UserRole.owner,
|
|
searchFocusNode: _searchFocusNode,
|
|
tabController: _tabController,
|
|
onTap: (value) {
|
|
setState(() {
|
|
_tabIndex = value;
|
|
});
|
|
},
|
|
onSearchChanged: (value) => _onSearchChanged(value),
|
|
tabs: [
|
|
Tab(text: "Produk", height: 10.h),
|
|
Tab(text: "Bahan Baku", height: 10.h),
|
|
],
|
|
),
|
|
|
|
body: TabBarView(
|
|
controller: _tabController,
|
|
children: const [
|
|
const ProductChoiceScreen(),
|
|
const RawMaterialChoiceScreen(),
|
|
],
|
|
),
|
|
),
|
|
|
|
if (messageActivity != null)
|
|
PopupNotification(
|
|
isOwner: currentUserRole == UserRole.owner,
|
|
messages: messageActivity.messages,
|
|
type: messageActivity.type,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|