fix: dashboard search UI, student screen UI, reset requests modal timezone

This commit is contained in:
ssbg04 committed 2026-07-21 23:13:05 +08:00
1 parent e80d9b7c53
commit 31d613fc09
4 files changed
+20 -31

No files matched your search

@@ -555,27 +555,24 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (!_searchFocusNode.hasFocus) ...[
if (!_searchFocusNode.hasFocus && _searchController.text.isEmpty) ...[
const Flexible(
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(
'Dashboard Overview',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
child: Text(
'Dashboard Overview',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(width: 16),
],
Expanded(
key: const ValueKey('dashboard_search_expanded'),
child: LayoutBuilder(
builder: (context, constraints) {
final isSearching = _searchFocusNode.hasFocus;
final isSearching = _searchFocusNode.hasFocus || _searchController.text.isNotEmpty;
return Align(
alignment: Alignment.centerRight,
child: AppSearchBar(
key: const ValueKey('dashboard_search'),
controller: _searchController,
focusNode: _searchFocusNode,
collapsible: true,
@@ -593,7 +590,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
},
),
),
if (!_searchFocusNode.hasFocus) ...[
if (!_searchFocusNode.hasFocus && _searchController.text.isEmpty) ...[
const SizedBox(width: 16),
Row(
children: [
@@ -590,7 +590,7 @@ class _StudentsScreenState extends ConsumerState<StudentsScreen> {
Widget _buildHeaderControls(BuildContext context, StudentQueryParams query, WidgetRef ref, int activeCount) {
return LayoutBuilder(builder: (_, c) {
final isDesktop = c.maxWidth > 800;
final bool isSearchActive = _searchFocusNode.hasFocus;
final bool isSearchActive = _searchFocusNode.hasFocus || _searchController.text.isNotEmpty;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -58,7 +58,7 @@ class _AppSearchBarState extends ConsumerState<AppSearchBar> {
super.initState();
_controller = widget.controller ?? TextEditingController();
_focusNode = widget.focusNode ?? FocusNode();
_isExpanded = !widget.collapsible;
_isExpanded = !widget.collapsible || _controller.text.trim().isNotEmpty;
_controller.addListener(_onTextChanged);
_focusNode.addListener(_onFocusChanged);
}
@@ -76,7 +76,7 @@ class _AppSearchBarState extends ConsumerState<AppSearchBar> {
void _onFocusChanged() {
if (mounted) {
setState(() {
if (!_focusNode.hasFocus && widget.collapsible) {
if (!_focusNode.hasFocus && widget.collapsible && _controller.text.trim().isEmpty) {
_isExpanded = false;
}
});
@@ -151,13 +151,15 @@ class _AppSearchBarState extends ConsumerState<AppSearchBar> {
itemBuilder: (context, index) {
final term = history[index];
return InkWell(
onTapDown: (_) {
onTap: () {
_controller.text = term;
_focusNode.unfocus();
if (widget.onSubmitted != null) {
widget.onSubmitted!(term);
}
ref.read(searchHistoryProvider.notifier).addSearch(term);
Future.delayed(const Duration(milliseconds: 50), () {
if (mounted) _focusNode.unfocus();
});
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
@@ -214,18 +216,7 @@ class _AppSearchBarState extends ConsumerState<AppSearchBar> {
@override
Widget build(BuildContext context) {
if (!_isExpanded && widget.collapsible) {
if (_hasText) {
return IconButton(
onPressed: () {
_controller.clear();
widget.onChanged?.call('');
if (widget.onSubmitted != null) widget.onSubmitted!('');
},
icon: const Icon(Icons.close, size: 28, color: Colors.redAccent),
tooltip: 'Clear search',
);
}
if (!_isExpanded && widget.collapsible && !_hasText) {
return IconButton(
onPressed: () {
setState(() => _isExpanded = true);
@@ -33,9 +33,10 @@ class _ResetRequestsModalState extends ConsumerState<ResetRequestsModal> {
String _formatDate(String isoString) {
try {
final utcTime = DateTime.parse(isoString).toUtc();
final phTime = utcTime.add(const Duration(hours: 8));
return DateFormat('MMM d, yyyy, hh:mm a').format(phTime);
DateTime dt = DateTime.parse(isoString);
if (!dt.isUtc) dt = dt.toUtc();
dt = dt.add(const Duration(hours: 8));
return DateFormat('MMM d, yyyy, hh:mm a').format(dt);
} catch (_) {
return isoString;
}