fix: dashboard search UI, student screen UI, reset requests modal timezone
This commit is contained in:
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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user