creek

The AI Image Editor of 2030
commit 9e2b44bba479ef0ffe774f8f5208d7be43f652ec
parent ba31c4b30ed8ad2b837a1e7a8d8ae60c82949c8a
Author: aditya-samal <samaladitya2004@gmail.com>
Date:   Tue,  2 Dec 2025 04:15:05 +0530

Fixed some screens

Diffstat:
Mlib/ui/pages/image_save_page.dart | 393+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Mlib/ui/pages/project_board_page.dart | 22+++++++++++++++++++++-
Mlib/ui/pages/project_board_page_alternate.dart | 70++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mlib/ui/pages/project_tag_page.dart | 1+
Mlib/ui/pages/stylesheet_page.dart | 20+++++++++++---------
Mlib/ui/widgets/top_bar.dart | 166++++++++++++++++++++++++++++++++++++++++++-------------------------------------
6 files changed, 424 insertions(+), 248 deletions(-)

diff --git a/lib/ui/pages/image_save_page.dart b/lib/ui/pages/image_save_page.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../services/image_service.dart'; import '../../services/note_service.dart'; +import 'project_board_page.dart'; // --- HELPER CLASS FOR TEMPORARY NOTES --- class TempNote { @@ -428,44 +429,60 @@ class _ImageSavePageState extends State<ImageSavePage> { mainAxisSize: MainAxisSize.min, children: [ Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 20, - ), + padding: const EdgeInsets.all(16), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ // --- ROW 1: Header --- Row( children: [ - const CircleAvatar( - radius: 18, - backgroundColor: Colors.grey, - child: Icon( - Icons.person, - color: Colors.white, - size: 20, + // Avatar + Container( + width: 30, + height: 30, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: const Color(0xFFFAFAFA), + width: 1.25, + ), + ), + child: const CircleAvatar( + radius: 15, + backgroundColor: Colors.grey, + child: Icon( + Icons.person, + color: Colors.white, + size: 18, + ), ), ), - const SizedBox(width: 12), + const SizedBox(width: 10), + // User name const Text( - "User", + "Alex", style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - color: Colors.black87, + fontFamily: 'GeneralSans', + fontSize: 12, + fontWeight: FontWeight.w500, + color: Colors.black, + letterSpacing: 0.4, + height: 16 / 12, ), ), const Spacer(), - // Dropdown --- + // Dropdown Container( - height: 40, - padding: const EdgeInsets.symmetric(horizontal: 16), + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), decoration: BoxDecoration( - color: const Color(0xFFE0E5FF), - borderRadius: BorderRadius.circular(20), + color: const Color(0xFFE0E7FF), + borderRadius: BorderRadius.circular(1000), ), child: DropdownButtonHideUnderline( child: DropdownButton<String>( @@ -473,17 +490,28 @@ class _ImageSavePageState extends State<ImageSavePage> { _categories.contains(_selectedCategory) ? _selectedCategory : null, - hint: const Text("Type"), + hint: const Text( + "Type", + style: TextStyle( + fontFamily: 'GeneralSans', + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xFF27272A), + height: 16 / 12, + ), + ), isDense: true, icon: const Icon( - Icons.keyboard_arrow_down, + Icons.arrow_drop_down, size: 20, - color: Colors.black54, + color: Color(0xFF27272A), ), style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.black87, + fontFamily: 'GeneralSans', + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xFF27272A), + height: 16 / 12, ), focusColor: Colors.transparent, dropdownColor: Colors.white, @@ -492,11 +520,17 @@ class _ImageSavePageState extends State<ImageSavePage> { .map( (c) => DropdownMenuItem( value: c, - child: Text(c), + child: Text( + c, + style: const TextStyle( + fontFamily: 'GeneralSans', + fontSize: 12, + fontWeight: FontWeight.normal, + ), + ), ), ) .toList(), - onChanged: (v) { setModalState(() { _selectedCategory = v!; @@ -508,47 +542,71 @@ class _ImageSavePageState extends State<ImageSavePage> { ], ), - const SizedBox(height: 20), + const SizedBox(height: 16), // --- ROW 2: Input & Send --- Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( - child: TextField( - controller: _commentController, - autofocus: true, - maxLines: 1, - style: const TextStyle(fontSize: 14), - decoration: InputDecoration( - filled: true, - fillColor: const Color(0xFFF3F4F6), - hintText: "Enter details...", - hintStyle: TextStyle(color: Colors.grey[600]), - contentPadding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 14, + child: Container( + decoration: BoxDecoration( + color: const Color(0xFFF4F4F5), + border: Border.all( + color: const Color(0xFFE4E4E7), + width: 1, ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(8), + ), + child: TextField( + controller: _commentController, + autofocus: true, + maxLines: null, + style: const TextStyle( + fontFamily: 'GeneralSans', + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xFF27272A), + height: 16 / 12, + ), + decoration: InputDecoration( + hintText: "I love the serif font and how it is used...", + hintStyle: const TextStyle( + fontFamily: 'GeneralSans', + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xFF27272A), + height: 16 / 12, + ), + contentPadding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 10, + ), + border: InputBorder.none, + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, ), ), ), ), - const SizedBox(width: 12), + const SizedBox(width: 8), - Container( - margin: const EdgeInsets.only(bottom: 2), - child: IconButton( - icon: const Icon(Icons.send_outlined), - color: Colors.black87, - iconSize: 28, - onPressed: () { - _addTempNote(); - Navigator.pop(context); - }, + // Send button + IconButton( + icon: const Icon( + Icons.send, + color: Color(0xFF27272A), + size: 24, + ), + onPressed: () { + _addTempNote(); + Navigator.pop(context); + }, + padding: EdgeInsets.zero, + constraints: const BoxConstraints( + minWidth: 24, + minHeight: 24, ), ), ], @@ -645,7 +703,17 @@ class _ImageSavePageState extends State<ImageSavePage> { if (widget.isFromShare) { SystemNavigator.pop(); } else { - Navigator.pop(context); + // Navigate to project board page in grid view (alternate view) + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute( + builder: (_) => ProjectBoardPage( + projectId: widget.projectId, + initialShowAlternateView: true, // Show grid view + ), + ), + (route) => false, // Remove all previous routes + ); } } } catch (e) { @@ -689,9 +757,12 @@ class _ImageSavePageState extends State<ImageSavePage> { title: Text( titleText, style: const TextStyle( + fontFamily: 'GeneralSans', color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.w600, + fontSize: 20, + fontWeight: FontWeight.w500, + height: 24 / 20, + letterSpacing: 0, ), ), actions: [ @@ -699,15 +770,20 @@ class _ImageSavePageState extends State<ImageSavePage> { if (_isResizing && _finalSelectionRect != null) IconButton( icon: const Icon( - Icons.check_circle_outline, - color: Color(0xFF7C4DFF), + Icons.check, + color: Color(0xFF7C86FF), + size: 24, ), onPressed: _confirmSelectionAndShowModal, ), // CANCEL SELECTION BUTTON (Visible only in drawing/resizing mode) if (_isDrawMode || _isResizing) IconButton( - icon: const Icon(Icons.close, color: Colors.black), + icon: const Icon( + Icons.close, + color: Colors.black87, + size: 24, + ), onPressed: _resetSelectionMode, ), ], @@ -909,7 +985,11 @@ class _ImageSavePageState extends State<ImageSavePage> { label: const Text( "Notes", style: TextStyle( - fontWeight: FontWeight.w600, + fontFamily: 'GeneralSans', + fontSize: 14, + fontWeight: FontWeight.w500, + height: 20 / 14, + letterSpacing: 0.25, ), ), ), @@ -935,8 +1015,10 @@ class _ImageSavePageState extends State<ImageSavePage> { child: const Text( "Drag on image to select area", style: TextStyle( + fontFamily: 'GeneralSans', color: Colors.white, fontSize: 12, + fontWeight: FontWeight.normal, ), ), ), @@ -965,8 +1047,10 @@ class _ImageSavePageState extends State<ImageSavePage> { child: const Text( "Adjust area or tap checkmark to confirm", style: TextStyle( + fontFamily: 'GeneralSans', color: Colors.white, fontSize: 12, + fontWeight: FontWeight.normal, ), ), ), @@ -984,86 +1068,114 @@ class _ImageSavePageState extends State<ImageSavePage> { ), ), // --- BOTTOM FORM (TAGS & SAVE) --- - Container( - width: double.infinity, - padding: const EdgeInsets.all(24), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: const BorderRadius.vertical( - top: Radius.circular(24), - ), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.05), - blurRadius: 10, - offset: const Offset(0, -5), - ), - ], - ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Text( - 'Tags', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), + // Tags box matching Figma design + Container( + width: double.infinity, + decoration: BoxDecoration( + color: const Color(0xFFFEFEFE), + border: Border.all( + color: const Color(0xFFE4E4E7), + width: 1, ), - if (widget.imagePaths.length > 1) - Text( - "Image ${_currentImageIndex + 1}/${widget.imagePaths.length}", - style: TextStyle(color: Colors.grey[600], fontSize: 12), - ), - ], - ), - const SizedBox(height: 12), - Wrap( - spacing: 8, - runSpacing: 8, - children: - _availableTags.map((tag) { - final isSelected = currentTags.contains(tag); - return GestureDetector( - onTap: () => _toggleTag(tag), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 14, - vertical: 8, - ), - decoration: BoxDecoration( - color: - isSelected - ? const Color(0xFFEEF0FF) - : Colors.white, - borderRadius: BorderRadius.circular(20), - border: Border.all( - color: - isSelected - ? const Color(0xFF7C4DFF) - : Colors.grey[300]!, - ), - ), - child: Text( - tag, + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Header section + Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'What did you like about this image?', style: TextStyle( - fontSize: 13, - fontWeight: - isSelected - ? FontWeight.w600 - : FontWeight.normal, - color: - isSelected - ? const Color(0xFF7C4DFF) - : Colors.black87, + fontFamily: 'GeneralSans', + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.black, + letterSpacing: 0.25, + height: 20 / 14, ), ), - ), - ); - }).toList(), + if (widget.imagePaths.length > 1) + Text( + "Image ${_currentImageIndex + 1}/${widget.imagePaths.length}", + style: const TextStyle( + fontFamily: 'GeneralSans', + color: Colors.grey, + fontSize: 12, + fontWeight: FontWeight.normal, + ), + ), + ], + ), + ), + // Divider + const Divider( + height: 0, + thickness: 1, + color: Color(0xFFE4E4E7), + ), + // Content section with tags + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 12, + ), + child: Wrap( + spacing: 8, + runSpacing: 8, + children: + _availableTags.map((tag) { + final isSelected = currentTags.contains(tag); + return GestureDetector( + onTap: () => _toggleTag(tag), + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 14, + vertical: 8, + ), + decoration: BoxDecoration( + color: + isSelected + ? const Color(0xFFE0E7FF) + : Colors.white, + borderRadius: BorderRadius.circular(20), + border: Border.all( + color: + isSelected + ? const Color(0xFF7C86FF) + : Colors.grey[300]!, + ), + ), + child: Text( + tag, + style: TextStyle( + fontFamily: 'GeneralSans', + fontSize: 14, + fontWeight: FontWeight.normal, + height: 20 / 14, + letterSpacing: 0, + color: + isSelected + ? const Color(0xFF27272A) + : Colors.black87, + ), + ), + ), + ); + }).toList(), + ), + ), + ], + ), ), const SizedBox(height: 24), SizedBox( @@ -1091,8 +1203,11 @@ class _ImageSavePageState extends State<ImageSavePage> { : Text( 'Save ${widget.imagePaths.length > 1 ? "All" : ""} to Moodboard', style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, + fontFamily: 'GeneralSans', + fontSize: 14, + fontWeight: FontWeight.w500, + height: 20 / 14, + letterSpacing: 0.25, ), ), ), diff --git a/lib/ui/pages/project_board_page.dart b/lib/ui/pages/project_board_page.dart @@ -13,12 +13,18 @@ import 'project_tag_page.dart'; import 'project_board_page_alternate.dart'; import 'image_save_page.dart'; import 'image_details_page.dart'; +import 'stylesheet_page.dart'; import '../widgets/image_context_menu.dart'; class ProjectBoardPage extends StatefulWidget { final int projectId; + final bool? initialShowAlternateView; - const ProjectBoardPage({super.key, required this.projectId}); + const ProjectBoardPage({ + super.key, + required this.projectId, + this.initialShowAlternateView, + }); @override State<ProjectBoardPage> createState() => _ProjectBoardPageState(); @@ -41,6 +47,8 @@ class _ProjectBoardPageState extends State<ProjectBoardPage> { @override void initState() { super.initState(); + // Set initial view based on parameter, default to true (grid view) + _showAlternateView = widget.initialShowAlternateView ?? true; _initData(); } @@ -168,6 +176,17 @@ class _ProjectBoardPageState extends State<ProjectBoardPage> { if (!_showAlternateView) _loadImagesForSelected(); }); }, + onAIPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => StylesheetPage( + projectId: _currentProject!.id!, + autoGenerate: true, + ), + ), + ); + }, ), bottomNavigationBar: BottomBar( currentTab: BottomBarItem.moodboard, @@ -181,6 +200,7 @@ class _ProjectBoardPageState extends State<ProjectBoardPage> { ), body: Column( children: [ + const SizedBox(height: 16), Expanded( child: _showAlternateView diff --git a/lib/ui/pages/project_board_page_alternate.dart b/lib/ui/pages/project_board_page_alternate.dart @@ -365,31 +365,57 @@ class ProjectBoardPageAlternateState extends State<ProjectBoardPageAlternate> { child: Wrap( spacing: 4, runSpacing: 4, - children: - image.tags.take(3).map((tag) { - return Container( - padding: const EdgeInsets.symmetric( - horizontal: 6, - vertical: 2, + children: [ + // Show first 2 tags + ...image.tags.take(2).map((tag) { + return Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.2), + borderRadius: BorderRadius.circular(4), + border: Border.all( + color: Colors.white.withValues(alpha: 0.1), ), - decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.2), - borderRadius: BorderRadius.circular(4), - border: Border.all( - color: Colors.white.withValues(alpha: 0.1), - ), + ), + child: Text( + tag.toUpperCase(), + style: const TextStyle( + color: Colors.white, + fontSize: 9, + fontFamily: 'GeneralSans', + fontWeight: FontWeight.w600, ), - child: Text( - tag.toUpperCase(), - style: const TextStyle( - color: Colors.white, - fontSize: 9, - fontFamily: 'GeneralSans', - fontWeight: FontWeight.w600, - ), + ), + ); + }), + // Show "+x" tag if there are more than 2 tags + if (image.tags.length > 2) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.2), + borderRadius: BorderRadius.circular(4), + border: Border.all( + color: Colors.white.withValues(alpha: 0.1), + ), + ), + child: Text( + '+${image.tags.length - 2}', + style: const TextStyle( + color: Colors.white, + fontSize: 9, + fontFamily: 'GeneralSans', + fontWeight: FontWeight.w600, ), - ); - }).toList(), + ), + ), + ], ), ), ), diff --git a/lib/ui/pages/project_tag_page.dart b/lib/ui/pages/project_tag_page.dart @@ -126,6 +126,7 @@ class _ProjectTagPageState extends State<ProjectTagPage> { currentProjectId: widget.projectId, titleOverride: widget.tag.toUpperCase(), onBack: () => Navigator.pop(context), + hideSecondRow: true, ), bottomNavigationBar: BottomBar( diff --git a/lib/ui/pages/stylesheet_page.dart b/lib/ui/pages/stylesheet_page.dart @@ -15,8 +15,9 @@ import 'package:path_provider/path_provider.dart'; class StylesheetPage extends StatefulWidget { final int projectId; + final bool autoGenerate; - const StylesheetPage({super.key, required this.projectId}); + const StylesheetPage({super.key, required this.projectId, this.autoGenerate = false}); @override State<StylesheetPage> createState() => _StylesheetPageState(); @@ -36,7 +37,14 @@ class _StylesheetPageState extends State<StylesheetPage> { void initState() { super.initState(); _currentProjectId = widget.projectId; - _loadSavedStylesheet(); + if (widget.autoGenerate) { + // Generate stylesheet automatically after a short delay to ensure page is built + WidgetsBinding.instance.addPostFrameCallback((_) { + _generateStylesheet(); + }); + } else { + _loadSavedStylesheet(); + } } // --- PARSING LOGIC --- @@ -260,13 +268,7 @@ class _StylesheetPageState extends State<StylesheetPage> { children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Text("Visual Identity", style: TextStyle(fontFamily: 'GeneralSans', fontSize: 24, fontWeight: FontWeight.w600)), - IconButton(icon: const Icon(Icons.refresh), onPressed: _generateStylesheet), - ], - ), + child: const Text("Visual Identity", style: TextStyle(fontFamily: 'GeneralSans', fontSize: 24, fontWeight: FontWeight.w600)), ), const SizedBox(height: 32), diff --git a/lib/ui/widgets/top_bar.dart b/lib/ui/widgets/top_bar.dart @@ -15,6 +15,7 @@ class TopBar extends StatefulWidget implements PreferredSizeWidget { final VoidCallback? onAIPressed; final bool? isAlternateView; // For toggle state final VoidCallback? onLayoutToggle; // For toggle callback + final bool hideSecondRow; // Hide the second row (dropdown, buttons, etc.) const TopBar({ super.key, @@ -28,13 +29,16 @@ class TopBar extends StatefulWidget implements PreferredSizeWidget { this.onAIPressed, this.isAlternateView, this.onLayoutToggle, + this.hideSecondRow = false, }); @override State<TopBar> createState() => _TopBarState(); @override - Size get preferredSize => const Size.fromHeight(88.0); // Height for two rows + Size get preferredSize => hideSecondRow + ? const Size.fromHeight(48.0) // Height for single row + : const Size.fromHeight(88.0); // Height for two rows } class _TopBarState extends State<TopBar> { @@ -160,24 +164,26 @@ class _TopBarState extends State<TopBar> { ) : const SizedBox(), ), - // Settings Icon - GestureDetector( - onTap: widget.onSettingsPressed, - child: SvgPicture.asset( - 'assets/icons/settings-line.svg', - width: 24, - height: 24, - colorFilter: const ColorFilter.mode( - Variables.textPrimary, - BlendMode.srcIn, + // Settings Icon (only show if second row is visible) + if (!widget.hideSecondRow) + GestureDetector( + onTap: widget.onSettingsPressed, + child: SvgPicture.asset( + 'assets/icons/settings-line.svg', + width: 24, + height: 24, + colorFilter: const ColorFilter.mode( + Variables.textPrimary, + BlendMode.srcIn, + ), ), ), - ), ], ), ), // Second Row: Global Dropdown and Action Buttons - Container( + if (!widget.hideSecondRow) + Container( height: 40.0, // py-[8px] = 16px + 24px content padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Row( @@ -201,11 +207,11 @@ class _TopBarState extends State<TopBar> { child: Container( padding: const EdgeInsets.symmetric( horizontal: 16, - vertical: 8, + vertical: 10, ), decoration: BoxDecoration( color: Variables.borderSubtle, // #e4e4e7 - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(1000), ), child: Row( mainAxisSize: MainAxisSize.min, @@ -216,9 +222,9 @@ class _TopBarState extends State<TopBar> { : _currentProject!.title, style: const TextStyle( fontFamily: 'GeneralSans', - fontSize: 16, + fontSize: 14, fontWeight: FontWeight.w500, - height: 24 / 16, + height: 20 / 14, color: Variables.textPrimary, ), ), @@ -253,75 +259,81 @@ class _TopBarState extends State<TopBar> { }).toList(); }, ), - const SizedBox(width: 8), // Layout Icon Button (Toggle between All Images/Categorized) - GestureDetector( - onTap: widget.onLayoutToggle ?? widget.onLayoutPressed, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, - ), - decoration: BoxDecoration( - color: Variables.borderSubtle, - borderRadius: BorderRadius.circular(1000), - ), - child: Icon( - widget.isAlternateView == true - ? Icons.dashboard - : Icons.view_agenda_outlined, - size: 20, - color: Variables.textPrimary, + if (widget.onLayoutToggle != null || widget.onLayoutPressed != null) ...[ + const SizedBox(width: 8), + GestureDetector( + onTap: widget.onLayoutToggle ?? widget.onLayoutPressed, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 10, + ), + decoration: BoxDecoration( + color: Variables.borderSubtle, + borderRadius: BorderRadius.circular(1000), + ), + child: Icon( + widget.isAlternateView == true + ? Icons.dashboard + : Icons.view_agenda_outlined, + size: 20, + color: Variables.textPrimary, + ), ), ), - ), + ], ], ), const Spacer(), // Right group: Filter and AI/Sparkle Buttons - Row( - children: [ - // Filter Icon Button - GestureDetector( - onTap: widget.onFilterPressed, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 10, - ), - decoration: BoxDecoration( - color: Variables.borderSubtle, - borderRadius: BorderRadius.circular(1000), - ), - child: const Icon( - Icons.tune, - size: 20, - color: Variables.textPrimary, - ), - ), - ), - const SizedBox(width: 8), - // AI/Sparkle Icon Button - GestureDetector( - onTap: widget.onAIPressed, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 10, - ), - decoration: BoxDecoration( - color: Variables.borderSubtle, - borderRadius: BorderRadius.circular(1000), + if (widget.onFilterPressed != null || widget.onAIPressed != null) + Row( + children: [ + // Filter Icon Button + if (widget.onFilterPressed != null) + GestureDetector( + onTap: widget.onFilterPressed, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 10, + ), + decoration: BoxDecoration( + color: Variables.borderSubtle, + borderRadius: BorderRadius.circular(1000), + ), + child: const Icon( + Icons.tune, + size: 20, + color: Variables.textPrimary, + ), + ), ), - child: const Icon( - Icons.auto_awesome, - size: 20, - color: Variables.textPrimary, + if (widget.onFilterPressed != null && widget.onAIPressed != null) + const SizedBox(width: 8), + // AI/Sparkle Icon Button + if (widget.onAIPressed != null) + GestureDetector( + onTap: widget.onAIPressed, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 10, + ), + decoration: BoxDecoration( + color: Variables.borderSubtle, + borderRadius: BorderRadius.circular(1000), + ), + child: const Icon( + Icons.auto_awesome, + size: 20, + color: Variables.textPrimary, + ), + ), ), - ), - ), - ], - ), + ], + ), ], ), ),