diff --git a/FONTAWESOME_ICON_MIGRATION.md b/FONTAWESOME_ICON_MIGRATION.md new file mode 100644 index 0000000..80dd79f --- /dev/null +++ b/FONTAWESOME_ICON_MIGRATION.md @@ -0,0 +1,227 @@ +# FontAwesome Icon Migration Guide + +## Package Added +```yaml +font_awesome_flutter: ^10.7.0 +``` + +## Import Statement +```dart +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +``` + +## Icon Mapping Reference + +### Navigation Icons +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.arrow_back` | `FontAwesomeIcons.arrowLeft` | Back buttons | +| `Icons.arrow_forward` | `FontAwesomeIcons.arrowRight` | Forward navigation | +| `Icons.home` | `FontAwesomeIcons.house` | Home button | +| `Icons.menu` | `FontAwesomeIcons.bars` | Menu/hamburger | +| `Icons.close` | `FontAwesomeIcons.xmark` | Close buttons | + +### Shopping & Cart Icons +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.shopping_cart` | `FontAwesomeIcons.cartShopping` | Shopping cart | +| `Icons.shopping_cart_outlined` | `FontAwesomeIcons.cartShopping` | Cart outline | +| `Icons.shopping_bag` | `FontAwesomeIcons.bagShopping` | Shopping bag | +| `Icons.shopping_bag_outlined` | `FontAwesomeIcons.bagShopping` | Bag outline | +| `Icons.add_shopping_cart` | `FontAwesomeIcons.cartPlus` | Add to cart | + +### Action Icons +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.add` | `FontAwesomeIcons.plus` | Add/increment | +| `Icons.remove` | `FontAwesomeIcons.minus` | Remove/decrement | +| `Icons.delete` | `FontAwesomeIcons.trash` | Delete | +| `Icons.delete_outline` | `FontAwesomeIcons.trashCan` | Delete outline | +| `Icons.edit` | `FontAwesomeIcons.pen` | Edit | +| `Icons.check` | `FontAwesomeIcons.check` | Checkmark | +| `Icons.check_circle` | `FontAwesomeIcons.circleCheck` | Check circle | +| `Icons.refresh` | `FontAwesomeIcons.arrowsRotate` | Refresh | + +### Status & Feedback Icons +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.error` | `FontAwesomeIcons.circleXmark` | Error | +| `Icons.error_outline` | `FontAwesomeIcons.circleExclamation` | Error outline | +| `Icons.warning` | `FontAwesomeIcons.triangleExclamation` | Warning | +| `Icons.info` | `FontAwesomeIcons.circleInfo` | Info | +| `Icons.info_outline` | `FontAwesomeIcons.circleInfo` | Info outline | + +### UI Elements +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.search` | `FontAwesomeIcons.magnifyingGlass` | Search | +| `Icons.filter_list` | `FontAwesomeIcons.filter` | Filter | +| `Icons.sort` | `FontAwesomeIcons.arrowDownAZ` | Sort | +| `Icons.more_vert` | `FontAwesomeIcons.ellipsisVertical` | More options | +| `Icons.more_horiz` | `FontAwesomeIcons.ellipsis` | More horizontal | + +### Calendar & Time +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.calendar_today` | `FontAwesomeIcons.calendar` | Calendar | +| `Icons.date_range` | `FontAwesomeIcons.calendarDays` | Date range | +| `Icons.access_time` | `FontAwesomeIcons.clock` | Time | + +### Payment Icons +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.payment` | `FontAwesomeIcons.creditCard` | Credit card | +| `Icons.payments` | `FontAwesomeIcons.creditCard` | Payments | +| `Icons.payments_outlined` | `FontAwesomeIcons.creditCard` | Payment outline | +| `Icons.account_balance` | `FontAwesomeIcons.buildingColumns` | Bank | +| `Icons.account_balance_outlined` | `FontAwesomeIcons.buildingColumns` | Bank outline | +| `Icons.account_balance_wallet` | `FontAwesomeIcons.wallet` | Wallet | + +### Media & Images +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.image` | `FontAwesomeIcons.image` | Image | +| `Icons.image_not_supported` | `FontAwesomeIcons.imageSlash` | No image | +| `Icons.photo_camera` | `FontAwesomeIcons.camera` | Camera | +| `Icons.photo_library` | `FontAwesomeIcons.images` | Gallery | + +### User & Profile +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.person` | `FontAwesomeIcons.user` | User | +| `Icons.person_outline` | `FontAwesomeIcons.user` | User outline | +| `Icons.account_circle` | `FontAwesomeIcons.circleUser` | Account | + +### Communication +| Material Icon | FontAwesome Icon | Usage | +|---------------|------------------|-------| +| `Icons.chat` | `FontAwesomeIcons.message` | Chat | +| `Icons.chat_bubble` | `FontAwesomeIcons.commentDots` | Chat bubble | +| `Icons.notifications` | `FontAwesomeIcons.bell` | Notifications | +| `Icons.phone` | `FontAwesomeIcons.phone` | Phone | +| `Icons.email` | `FontAwesomeIcons.envelope` | Email | + +## Usage Examples + +### Before (Material Icons) +```dart +Icon(Icons.shopping_cart, size: 24, color: Colors.blue) +Icon(Icons.add, size: 16) +IconButton( + icon: Icon(Icons.delete_outline), + onPressed: () {}, +) +``` + +### After (FontAwesome) +```dart +FaIcon(FontAwesomeIcons.cartShopping, size: 24, color: Colors.blue) +FaIcon(FontAwesomeIcons.plus, size: 16) +IconButton( + icon: FaIcon(FontAwesomeIcons.trashCan), + onPressed: () {}, +) +``` + +## Size Guidelines + +FontAwesome icons tend to be slightly larger than Material icons at the same size. Recommended adjustments: + +| Material Size | FontAwesome Size | Notes | +|---------------|------------------|-------| +| 24 (default) | 20-22 | Standard icons | +| 20 | 18 | Small icons | +| 16 | 14-15 | Tiny icons | +| 48 | 40-44 | Large icons | +| 64 | 56-60 | Extra large | + +## Color Usage + +FontAwesome icons use the same color properties: +```dart +// Both work the same +Icon(Icons.add, color: AppColors.primaryBlue) +FaIcon(FontAwesomeIcons.plus, color: AppColors.primaryBlue) +``` + +## Common Issues & Solutions + +### Issue 1: Icon Size Mismatch +**Problem**: FontAwesome icons appear larger than expected +**Solution**: Reduce size by 2-4 pixels +```dart +// Before +Icon(Icons.add, size: 24) + +// After +FaIcon(FontAwesomeIcons.plus, size: 20) +``` + +### Issue 2: Icon Alignment +**Problem**: Icons not centered properly +**Solution**: Use `IconTheme` or wrap in `SizedBox` +```dart +SizedBox( + width: 24, + height: 24, + child: FaIcon(FontAwesomeIcons.plus, size: 18), +) +``` + +### Issue 3: Icon Not Found +**Problem**: Icon name doesn't match +**Solution**: Check FontAwesome documentation or use search +```dart +// Use camelCase, not snake_case +// ❌ FontAwesomeIcons.shopping_cart +// ✅ FontAwesomeIcons.cartShopping +``` + +## Migration Checklist + +- [x] Add `font_awesome_flutter` to pubspec.yaml +- [x] Run `flutter pub get` +- [ ] Update all `Icons.*` to `FontAwesomeIcons.*` +- [ ] Replace `Icon()` with `FaIcon()` +- [ ] Adjust icon sizes as needed +- [ ] Test visual appearance +- [ ] Update documentation + +## Cart Feature Icon Updates + +### Files to Update +1. `lib/features/cart/presentation/pages/cart_page.dart` +2. `lib/features/cart/presentation/pages/checkout_page.dart` +3. `lib/features/cart/presentation/widgets/cart_item_widget.dart` +4. `lib/features/cart/presentation/widgets/payment_method_section.dart` +5. `lib/features/cart/presentation/widgets/checkout_date_picker_field.dart` + +### Specific Replacements + +#### cart_page.dart +- `Icons.arrow_back` → `FontAwesomeIcons.arrowLeft` +- `Icons.delete_outline` → `FontAwesomeIcons.trashCan` +- `Icons.error_outline` → `FontAwesomeIcons.circleExclamation` +- `Icons.refresh` → `FontAwesomeIcons.arrowsRotate` +- `Icons.shopping_cart_outlined` → `FontAwesomeIcons.cartShopping` +- `Icons.shopping_bag_outlined` → `FontAwesomeIcons.bagShopping` +- `Icons.check` → `FontAwesomeIcons.check` + +#### cart_item_widget.dart +- `Icons.image_not_supported` → `FontAwesomeIcons.imageSlash` +- `Icons.remove` → `FontAwesomeIcons.minus` +- `Icons.add` → `FontAwesomeIcons.plus` +- `Icons.check` → `FontAwesomeIcons.check` + +#### payment_method_section.dart +- `Icons.account_balance_outlined` → `FontAwesomeIcons.buildingColumns` +- `Icons.payments_outlined` → `FontAwesomeIcons.creditCard` + +#### checkout_date_picker_field.dart +- `Icons.calendar_today` → `FontAwesomeIcons.calendar` + +## Resources + +- [FontAwesome Flutter Package](https://pub.dev/packages/font_awesome_flutter) +- [FontAwesome Icon Gallery](https://fontawesome.com/icons) +- [FontAwesome Flutter Gallery](https://github.com/fluttercommunity/font_awesome_flutter/blob/master/GALLERY.md) diff --git a/lib/core/widgets/bottom_nav_bar.dart b/lib/core/widgets/bottom_nav_bar.dart index d6afd63..41d2f6e 100644 --- a/lib/core/widgets/bottom_nav_bar.dart +++ b/lib/core/widgets/bottom_nav_bar.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/theme/colors.dart'; @@ -58,17 +59,17 @@ class CustomBottomNavBar extends StatelessWidget { selectedFontSize: 12, unselectedFontSize: 12, items: const [ - BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'), + BottomNavigationBarItem(icon: FaIcon(FontAwesomeIcons.house, size: 20), label: 'Home'), BottomNavigationBarItem( - icon: Icon(Icons.shopping_bag), + icon: FaIcon(FontAwesomeIcons.bagShopping, size: 20), label: 'Products', ), BottomNavigationBarItem( - icon: Icon(Icons.card_membership), + icon: FaIcon(FontAwesomeIcons.gift, size: 20), label: 'Loyalty', ), - BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Account'), - BottomNavigationBarItem(icon: Icon(Icons.menu), label: 'More'), + BottomNavigationBarItem(icon: FaIcon(FontAwesomeIcons.user, size: 20), label: 'Account'), + BottomNavigationBarItem(icon: FaIcon(FontAwesomeIcons.bars, size: 20), label: 'More'), ], ); } diff --git a/lib/core/widgets/empty_state.dart b/lib/core/widgets/empty_state.dart index 0502b9c..31dcc9a 100644 --- a/lib/core/widgets/empty_state.dart +++ b/lib/core/widgets/empty_state.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/theme/colors.dart'; @@ -54,7 +55,7 @@ class EmptyState extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Icon(icon, size: iconSize, color: AppColors.grey500), + FaIcon(icon, size: iconSize, color: AppColors.grey500), const SizedBox(height: 16), Text( title, diff --git a/lib/core/widgets/error_widget.dart b/lib/core/widgets/error_widget.dart index 9c2e5a9..c57e393 100644 --- a/lib/core/widgets/error_widget.dart +++ b/lib/core/widgets/error_widget.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/theme/colors.dart'; @@ -43,8 +44,8 @@ class CustomErrorWidget extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Icon( - icon ?? Icons.error_outline, + FaIcon( + icon ?? FontAwesomeIcons.circleExclamation, size: iconSize, color: AppColors.danger, ), @@ -62,7 +63,7 @@ class CustomErrorWidget extends StatelessWidget { const SizedBox(height: 24), ElevatedButton.icon( onPressed: onRetry, - icon: const Icon(Icons.refresh), + icon: const FaIcon(FontAwesomeIcons.arrowsRotate, size: 16), label: const Text('Retry'), style: ElevatedButton.styleFrom( backgroundColor: AppColors.primaryBlue, diff --git a/lib/core/widgets/floating_chat_button.dart b/lib/core/widgets/floating_chat_button.dart index 1e3132e..7ed9e5b 100644 --- a/lib/core/widgets/floating_chat_button.dart +++ b/lib/core/widgets/floating_chat_button.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/theme/colors.dart'; @@ -43,10 +44,10 @@ class ChatFloatingButton extends StatelessWidget { onPressed: onPressed, backgroundColor: AppColors.accentCyan, elevation: 6, - child: const Icon( - Icons.chat_bubble_outline, + child: const FaIcon( + FontAwesomeIcons.message, color: Colors.white, - size: 24, + size: 22, ), ), if (unreadCount != null && unreadCount! > 0) diff --git a/lib/features/auth/presentation/pages/business_unit_selection_page.dart b/lib/features/auth/presentation/pages/business_unit_selection_page.dart index fca5944..2c944a4 100644 --- a/lib/features/auth/presentation/pages/business_unit_selection_page.dart +++ b/lib/features/auth/presentation/pages/business_unit_selection_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/router/app_router.dart'; @@ -162,7 +163,7 @@ class _BusinessUnitSelectionPageState extends State { backgroundColor: AppColors.white, elevation: AppBarSpecs.elevation, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -176,7 +177,7 @@ class _BusinessUnitSelectionPageState extends State { centerTitle: false, actions: [ IconButton( - icon: const Icon(Icons.info_outline, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.circleInfo, color: Colors.black, size: 20), onPressed: _showInfoDialog, ), const SizedBox(width: AppSpacing.sm), @@ -331,7 +332,7 @@ class _BusinessUnitSelectionPageState extends State { borderRadius: BorderRadius.circular(8), ), child: Icon( - Icons.business, + FontAwesomeIcons.building, color: isSelected ? AppColors.primaryBlue : AppColors.grey500, @@ -387,7 +388,7 @@ class _BusinessUnitSelectionPageState extends State { ), child: isSelected ? const Icon( - Icons.circle, + FontAwesomeIcons.solidCircle, size: 10, color: AppColors.white, ) diff --git a/lib/features/auth/presentation/pages/forgot_password_page.dart b/lib/features/auth/presentation/pages/forgot_password_page.dart index 02edf8e..af198dc 100644 --- a/lib/features/auth/presentation/pages/forgot_password_page.dart +++ b/lib/features/auth/presentation/pages/forgot_password_page.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -147,7 +148,7 @@ class _ForgotPasswordPageState extends ConsumerState { ), centerTitle: false, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), actions: const [ @@ -205,7 +206,7 @@ class _ForgotPasswordPageState extends ConsumerState { shape: BoxShape.circle, ), child: const Icon( - Icons.lock_reset, + FontAwesomeIcons.key, size: 50, color: AppColors.primaryBlue, ), @@ -349,7 +350,7 @@ class _ForgotPasswordPageState extends ConsumerState { child: TextButton.icon( onPressed: _showSupport, icon: const Icon( - Icons.headset_mic, + FontAwesomeIcons.headset, size: AppIconSize.sm, color: AppColors.primaryBlue, ), diff --git a/lib/features/auth/presentation/pages/login_page.dart b/lib/features/auth/presentation/pages/login_page.dart index 22de62c..a248789 100644 --- a/lib/features/auth/presentation/pages/login_page.dart +++ b/lib/features/auth/presentation/pages/login_page.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/router/app_router.dart'; @@ -329,13 +330,13 @@ class _LoginPageState extends ConsumerState { color: AppColors.grey500, ), prefixIcon: const Icon( - Icons.lock, + FontAwesomeIcons.lock, color: AppColors.primaryBlue, size: AppIconSize.md, ), suffixIcon: IconButton( icon: Icon( - isPasswordVisible ? Icons.visibility : Icons.visibility_off, + isPasswordVisible ? FontAwesomeIcons.eye : FontAwesomeIcons.eyeSlash, color: AppColors.grey500, size: AppIconSize.md, ), @@ -538,7 +539,7 @@ class _LoginPageState extends ConsumerState { child: TextButton.icon( onPressed: _showSupport, icon: const Icon( - Icons.headset_mic, + FontAwesomeIcons.headset, size: AppIconSize.sm, color: AppColors.primaryBlue, ), diff --git a/lib/features/auth/presentation/pages/otp_verification_page.dart b/lib/features/auth/presentation/pages/otp_verification_page.dart index b37e299..6a28544 100644 --- a/lib/features/auth/presentation/pages/otp_verification_page.dart +++ b/lib/features/auth/presentation/pages/otp_verification_page.dart @@ -9,6 +9,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; @@ -242,7 +243,7 @@ class _OtpVerificationPageState extends ConsumerState { backgroundColor: AppColors.white, elevation: AppBarSpecs.elevation, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -280,7 +281,7 @@ class _OtpVerificationPageState extends ConsumerState { shape: BoxShape.circle, ), child: const Icon( - Icons.shield_outlined, + FontAwesomeIcons.shieldHalved, size: 36, color: AppColors.white, ), diff --git a/lib/features/auth/presentation/pages/register_page.dart b/lib/features/auth/presentation/pages/register_page.dart index f8fb4ce..84f3ff0 100644 --- a/lib/features/auth/presentation/pages/register_page.dart +++ b/lib/features/auth/presentation/pages/register_page.dart @@ -9,6 +9,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:image_picker/image_picker.dart'; @@ -174,12 +175,12 @@ class _RegisterPageState extends ConsumerState { child: Wrap( children: [ ListTile( - leading: const Icon(Icons.camera_alt), + leading: const FaIcon(FontAwesomeIcons.camera, size: 20), title: const Text('Chụp ảnh'), onTap: () => Navigator.pop(context, ImageSource.camera), ), ListTile( - leading: const Icon(Icons.photo_library), + leading: const FaIcon(FontAwesomeIcons.images, size: 20), title: const Text('Chọn từ thư viện'), onTap: () => Navigator.pop(context, ImageSource.gallery), ), @@ -392,7 +393,7 @@ class _RegisterPageState extends ConsumerState { backgroundColor: AppColors.white, elevation: AppBarSpecs.elevation, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -470,7 +471,7 @@ class _RegisterPageState extends ConsumerState { textInputAction: TextInputAction.next, decoration: _buildInputDecoration( hintText: 'Nhập họ và tên', - prefixIcon: Icons.person, + prefixIcon: FontAwesomeIcons.user, ), validator: (value) => Validators.minLength( value, @@ -498,7 +499,7 @@ class _RegisterPageState extends ConsumerState { textInputAction: TextInputAction.next, decoration: _buildInputDecoration( hintText: 'Nhập email', - prefixIcon: Icons.email, + prefixIcon: FontAwesomeIcons.envelope, ), validator: Validators.email, ), @@ -513,12 +514,12 @@ class _RegisterPageState extends ConsumerState { textInputAction: TextInputAction.done, decoration: _buildInputDecoration( hintText: 'Tạo mật khẩu mới', - prefixIcon: Icons.lock, + prefixIcon: FontAwesomeIcons.lock, suffixIcon: IconButton( icon: Icon( _passwordVisible - ? Icons.visibility - : Icons.visibility_off, + ? FontAwesomeIcons.eye + : FontAwesomeIcons.eyeSlash, color: AppColors.grey500, ), onPressed: () { @@ -560,7 +561,7 @@ class _RegisterPageState extends ConsumerState { textInputAction: TextInputAction.next, decoration: _buildInputDecoration( hintText: 'Nhập tên công ty (không bắt buộc)', - prefixIcon: Icons.business, + prefixIcon: FontAwesomeIcons.building, ), ), const SizedBox(height: AppSpacing.md), @@ -761,7 +762,7 @@ class _RegisterPageState extends ConsumerState { value: _selectedRole, decoration: _buildInputDecoration( hintText: 'Chọn vai trò', - prefixIcon: Icons.work, + prefixIcon: FontAwesomeIcons.briefcase, ), items: groups .map( diff --git a/lib/features/auth/presentation/widgets/file_upload_card.dart b/lib/features/auth/presentation/widgets/file_upload_card.dart index 2c2212f..3100b55 100644 --- a/lib/features/auth/presentation/widgets/file_upload_card.dart +++ b/lib/features/auth/presentation/widgets/file_upload_card.dart @@ -6,6 +6,7 @@ library; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -154,7 +155,7 @@ class FileUploadCard extends StatelessWidget { height: 50, color: AppColors.grey100, child: const Icon( - Icons.broken_image, + FontAwesomeIcons.image, color: AppColors.grey500, size: 24, ), @@ -203,7 +204,7 @@ class FileUploadCard extends StatelessWidget { // Remove button IconButton( - icon: const Icon(Icons.close, color: AppColors.danger, size: 20), + icon: const FaIcon(FontAwesomeIcons.xmark, color: AppColors.danger, size: 18), onPressed: onRemove, padding: EdgeInsets.zero, constraints: const BoxConstraints(), diff --git a/lib/features/auth/presentation/widgets/phone_input_field.dart b/lib/features/auth/presentation/widgets/phone_input_field.dart index 583069d..cdea2e8 100644 --- a/lib/features/auth/presentation/widgets/phone_input_field.dart +++ b/lib/features/auth/presentation/widgets/phone_input_field.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -93,7 +94,7 @@ class PhoneInputField extends StatelessWidget { color: AppColors.grey500, ), prefixIcon: const Icon( - Icons.phone, + FontAwesomeIcons.phone, color: AppColors.primaryBlue, size: AppIconSize.md, ), diff --git a/lib/features/auth/presentation/widgets/role_dropdown.dart b/lib/features/auth/presentation/widgets/role_dropdown.dart index f7d3c8b..67da869 100644 --- a/lib/features/auth/presentation/widgets/role_dropdown.dart +++ b/lib/features/auth/presentation/widgets/role_dropdown.dart @@ -4,6 +4,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -62,7 +63,7 @@ class RoleDropdown extends StatelessWidget { color: AppColors.grey500, ), prefixIcon: const Icon( - Icons.work, + FontAwesomeIcons.briefcase, color: AppColors.primaryBlue, size: AppIconSize.md, ), @@ -104,7 +105,7 @@ class RoleDropdown extends StatelessWidget { ], onChanged: onChanged, validator: validator, - icon: const Icon(Icons.arrow_drop_down, color: AppColors.grey500), + icon: const FaIcon(FontAwesomeIcons.chevronDown, color: AppColors.grey500, size: 16), dropdownColor: AppColors.white, style: const TextStyle( fontSize: InputFieldSpecs.fontSize, diff --git a/lib/features/cart/presentation/pages/cart_page.dart b/lib/features/cart/presentation/pages/cart_page.dart index 83adcd7..d9a2fed 100644 --- a/lib/features/cart/presentation/pages/cart_page.dart +++ b/lib/features/cart/presentation/pages/cart_page.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/constants/ui_constants.dart'; @@ -66,7 +67,7 @@ class _CartPageState extends ConsumerState { backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: Text( @@ -81,7 +82,7 @@ class _CartPageState extends ConsumerState { if (cartState.isNotEmpty) IconButton( icon: Icon( - Icons.delete_outline, + FontAwesomeIcons.trashCan, color: hasSelection ? AppColors.danger : AppColors.grey500, ), onPressed: hasSelection @@ -326,7 +327,7 @@ class _CartPageState extends ConsumerState { color: AppColors.danger.withValues(alpha: 0.1), child: Row( children: [ - const Icon(Icons.error_outline, color: AppColors.danger, size: 20), + const FaIcon(FontAwesomeIcons.circleExclamation, color: AppColors.danger, size: 18), const SizedBox(width: 8), Expanded( child: Text( @@ -345,7 +346,7 @@ class _CartPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(Icons.error_outline, size: 64, color: AppColors.danger), + const FaIcon(FontAwesomeIcons.circleExclamation, size: 56, color: AppColors.danger), const SizedBox(height: 16), const Text( 'Không thể tải giỏ hàng', @@ -365,7 +366,7 @@ class _CartPageState extends ConsumerState { onPressed: () { ref.read(cartProvider.notifier).initialize(); }, - icon: const Icon(Icons.refresh), + icon: const FaIcon(FontAwesomeIcons.arrowsRotate, size: 20), label: const Text('Thử lại'), ), ], @@ -380,7 +381,7 @@ class _CartPageState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( - Icons.shopping_cart_outlined, + FontAwesomeIcons.cartShopping, size: 80, color: AppColors.grey500.withValues(alpha: 0.5), ), @@ -399,7 +400,7 @@ class _CartPageState extends ConsumerState { const SizedBox(height: 24), ElevatedButton.icon( onPressed: () => context.go(RouteNames.products), - icon: const Icon(Icons.shopping_bag_outlined), + icon: const FaIcon(FontAwesomeIcons.bagShopping, size: 20), label: const Text('Xem sản phẩm'), ), ], @@ -472,7 +473,7 @@ class _CustomCheckbox extends StatelessWidget { ), child: value ? const Icon( - Icons.check, + FontAwesomeIcons.check, size: 16, color: AppColors.white, ) diff --git a/lib/features/cart/presentation/pages/checkout_page.dart b/lib/features/cart/presentation/pages/checkout_page.dart index b7d71c7..b5c60d9 100644 --- a/lib/features/cart/presentation/pages/checkout_page.dart +++ b/lib/features/cart/presentation/pages/checkout_page.dart @@ -12,6 +12,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -95,7 +96,7 @@ class CheckoutPage extends HookConsumerWidget { backgroundColor: Colors.white, elevation: 0, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( diff --git a/lib/features/cart/presentation/widgets/cart_item_widget.dart b/lib/features/cart/presentation/widgets/cart_item_widget.dart index 7091c91..99a7e8c 100644 --- a/lib/features/cart/presentation/widgets/cart_item_widget.dart +++ b/lib/features/cart/presentation/widgets/cart_item_widget.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/core/theme/typography.dart'; @@ -135,8 +136,8 @@ class _CartItemWidgetState extends ConsumerState { width: 100, height: 100, color: AppColors.grey100, - child: const Icon( - Icons.image_not_supported, + child: const FaIcon( + FontAwesomeIcons.image, color: AppColors.grey500, size: 32, ), @@ -181,7 +182,7 @@ class _CartItemWidgetState extends ConsumerState { children: [ // Decrease button _QuantityButton( - icon: Icons.remove, + icon: FontAwesomeIcons.minus, onPressed: () { ref .read(cartProvider.notifier) @@ -239,7 +240,7 @@ class _CartItemWidgetState extends ConsumerState { // Increase button _QuantityButton( - icon: Icons.add, + icon: FontAwesomeIcons.plus, onPressed: () { ref .read(cartProvider.notifier) @@ -319,7 +320,7 @@ class _CustomCheckbox extends StatelessWidget { ), child: value ? const Icon( - Icons.check, + FontAwesomeIcons.check, size: 14, color: AppColors.white, ) diff --git a/lib/features/cart/presentation/widgets/checkout_date_picker_field.dart b/lib/features/cart/presentation/widgets/checkout_date_picker_field.dart index 0f992b3..985fbeb 100644 --- a/lib/features/cart/presentation/widgets/checkout_date_picker_field.dart +++ b/lib/features/cart/presentation/widgets/checkout_date_picker_field.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -69,7 +70,7 @@ class CheckoutDatePickerField extends HookWidget { ), ), const Icon( - Icons.calendar_today, + FontAwesomeIcons.calendar, size: 20, color: AppColors.grey500, ), diff --git a/lib/features/cart/presentation/widgets/payment_method_section.dart b/lib/features/cart/presentation/widgets/payment_method_section.dart index 46555d7..1b542c7 100644 --- a/lib/features/cart/presentation/widgets/payment_method_section.dart +++ b/lib/features/cart/presentation/widgets/payment_method_section.dart @@ -7,6 +7,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -66,7 +67,7 @@ class PaymentMethodSection extends HookWidget { ), const SizedBox(width: 12), const Icon( - Icons.account_balance_outlined, + FontAwesomeIcons.buildingColumns, color: AppColors.grey500, size: 24, ), @@ -117,7 +118,7 @@ class PaymentMethodSection extends HookWidget { ), const SizedBox(width: 12), const Icon( - Icons.payments_outlined, + FontAwesomeIcons.creditCard, color: AppColors.grey500, size: 24, ), diff --git a/lib/features/favorites/presentation/pages/favorites_page.dart b/lib/features/favorites/presentation/pages/favorites_page.dart index aa81371..8433656 100644 --- a/lib/features/favorites/presentation/pages/favorites_page.dart +++ b/lib/features/favorites/presentation/pages/favorites_page.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:shimmer/shimmer.dart'; import 'package:worker/core/constants/ui_constants.dart'; @@ -82,7 +83,7 @@ class FavoritesPage extends ConsumerWidget { backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text('Yêu thích', style: TextStyle(color: Colors.black)), @@ -110,7 +111,7 @@ class FavoritesPage extends ConsumerWidget { // Clear all button if (favoriteCount > 0) IconButton( - icon: const Icon(Icons.delete_outline, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.trashCan, color: Colors.black, size: 20), tooltip: 'Xóa tất cả', onPressed: () => _showClearAllDialog(context, ref, favoriteCount), ), @@ -165,8 +166,8 @@ class _EmptyState extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ // Large icon - Icon( - Icons.favorite_border, + FaIcon( + FontAwesomeIcons.heart, size: 80.0, color: AppColors.grey500.withValues(alpha: 0.5), ), @@ -360,8 +361,8 @@ class _ErrorState extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ // Error icon - Icon( - Icons.error_outline, + FaIcon( + FontAwesomeIcons.circleExclamation, size: 80.0, color: AppColors.danger.withValues(alpha: 0.7), ), @@ -406,7 +407,7 @@ class _ErrorState extends StatelessWidget { borderRadius: BorderRadius.circular(AppRadius.button), ), ), - icon: const Icon(Icons.refresh), + icon: const FaIcon(FontAwesomeIcons.arrowsRotate, size: 18), label: const Text( 'Thử lại', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600), diff --git a/lib/features/favorites/presentation/widgets/favorite_product_card.dart b/lib/features/favorites/presentation/widgets/favorite_product_card.dart index bc350a4..97204a6 100644 --- a/lib/features/favorites/presentation/widgets/favorite_product_card.dart +++ b/lib/features/favorites/presentation/widgets/favorite_product_card.dart @@ -7,6 +7,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import 'package:shimmer/shimmer.dart'; @@ -106,8 +107,8 @@ class FavoriteProductCard extends ConsumerWidget { ), errorWidget: (context, url, error) => Container( color: AppColors.grey100, - child: const Icon( - Icons.image_not_supported, + child: const FaIcon( + FontAwesomeIcons.image, size: 48.0, color: AppColors.grey500, ), @@ -132,10 +133,10 @@ class FavoriteProductCard extends ConsumerWidget { ], ), child: IconButton( - icon: const Icon( - Icons.favorite, + icon: const FaIcon( + FontAwesomeIcons.solidHeart, color: AppColors.danger, - size: 20.0, + size: 18.0, ), padding: const EdgeInsets.all(AppSpacing.sm), constraints: const BoxConstraints( diff --git a/lib/features/home/presentation/pages/home_page.dart b/lib/features/home/presentation/pages/home_page.dart index bb1c37b..a587540 100644 --- a/lib/features/home/presentation/pages/home_page.dart +++ b/lib/features/home/presentation/pages/home_page.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/router/app_router.dart'; import 'package:worker/core/theme/colors.dart'; @@ -90,8 +91,8 @@ class _HomePageState extends ConsumerState { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const Icon( - Icons.error_outline, + const FaIcon( + FontAwesomeIcons.circleExclamation, color: AppColors.danger, size: 48, ), @@ -149,18 +150,18 @@ class _HomePageState extends ConsumerState { title: 'Sản phẩm & Giỏ hàng', actions: [ QuickAction( - icon: Icons.grid_view, + icon: FontAwesomeIcons.grip, label: 'Sản phẩm', onTap: () => context.pushNamed(RouteNames.products), ), QuickAction( - icon: Icons.shopping_cart, + icon: FontAwesomeIcons.cartShopping, label: 'Giỏ hàng', badge: cartItemCount > 0 ? '$cartItemCount' : null, onTap: () => context.push(RouteNames.cart), ), QuickAction( - icon: Icons.favorite, + icon: FontAwesomeIcons.heart, label: 'Yêu thích', onTap: () => context.push(RouteNames.favorites), ), @@ -172,17 +173,17 @@ class _HomePageState extends ConsumerState { title: 'Đơn hàng & thanh toán', actions: [ QuickAction( - icon: Icons.description, + icon: FontAwesomeIcons.fileLines, label: 'Chính sách giá', onTap: () => context.push(RouteNames.pricePolicy), ), QuickAction( - icon: Icons.inventory_2, + icon: FontAwesomeIcons.boxesStacked, label: 'Đơn hàng', onTap: () => context.push(RouteNames.orders), ), QuickAction( - icon: Icons.receipt_long, + icon: FontAwesomeIcons.receipt, label: 'Thanh toán', onTap: () => context.push(RouteNames.payments), ), @@ -194,18 +195,18 @@ class _HomePageState extends ConsumerState { title: 'Khách hàng thân thiết', actions: [ QuickAction( - icon: Icons.add_circle_outline, + icon: FontAwesomeIcons.circlePlus, label: 'Ghi nhận điểm', onTap: () => _showComingSoon(context, 'Ghi nhận điểm', l10n), ), QuickAction( - icon: Icons.card_giftcard, + icon: FontAwesomeIcons.gift, label: 'Đổi quà', onTap: () => context.push('/loyalty/rewards'), ), QuickAction( - icon: Icons.history, + icon: FontAwesomeIcons.clockRotateLeft, label: 'Lịch sử điểm', onTap: () => context.push(RouteNames.pointsHistory), ), @@ -217,12 +218,12 @@ class _HomePageState extends ConsumerState { title: 'Nhà mẫu, dự án & tin tức', actions: [ QuickAction( - icon: Icons.home_work, + icon: FontAwesomeIcons.houseCircleCheck, label: 'Nhà mẫu', onTap: () => context.push(RouteNames.modelHouses), ), QuickAction( - icon: Icons.business, + icon: FontAwesomeIcons.building, label: 'Đăng ký dự án', onTap: () => _showComingSoon(context, 'Đăng ký dự án', l10n), diff --git a/lib/features/home/presentation/widgets/promotion_slider.dart b/lib/features/home/presentation/widgets/promotion_slider.dart index 511833e..c62d867 100644 --- a/lib/features/home/presentation/widgets/promotion_slider.dart +++ b/lib/features/home/presentation/widgets/promotion_slider.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/router/app_router.dart'; import 'package:worker/core/theme/colors.dart'; @@ -127,8 +128,8 @@ class _PromotionCard extends StatelessWidget { errorWidget: (context, url, error) => Container( height: 140, color: AppColors.grey100, - child: const Icon( - Icons.image_not_supported, + child: const FaIcon( + FontAwesomeIcons.image, size: 48, color: AppColors.grey500, ), diff --git a/lib/features/loyalty/presentation/pages/loyalty_page.dart b/lib/features/loyalty/presentation/pages/loyalty_page.dart index a74e220..df58182 100644 --- a/lib/features/loyalty/presentation/pages/loyalty_page.dart +++ b/lib/features/loyalty/presentation/pages/loyalty_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; @@ -282,37 +283,37 @@ class LoyaltyPage extends ConsumerWidget { List _buildLoyaltyMenu(BuildContext context) { final menuItems = [ { - 'icon': Icons.card_giftcard, + 'icon': FontAwesomeIcons.gift, 'title': 'Đổi quà tặng', 'subtitle': 'Sử dụng điểm để đổi quà hấp dẫn', 'route': '/loyalty/rewards', }, { - 'icon': Icons.add_circle_outline, + 'icon': FontAwesomeIcons.circlePlus, 'title': 'Ghi nhận điểm', 'subtitle': 'Gửi hóa đơn để nhận điểm thưởng', 'route': null, }, { - 'icon': Icons.history, + 'icon': FontAwesomeIcons.clockRotateLeft, 'title': 'Lịch sử điểm', 'subtitle': 'Xem chi tiết cộng/trừ điểm', 'route': '/loyalty/points-history', }, { - 'icon': Icons.person_add, + 'icon': FontAwesomeIcons.userPlus, 'title': 'Giới thiệu bạn bè', 'subtitle': 'Nhận thưởng khi giới thiệu thành công', 'route': null, }, { - 'icon': Icons.inventory_2_outlined, + 'icon': FontAwesomeIcons.boxOpen, 'title': 'Quà của tôi', 'subtitle': 'Xem voucher và quà tặng đã đổi', 'route': null, }, { - 'icon': Icons.diamond_outlined, + 'icon': FontAwesomeIcons.gem, 'title': 'Quyền lợi hội viên', 'subtitle': 'Xem các ưu đãi dành cho hạng của bạn', 'route': null, @@ -386,7 +387,7 @@ class LoyaltyPage extends ConsumerWidget { // Arrow const Icon( - Icons.chevron_right, + FontAwesomeIcons.chevronRight, color: AppColors.grey500, size: 20, ), @@ -440,7 +441,7 @@ class LoyaltyPage extends ConsumerWidget { child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Icon(Icons.check_circle, size: 20, color: Color(0xFF4A00E0)), + const FaIcon(FontAwesomeIcons.solidCircleCheck, size: 18, color: Color(0xFF4A00E0)), const SizedBox(width: 12), Expanded( child: Text( diff --git a/lib/features/loyalty/presentation/pages/points_history_page.dart b/lib/features/loyalty/presentation/pages/points_history_page.dart index f4f8c0d..26cb0bf 100644 --- a/lib/features/loyalty/presentation/pages/points_history_page.dart +++ b/lib/features/loyalty/presentation/pages/points_history_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/constants/ui_constants.dart'; @@ -32,7 +33,7 @@ class PointsHistoryPage extends ConsumerWidget { backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -101,7 +102,7 @@ class PointsHistoryPage extends ConsumerWidget { color: AppColors.grey900, ), ), - Icon(Icons.filter_list, color: AppColors.primaryBlue, size: 20), + FaIcon(FontAwesomeIcons.sliders, color: AppColors.primaryBlue, size: 18), ], ), const SizedBox(height: 8), @@ -263,8 +264,8 @@ class PointsHistoryPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.history, + FaIcon( + FontAwesomeIcons.clockRotateLeft, size: 80, color: AppColors.grey500.withValues(alpha: 0.5), ), @@ -294,8 +295,8 @@ class PointsHistoryPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.error_outline, + FaIcon( + FontAwesomeIcons.circleExclamation, size: 80, color: AppColors.danger.withValues(alpha: 0.7), ), diff --git a/lib/features/loyalty/presentation/pages/rewards_page.dart b/lib/features/loyalty/presentation/pages/rewards_page.dart index 3841bd5..03075d4 100644 --- a/lib/features/loyalty/presentation/pages/rewards_page.dart +++ b/lib/features/loyalty/presentation/pages/rewards_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/constants/ui_constants.dart'; @@ -34,7 +35,7 @@ class RewardsPage extends ConsumerWidget { backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -47,7 +48,7 @@ class RewardsPage extends ConsumerWidget { centerTitle: false, actions: [ IconButton( - icon: const Icon(Icons.info_outline, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.circleInfo, color: Colors.black, size: 20), onPressed: () => _showInfoDialog(context), ), const SizedBox(width: AppSpacing.sm), @@ -168,7 +169,7 @@ class RewardsPage extends ConsumerWidget { children: [ const Padding( padding: EdgeInsets.only(top: 6), - child: Icon(Icons.circle, size: 6, color: AppColors.grey500), + child: FaIcon(FontAwesomeIcons.solidCircle, size: 6, color: AppColors.grey500), ), const SizedBox(width: 12), Expanded( @@ -299,8 +300,8 @@ class RewardsPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.card_giftcard_outlined, + FaIcon( + FontAwesomeIcons.gift, size: 64, color: AppColors.grey500, ), @@ -434,7 +435,7 @@ class RewardsPage extends ConsumerWidget { SnackBar( content: Row( children: [ - const Icon(Icons.check_circle, color: Colors.white), + const FaIcon(FontAwesomeIcons.solidCircleCheck, color: Colors.white, size: 20), const SizedBox(width: 12), Expanded(child: Text('Đổi quà "${gift.name}" thành công!')), ], diff --git a/lib/features/loyalty/presentation/widgets/points_balance_card.dart b/lib/features/loyalty/presentation/widgets/points_balance_card.dart index 3467773..7a720e7 100644 --- a/lib/features/loyalty/presentation/widgets/points_balance_card.dart +++ b/lib/features/loyalty/presentation/widgets/points_balance_card.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/loyalty/presentation/providers/loyalty_points_provider.dart'; @@ -75,8 +76,8 @@ class PointsBalanceCard extends ConsumerWidget { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.info_outline, + FaIcon( + FontAwesomeIcons.circleInfo, size: 14, color: Colors.white.withValues(alpha: 0.8), ), diff --git a/lib/features/loyalty/presentation/widgets/reward_card.dart b/lib/features/loyalty/presentation/widgets/reward_card.dart index 721675f..2ff8400 100644 --- a/lib/features/loyalty/presentation/widgets/reward_card.dart +++ b/lib/features/loyalty/presentation/widgets/reward_card.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/loyalty/domain/entities/gift_catalog.dart'; @@ -96,9 +97,9 @@ class RewardCard extends ConsumerWidget { onPressed: hasEnoughPoints && gift.isAvailable ? onRedeem : null, - icon: Icon( - Icons.card_giftcard, - size: 16, + icon: FaIcon( + FontAwesomeIcons.gift, + size: 14, color: hasEnoughPoints && gift.isAvailable ? Colors.white : AppColors.grey500, @@ -155,8 +156,8 @@ class RewardCard extends ConsumerWidget { ), errorWidget: (context, url, error) => Container( color: AppColors.grey100, - child: const Icon( - Icons.card_giftcard, + child: const FaIcon( + FontAwesomeIcons.gift, size: 48, color: AppColors.grey500, ), @@ -164,8 +165,8 @@ class RewardCard extends ConsumerWidget { ) : Container( color: AppColors.grey100, - child: const Icon( - Icons.card_giftcard, + child: const FaIcon( + FontAwesomeIcons.gift, size: 48, color: AppColors.grey500, ), diff --git a/lib/features/news/presentation/pages/news_detail_page.dart b/lib/features/news/presentation/pages/news_detail_page.dart index 650b451..5f9d430 100644 --- a/lib/features/news/presentation/pages/news_detail_page.dart +++ b/lib/features/news/presentation/pages/news_detail_page.dart @@ -9,6 +9,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:share_plus/share_plus.dart'; import 'package:worker/core/constants/api_constants.dart'; @@ -77,20 +78,21 @@ class _NewsDetailPageState extends ConsumerState { ), centerTitle: false, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), actions: [ // Share button IconButton( - icon: const Icon(Icons.share, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.shareNodes, color: Colors.black, size: 20), onPressed: _onShareTap, ), // Bookmark button IconButton( - icon: Icon( - _isBookmarked ? Icons.bookmark : Icons.bookmark_border, + icon: FaIcon( + _isBookmarked ? FontAwesomeIcons.solidBookmark : FontAwesomeIcons.bookmark, color: _isBookmarked ? AppColors.warning : Colors.black, + size: 20, ), onPressed: _onBookmarkTap, ), @@ -126,8 +128,8 @@ class _NewsDetailPageState extends ConsumerState { errorWidget: (context, url, error) => Container( height: 250, color: AppColors.grey100, - child: const Icon( - Icons.image_outlined, + child: const FaIcon( + FontAwesomeIcons.image, size: 48, color: AppColors.grey500, ), @@ -276,7 +278,7 @@ class _NewsDetailPageState extends ConsumerState { ), // Date - _buildMetaItem(Icons.calendar_today, article.formattedDate), + _buildMetaItem(FontAwesomeIcons.calendar, article.formattedDate), // Reading time // _buildMetaItem(Icons.schedule, article.readingTimeText), @@ -295,7 +297,7 @@ class _NewsDetailPageState extends ConsumerState { return Row( mainAxisSize: MainAxisSize.min, children: [ - Icon(icon, size: 12, color: const Color(0xFF64748B)), + FaIcon(icon, size: 12, color: const Color(0xFF64748B)), const SizedBox(width: 4), Text( text, @@ -369,18 +371,18 @@ class _NewsDetailPageState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.center, children: [ _buildActionButton( - icon: _isLiked ? Icons.favorite : Icons.favorite_border, + icon: _isLiked ? FontAwesomeIcons.solidHeart : FontAwesomeIcons.heart, onPressed: _onLikeTap, color: _isLiked ? Colors.red : null, ), const SizedBox(width: 8), _buildActionButton( - icon: _isBookmarked ? Icons.bookmark : Icons.bookmark_border, + icon: _isBookmarked ? FontAwesomeIcons.solidBookmark : FontAwesomeIcons.bookmark, onPressed: _onBookmarkTap, color: _isBookmarked ? AppColors.warning : null, ), const SizedBox(width: 8), - _buildActionButton(icon: Icons.share, onPressed: _onShareTap), + _buildActionButton(icon: FontAwesomeIcons.shareNodes, onPressed: _onShareTap), ], ), ); @@ -414,7 +416,7 @@ class _NewsDetailPageState extends ConsumerState { side: BorderSide(color: color ?? const Color(0xFFE2E8F0), width: 2), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), - child: Icon(icon, size: 20, color: color ?? const Color(0xFF64748B)), + child: FaIcon(icon, size: 18, color: color ?? const Color(0xFF64748B)), ); } @@ -458,7 +460,7 @@ class _NewsDetailPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.article_outlined, size: 64, color: AppColors.grey500), + FaIcon(FontAwesomeIcons.fileLines, size: 64, color: AppColors.grey500), const SizedBox(height: 16), const Text( 'Không tìm thấy bài viết', @@ -490,7 +492,7 @@ class _NewsDetailPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.error_outline, size: 64, color: AppColors.danger), + FaIcon(FontAwesomeIcons.circleExclamation, size: 64, color: AppColors.danger), const SizedBox(height: 16), const Text( 'Không thể tải bài viết', diff --git a/lib/features/news/presentation/pages/news_list_page.dart b/lib/features/news/presentation/pages/news_list_page.dart index 3a66bf4..a368447 100644 --- a/lib/features/news/presentation/pages/news_list_page.dart +++ b/lib/features/news/presentation/pages/news_list_page.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -111,9 +112,9 @@ class _NewsListPageState extends ConsumerState { padding: EdgeInsets.symmetric(horizontal: AppSpacing.md), child: Row( children: [ - Icon( - Icons.newspaper, - size: 18, + FaIcon( + FontAwesomeIcons.newspaper, + size: 16, color: AppColors.primaryBlue, ), SizedBox(width: 8), @@ -194,7 +195,7 @@ class _NewsListPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.newspaper_outlined, size: 64, color: AppColors.grey500), + FaIcon(FontAwesomeIcons.newspaper, size: 64, color: AppColors.grey500), const SizedBox(height: 16), const Text( 'Chưa có tin tức', @@ -221,7 +222,7 @@ class _NewsListPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.error_outline, size: 64, color: AppColors.danger), + FaIcon(FontAwesomeIcons.circleExclamation, size: 64, color: AppColors.danger), const SizedBox(height: 16), const Text( 'Không thể tải tin tức', diff --git a/lib/features/news/presentation/widgets/category_filter_chips.dart b/lib/features/news/presentation/widgets/category_filter_chips.dart index ca52073..5aaf2e4 100644 --- a/lib/features/news/presentation/widgets/category_filter_chips.dart +++ b/lib/features/news/presentation/widgets/category_filter_chips.dart @@ -7,6 +7,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/news/domain/entities/blog_category.dart'; @@ -121,7 +122,7 @@ class CategoryFilterChips extends ConsumerWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Icon(Icons.error_outline, size: 16, color: AppColors.grey500), + FaIcon(FontAwesomeIcons.circleExclamation, size: 16, color: AppColors.grey500), const SizedBox(width: AppSpacing.xs), Text( 'Lỗi tải danh mục', @@ -133,7 +134,7 @@ class CategoryFilterChips extends ConsumerWidget { const SizedBox(width: AppSpacing.xs), GestureDetector( onTap: () => ref.refresh(blogCategoriesProvider), - child: Icon(Icons.refresh, size: 16, color: AppColors.primaryBlue), + child: FaIcon(FontAwesomeIcons.arrowsRotate, size: 14, color: AppColors.primaryBlue), ), ], ), diff --git a/lib/features/news/presentation/widgets/featured_news_card.dart b/lib/features/news/presentation/widgets/featured_news_card.dart index b80c1eb..da09409 100644 --- a/lib/features/news/presentation/widgets/featured_news_card.dart +++ b/lib/features/news/presentation/widgets/featured_news_card.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/news/domain/entities/news_article.dart'; @@ -68,8 +69,8 @@ class FeaturedNewsCard extends StatelessWidget { errorWidget: (context, url, error) => Container( height: 200, color: AppColors.grey100, - child: const Icon( - Icons.image_outlined, + child: const FaIcon( + FontAwesomeIcons.image, size: 48, color: AppColors.grey500, ), @@ -122,7 +123,7 @@ class FeaturedNewsCard extends StatelessWidget { children: [ // Date _buildMetaItem( - icon: Icons.calendar_today, + icon: FontAwesomeIcons.calendar, text: article.formattedDate, ), @@ -176,7 +177,7 @@ class FeaturedNewsCard extends StatelessWidget { return Row( mainAxisSize: MainAxisSize.min, children: [ - Icon(icon, size: 12, color: const Color(0xFF64748B)), + FaIcon(icon, size: 12, color: const Color(0xFF64748B)), const SizedBox(width: 4), Text( text, diff --git a/lib/features/news/presentation/widgets/highlight_box.dart b/lib/features/news/presentation/widgets/highlight_box.dart index 865c5cc..6cea950 100644 --- a/lib/features/news/presentation/widgets/highlight_box.dart +++ b/lib/features/news/presentation/widgets/highlight_box.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; /// Highlight type enum @@ -65,7 +66,7 @@ class HighlightBox extends StatelessWidget { // Title with icon Row( children: [ - Icon(_getIcon(), size: 20, color: const Color(0xFF92400E)), + FaIcon(_getIcon(), size: 18, color: const Color(0xFF92400E)), const SizedBox(width: 8), Text( title, @@ -98,9 +99,9 @@ class HighlightBox extends StatelessWidget { IconData _getIcon() { switch (type) { case HighlightType.tip: - return Icons.lightbulb; + return FontAwesomeIcons.lightbulb; case HighlightType.warning: - return Icons.error_outline; + return FontAwesomeIcons.circleExclamation; } } } diff --git a/lib/features/news/presentation/widgets/news_card.dart b/lib/features/news/presentation/widgets/news_card.dart index c598180..5719641 100644 --- a/lib/features/news/presentation/widgets/news_card.dart +++ b/lib/features/news/presentation/widgets/news_card.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/news/domain/entities/news_article.dart'; @@ -67,8 +68,8 @@ class NewsCard extends StatelessWidget { width: 80, height: 80, color: AppColors.grey100, - child: const Icon( - Icons.image_outlined, + child: const FaIcon( + FontAwesomeIcons.image, size: 24, color: AppColors.grey500, ), @@ -116,8 +117,8 @@ class NewsCard extends StatelessWidget { Row( children: [ // Date - const Icon( - Icons.calendar_today, + const FaIcon( + FontAwesomeIcons.calendar, size: 12, color: Color(0xFF64748B), ), diff --git a/lib/features/news/presentation/widgets/related_article_card.dart b/lib/features/news/presentation/widgets/related_article_card.dart index f1f81fa..d25ee24 100644 --- a/lib/features/news/presentation/widgets/related_article_card.dart +++ b/lib/features/news/presentation/widgets/related_article_card.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/news/domain/entities/news_article.dart'; @@ -66,8 +67,8 @@ class RelatedArticleCard extends StatelessWidget { width: 60, height: 60, color: AppColors.grey100, - child: const Icon( - Icons.image_outlined, + child: const FaIcon( + FontAwesomeIcons.image, size: 20, color: AppColors.grey500, ), diff --git a/lib/features/orders/presentation/pages/orders_page.dart b/lib/features/orders/presentation/pages/orders_page.dart index 6bd60a4..c75b5b7 100644 --- a/lib/features/orders/presentation/pages/orders_page.dart +++ b/lib/features/orders/presentation/pages/orders_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/database/models/enums.dart'; @@ -57,7 +58,7 @@ class _OrdersPageState extends ConsumerState { backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -137,17 +138,17 @@ class _OrdersPageState extends ConsumerState { decoration: InputDecoration( hintText: 'Mã đơn hàng', hintStyle: const TextStyle(color: AppColors.grey500, fontSize: 14), - prefixIcon: const Icon( - Icons.search, + prefixIcon: const FaIcon( + FontAwesomeIcons.magnifyingGlass, color: AppColors.grey500, - size: 20, + size: 18, ), suffixIcon: _searchController.text.isNotEmpty ? IconButton( - icon: const Icon( - Icons.clear, + icon: const FaIcon( + FontAwesomeIcons.xmark, color: AppColors.grey500, - size: 20, + size: 18, ), onPressed: () { _searchController.clear(); @@ -283,8 +284,8 @@ class _OrdersPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.receipt_long_outlined, + FaIcon( + FontAwesomeIcons.receipt, size: 80, color: AppColors.grey500.withValues(alpha: 0.5), ), @@ -322,8 +323,8 @@ class _OrdersPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.error_outline, + FaIcon( + FontAwesomeIcons.circleExclamation, size: 80, color: AppColors.danger.withValues(alpha: 0.7), ), diff --git a/lib/features/orders/presentation/pages/payments_page.dart b/lib/features/orders/presentation/pages/payments_page.dart index 8a17b28..f4ad4ad 100644 --- a/lib/features/orders/presentation/pages/payments_page.dart +++ b/lib/features/orders/presentation/pages/payments_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/database/models/enums.dart'; @@ -140,7 +141,7 @@ class _PaymentsPageState extends ConsumerState backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -256,7 +257,7 @@ class _PaymentsPageState extends ConsumerState backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -274,7 +275,7 @@ class _PaymentsPageState extends ConsumerState backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -290,8 +291,8 @@ class _PaymentsPageState extends ConsumerState child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.error_outline, + FaIcon( + FontAwesomeIcons.circleExclamation, size: 80, color: AppColors.danger.withValues(alpha: 0.7), ), @@ -325,19 +326,19 @@ class _PaymentsPageState extends ConsumerState switch (tabLabel) { case 'Chưa thanh toán': message = 'Không có hóa đơn chưa thanh toán'; - icon = Icons.receipt_long_outlined; + icon = FontAwesomeIcons.receipt; break; case 'Quá hạn': message = 'Không có hóa đơn quá hạn'; - icon = Icons.warning_amber_outlined; + icon = FontAwesomeIcons.triangleExclamation; break; case 'Đã thanh toán': message = 'Không có hóa đơn đã thanh toán'; - icon = Icons.check_circle_outline; + icon = FontAwesomeIcons.circleCheck; break; default: message = 'Không có hóa đơn nào'; - icon = Icons.receipt_long_outlined; + icon = FontAwesomeIcons.receipt; } return SliverFillRemaining( @@ -345,7 +346,7 @@ class _PaymentsPageState extends ConsumerState child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( + FaIcon( icon, size: 80, color: AppColors.grey500.withValues(alpha: 0.5), diff --git a/lib/features/orders/presentation/widgets/invoice_card.dart b/lib/features/orders/presentation/widgets/invoice_card.dart index 02bf47a..680248c 100644 --- a/lib/features/orders/presentation/widgets/invoice_card.dart +++ b/lib/features/orders/presentation/widgets/invoice_card.dart @@ -4,6 +4,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:worker/core/database/models/enums.dart'; import 'package:worker/core/theme/colors.dart'; @@ -241,7 +242,7 @@ class InvoiceCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, spacing: 8, children: [ - Icon(Icons.credit_card), + FaIcon(FontAwesomeIcons.creditCard, size: 18), Text( buttonText, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600), diff --git a/lib/features/products/presentation/pages/product_detail_page.dart b/lib/features/products/presentation/pages/product_detail_page.dart index cc2c55d..535489d 100644 --- a/lib/features/products/presentation/pages/product_detail_page.dart +++ b/lib/features/products/presentation/pages/product_detail_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -112,7 +113,7 @@ class _ProductDetailPageState extends ConsumerState { // Share options ListTile( - leading: const Icon(Icons.chat, color: AppColors.primaryBlue), + leading: const FaIcon(FontAwesomeIcons.message, color: AppColors.primaryBlue, size: 20), title: const Text('Chia sẻ qua tin nhắn'), onTap: () { Navigator.pop(context); @@ -124,7 +125,7 @@ class _ProductDetailPageState extends ConsumerState { }, ), ListTile( - leading: const Icon(Icons.share, color: AppColors.primaryBlue), + leading: const FaIcon(FontAwesomeIcons.shareNodes, color: AppColors.primaryBlue, size: 20), title: const Text('Chia sẻ khác'), onTap: () { Navigator.pop(context); @@ -132,7 +133,7 @@ class _ProductDetailPageState extends ConsumerState { }, ), ListTile( - leading: const Icon(Icons.copy, color: AppColors.primaryBlue), + leading: const FaIcon(FontAwesomeIcons.copy, color: AppColors.primaryBlue, size: 20), title: const Text('Sao chép link'), onTap: () { Navigator.pop(context); @@ -178,7 +179,7 @@ class _ProductDetailPageState extends ConsumerState { backgroundColor: const Color(0xFFF4F6F8), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -192,7 +193,7 @@ class _ProductDetailPageState extends ConsumerState { actions: [ // Share button IconButton( - icon: const Icon(Icons.share, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.shareNodes, color: Colors.black, size: 20), onPressed: () { productAsync.whenData((product) { _shareProduct(product); @@ -202,7 +203,7 @@ class _ProductDetailPageState extends ConsumerState { // Favorite button IconButton( icon: Icon( - isFavorite ? Icons.favorite : Icons.favorite_border, + isFavorite ? FontAwesomeIcons.solidHeart : FontAwesomeIcons.heart, color: isFavorite ? AppColors.danger : Colors.black, ), onPressed: _toggleFavorite, @@ -265,7 +266,7 @@ class _ProductDetailPageState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( - Icons.error_outline, + FontAwesomeIcons.circleExclamation, size: 80, color: AppColors.danger, ), @@ -290,7 +291,7 @@ class _ProductDetailPageState extends ConsumerState { // Invalidate to trigger refetch ref.invalidate(productDetailProvider(productId: widget.productId)); }, - icon: const Icon(Icons.refresh), + icon: const FaIcon(FontAwesomeIcons.arrowsRotate, size: 18), label: const Text('Thử lại'), style: ElevatedButton.styleFrom( backgroundColor: AppColors.primaryBlue, diff --git a/lib/features/products/presentation/pages/products_page.dart b/lib/features/products/presentation/pages/products_page.dart index 31b7b3c..2baf7ed 100644 --- a/lib/features/products/presentation/pages/products_page.dart +++ b/lib/features/products/presentation/pages/products_page.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/router/app_router.dart'; @@ -45,7 +46,7 @@ class ProductsPage extends ConsumerWidget { endDrawer: const ProductFilterDrawer(), appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text('Sản phẩm', style: TextStyle(color: Colors.black)), @@ -61,7 +62,7 @@ class ProductsPage extends ConsumerWidget { backgroundColor: AppColors.danger, textColor: AppColors.white, isLabelVisible: cartItemCount > 0, - child: const Icon(Icons.shopping_cart_outlined, color: Colors.black), + child: const FaIcon(FontAwesomeIcons.cartShopping, color: Colors.black, size: 20), ), onPressed: () => context.push(RouteNames.cart), ), @@ -88,7 +89,7 @@ class ProductsPage extends ConsumerWidget { // Open filter drawer from right Scaffold.of(scaffoldContext).openEndDrawer(); }, - icon: const Icon(Icons.filter_list, size: 20), + icon: const FaIcon(FontAwesomeIcons.sliders, size: 18), label: const Text('Lọc', style: TextStyle(fontSize: 12)), style: OutlinedButton.styleFrom( foregroundColor: AppColors.grey900, @@ -160,7 +161,7 @@ class ProductsPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.inventory_2_outlined, size: 80.0, color: AppColors.grey500.withAlpha(128)), + FaIcon(FontAwesomeIcons.boxOpen, size: 80.0, color: AppColors.grey500.withAlpha(128)), const SizedBox(height: AppSpacing.lg), Text( l10n.noProductsFound, @@ -186,7 +187,7 @@ class ProductsPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.error_outline, size: 80.0, color: AppColors.danger.withAlpha(128)), + FaIcon(FontAwesomeIcons.circleExclamation, size: 80.0, color: AppColors.danger.withAlpha(128)), const SizedBox(height: AppSpacing.lg), Text( l10n.error, @@ -203,7 +204,7 @@ class ProductsPage extends ConsumerWidget { onPressed: () async { await ref.read(productsProvider.notifier).refresh(); }, - icon: const Icon(Icons.refresh), + icon: const FaIcon(FontAwesomeIcons.arrowsRotate, size: 18), label: Text(l10n.tryAgain), style: ElevatedButton.styleFrom( backgroundColor: AppColors.primaryBlue, diff --git a/lib/features/products/presentation/widgets/product_card.dart b/lib/features/products/presentation/widgets/product_card.dart index 2ade035..a520c64 100644 --- a/lib/features/products/presentation/widgets/product_card.dart +++ b/lib/features/products/presentation/widgets/product_card.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:shimmer/shimmer.dart'; import 'package:worker/core/constants/ui_constants.dart'; @@ -75,7 +76,7 @@ class ProductCard extends ConsumerWidget { errorWidget: (context, url, error) => Container( color: AppColors.grey100, child: const Icon( - Icons.image_not_supported, + FontAwesomeIcons.image, size: 48.0, color: AppColors.grey500, ), @@ -254,7 +255,7 @@ class ProductCard extends ConsumerWidget { horizontal: AppSpacing.sm, ), ), - icon: const Icon(Icons.shopping_cart, size: 16.0), + icon: const FaIcon(FontAwesomeIcons.cartShopping, size: 14.0), label: Text( !product.inStock ? 'Thêm vào giỏ' : l10n.outOfStock, style: const TextStyle( @@ -299,7 +300,7 @@ class ProductCard extends ConsumerWidget { horizontal: AppSpacing.sm, ), ), - icon: const Icon(Icons.threed_rotation, size: 16.0), + icon: const FaIcon(FontAwesomeIcons.cube, size: 14.0), label: const Text( 'Phối cảnh 360°', style: TextStyle( diff --git a/lib/features/products/presentation/widgets/product_detail/image_gallery_section.dart b/lib/features/products/presentation/widgets/product_detail/image_gallery_section.dart index 187b488..9126e53 100644 --- a/lib/features/products/presentation/widgets/product_detail/image_gallery_section.dart +++ b/lib/features/products/presentation/widgets/product_detail/image_gallery_section.dart @@ -5,6 +5,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:shimmer/shimmer.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -108,7 +109,7 @@ class _ImageGallerySectionState extends State { errorWidget: (context, url, error) => Container( color: AppColors.grey100, child: const Icon( - Icons.image_not_supported, + FontAwesomeIcons.image, size: 64, color: AppColors.grey500, ), @@ -144,7 +145,7 @@ class _ImageGallerySectionState extends State { return Transform.rotate( angle: value * 2 * 3.14159, child: const Icon( - Icons.sync, + FontAwesomeIcons.arrowsRotate, size: 10, color: AppColors.white, ), @@ -234,7 +235,7 @@ class _ImageGallerySectionState extends State { errorWidget: (context, url, error) => Container( color: AppColors.grey100, child: const Icon( - Icons.image_not_supported, + FontAwesomeIcons.image, size: 20, color: AppColors.grey500, ), @@ -312,7 +313,7 @@ class _ImageLightboxState extends State<_ImageLightbox> { foregroundColor: AppColors.white, elevation: 0, leading: IconButton( - icon: const Icon(Icons.close, size: 32), + icon: const FaIcon(FontAwesomeIcons.xmark, size: 28), onPressed: () => Navigator.of(context).pop(), ), title: Text( @@ -340,7 +341,7 @@ class _ImageLightboxState extends State<_ImageLightbox> { imageUrl: widget.images[index], fit: BoxFit.contain, errorWidget: (context, url, error) => const Icon( - Icons.error_outline, + FontAwesomeIcons.circleExclamation, color: AppColors.white, size: 64, ), @@ -361,7 +362,7 @@ class _ImageLightboxState extends State<_ImageLightbox> { child: Center( child: IconButton( icon: const Icon( - Icons.chevron_left, + FontAwesomeIcons.chevronLeft, color: AppColors.white, size: 32, ), @@ -382,7 +383,7 @@ class _ImageLightboxState extends State<_ImageLightbox> { child: Center( child: IconButton( icon: const Icon( - Icons.chevron_right, + FontAwesomeIcons.chevronRight, color: AppColors.white, size: 32, ), diff --git a/lib/features/products/presentation/widgets/product_detail/product_tabs_section.dart b/lib/features/products/presentation/widgets/product_detail/product_tabs_section.dart index 5ad8aaa..7f247af 100644 --- a/lib/features/products/presentation/widgets/product_detail/product_tabs_section.dart +++ b/lib/features/products/presentation/widgets/product_detail/product_tabs_section.dart @@ -4,6 +4,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/products/domain/entities/product.dart'; @@ -152,7 +153,7 @@ class _DescriptionTab extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon( - Icons.check_circle, + FontAwesomeIcons.circleCheck, size: 18, color: AppColors.success, ), @@ -328,7 +329,7 @@ class _ReviewsTab extends StatelessWidget { children: List.generate( 5, (index) => Icon( - index < 4 ? Icons.star : Icons.star_half, + index < 4 ? FontAwesomeIcons.solidStar : FontAwesomeIcons.starHalfStroke, color: const Color(0xFFffc107), size: 18, ), @@ -387,7 +388,7 @@ class _ReviewItem extends StatelessWidget { color: Color(0xFFF4F6F8), ), child: const Icon( - Icons.person, + FontAwesomeIcons.solidUser, color: AppColors.grey500, size: 20, ), @@ -428,8 +429,8 @@ class _ReviewItem extends StatelessWidget { 5, (index) => Icon( index < (review['rating'] as num? ?? 0).toInt() - ? Icons.star - : Icons.star_border, + ? FontAwesomeIcons.solidStar + : FontAwesomeIcons.star, color: const Color(0xFFffc107), size: 14, ), diff --git a/lib/features/products/presentation/widgets/product_detail/sticky_action_bar.dart b/lib/features/products/presentation/widgets/product_detail/sticky_action_bar.dart index 6f856e6..2fa2ec0 100644 --- a/lib/features/products/presentation/widgets/product_detail/sticky_action_bar.dart +++ b/lib/features/products/presentation/widgets/product_detail/sticky_action_bar.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; @@ -89,7 +90,7 @@ class StickyActionBar extends StatelessWidget { children: [ // Decrease Button _QuantityButton( - icon: Icons.remove, + icon: FontAwesomeIcons.minus, onPressed: quantity > 1 ? onDecrease : null, ), @@ -122,7 +123,7 @@ class StickyActionBar extends StatelessWidget { ), // Increase Button - _QuantityButton(icon: Icons.add, onPressed: onIncrease), + _QuantityButton(icon: FontAwesomeIcons.plus, onPressed: onIncrease), ], ), ), @@ -160,7 +161,7 @@ class StickyActionBar extends StatelessWidget { borderRadius: BorderRadius.circular(8), ), ), - icon: const Icon(Icons.shopping_cart, size: 20), + icon: const FaIcon(FontAwesomeIcons.cartShopping, size: 18), label: Text( isOutOfStock ? 'Hết hàng' : 'Thêm vào giỏ hàng', style: const TextStyle( diff --git a/lib/features/products/presentation/widgets/product_filter_drawer.dart b/lib/features/products/presentation/widgets/product_filter_drawer.dart index c18fa3e..26789fe 100644 --- a/lib/features/products/presentation/widgets/product_filter_drawer.dart +++ b/lib/features/products/presentation/widgets/product_filter_drawer.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/products/presentation/providers/product_filters_provider.dart'; @@ -51,7 +52,7 @@ class ProductFilterDrawer extends ConsumerWidget { ), ), IconButton( - icon: const Icon(Icons.close), + icon: const FaIcon(FontAwesomeIcons.xmark, size: 20), onPressed: () => Navigator.of(context).pop(), color: AppColors.grey500, ), @@ -208,7 +209,7 @@ class ProductFilterDrawer extends ConsumerWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( - Icons.error_outline, + FontAwesomeIcons.circleExclamation, size: 48, color: AppColors.danger, ), diff --git a/lib/features/products/presentation/widgets/product_search_bar.dart b/lib/features/products/presentation/widgets/product_search_bar.dart index dd50abb..f65d477 100644 --- a/lib/features/products/presentation/widgets/product_search_bar.dart +++ b/lib/features/products/presentation/widgets/product_search_bar.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/products/presentation/providers/search_query_provider.dart'; @@ -67,14 +68,14 @@ class _ProductSearchBarState extends ConsumerState { color: AppColors.grey500, ), prefixIcon: const Icon( - Icons.search, + FontAwesomeIcons.magnifyingGlass, color: AppColors.grey500, size: AppIconSize.md, ), suffixIcon: _controller.text.isNotEmpty ? IconButton( icon: const Icon( - Icons.clear, + FontAwesomeIcons.xmark, color: AppColors.grey500, size: AppIconSize.md, ), diff --git a/lib/features/promotions/presentation/pages/promotion_detail_page.dart b/lib/features/promotions/presentation/pages/promotion_detail_page.dart index 84daa92..b154231 100644 --- a/lib/features/promotions/presentation/pages/promotion_detail_page.dart +++ b/lib/features/promotions/presentation/pages/promotion_detail_page.dart @@ -11,6 +11,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/router/app_router.dart'; @@ -56,7 +57,7 @@ class _PromotionDetailPageState extends ConsumerState { loading: () => Scaffold( appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -73,7 +74,7 @@ class _PromotionDetailPageState extends ConsumerState { error: (error, stack) => Scaffold( appBar: AppBar( leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -89,8 +90,8 @@ class _PromotionDetailPageState extends ConsumerState { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon( - Icons.error_outline, + const FaIcon( + FontAwesomeIcons.circleExclamation, size: 64, color: AppColors.danger, ), @@ -127,7 +128,7 @@ class _PromotionDetailPageState extends ConsumerState { foregroundColor: AppColors.grey900, elevation: AppBarSpecs.elevation, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, color: Colors.black, size: 20), onPressed: () => context.pop(), ), title: const Text( @@ -138,15 +139,16 @@ class _PromotionDetailPageState extends ConsumerState { actions: [ // Share Button IconButton( - icon: const Icon(Icons.share, color: Colors.black), + icon: const FaIcon(FontAwesomeIcons.shareNodes, color: Colors.black, size: 20), onPressed: _handleShare, ), // Bookmark Button IconButton( - icon: Icon( - _isBookmarked ? Icons.bookmark : Icons.bookmark_border, + icon: FaIcon( + _isBookmarked ? FontAwesomeIcons.solidBookmark : FontAwesomeIcons.bookmark, color: Colors.black, + size: 20, ), onPressed: _handleBookmark, ), @@ -205,8 +207,8 @@ class _PromotionDetailPageState extends ConsumerState { height: 200, color: AppColors.grey100, child: const Center( - child: Icon( - Icons.image_not_supported, + child: FaIcon( + FontAwesomeIcons.image, size: 64, color: AppColors.grey500, ), @@ -243,9 +245,9 @@ class _PromotionDetailPageState extends ConsumerState { crossAxisAlignment: WrapCrossAlignment.center, children: [ // Clock icon and date - const Icon( - Icons.access_time, - size: 18, + const FaIcon( + FontAwesomeIcons.clock, + size: 16, color: Color(0xFFF59E0B), // warning color ), Text( @@ -270,8 +272,8 @@ class _PromotionDetailPageState extends ConsumerState { child: const Row( mainAxisSize: MainAxisSize.min, children: [ - Icon( - Icons.local_fire_department, + FaIcon( + FontAwesomeIcons.fire, size: 14, color: Colors.white, ), @@ -298,7 +300,7 @@ class _PromotionDetailPageState extends ConsumerState { Widget _buildProgramContentSection() { return const PromotionSection( title: 'Nội dung chương trình', - icon: Icons.card_giftcard, + icon: FontAwesomeIcons.gift, content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -345,7 +347,7 @@ class _PromotionDetailPageState extends ConsumerState { Widget _buildTermsSection() { return const PromotionSection( title: 'Điều kiện áp dụng', - icon: Icons.description, + icon: FontAwesomeIcons.fileLines, content: PromotionBulletList( items: [ 'Áp dụng cho tất cả khách hàng là thợ xây dựng đã đăng ký tài khoản', @@ -365,7 +367,7 @@ class _PromotionDetailPageState extends ConsumerState { Widget _buildContactSection() { return const PromotionSection( title: 'Thông tin liên hệ', - icon: Icons.phone, + icon: FontAwesomeIcons.phone, isLast: true, content: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -414,7 +416,7 @@ class _PromotionDetailPageState extends ConsumerState { child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.visibility, size: 20), + FaIcon(FontAwesomeIcons.eye, size: 18), SizedBox(width: 8), Text( 'Xem sản phẩm áp dụng', diff --git a/lib/features/promotions/presentation/pages/promotions_page.dart b/lib/features/promotions/presentation/pages/promotions_page.dart index 4264d80..90b6d53 100644 --- a/lib/features/promotions/presentation/pages/promotions_page.dart +++ b/lib/features/promotions/presentation/pages/promotions_page.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/home/domain/entities/promotion.dart'; @@ -47,8 +48,8 @@ class PromotionsPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon( - Icons.error_outline, + const FaIcon( + FontAwesomeIcons.circleExclamation, color: AppColors.danger, size: 48, ), @@ -117,8 +118,8 @@ class PromotionsPage extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.local_offer_outlined, + FaIcon( + FontAwesomeIcons.tag, size: 64, color: AppColors.grey500, ), diff --git a/lib/features/promotions/presentation/widgets/featured_promotion_card.dart b/lib/features/promotions/presentation/widgets/featured_promotion_card.dart index 63cfba9..832f921 100644 --- a/lib/features/promotions/presentation/widgets/featured_promotion_card.dart +++ b/lib/features/promotions/presentation/widgets/featured_promotion_card.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/theme/colors.dart'; /// Featured Promotion Card @@ -90,9 +91,9 @@ class FeaturedPromotionCard extends StatelessWidget { const SizedBox(height: 12), Row( children: [ - Icon( - Icons.access_time, - size: 14, + FaIcon( + FontAwesomeIcons.clock, + size: 12, color: Colors.white.withValues(alpha: 0.8), ), const SizedBox(width: 4), @@ -112,8 +113,8 @@ class FeaturedPromotionCard extends StatelessWidget { // Right side - Icon const SizedBox(width: 16), - Icon( - Icons.percent, + FaIcon( + FontAwesomeIcons.percent, size: 48, color: Colors.white.withValues(alpha: 0.9), ), diff --git a/lib/features/promotions/presentation/widgets/promotion_card.dart b/lib/features/promotions/presentation/widgets/promotion_card.dart index a8143e2..83a521c 100644 --- a/lib/features/promotions/presentation/widgets/promotion_card.dart +++ b/lib/features/promotions/presentation/widgets/promotion_card.dart @@ -6,6 +6,7 @@ library; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/router/app_router.dart'; import 'package:worker/core/theme/colors.dart'; @@ -62,8 +63,8 @@ class PromotionCard extends StatelessWidget { height: 150, color: AppColors.grey100, child: const Center( - child: Icon( - Icons.image_not_supported, + child: FaIcon( + FontAwesomeIcons.image, size: 48, color: AppColors.grey500, ), @@ -109,8 +110,8 @@ class PromotionCard extends StatelessWidget { Expanded( child: Row( children: [ - const Icon( - Icons.calendar_today, + const FaIcon( + FontAwesomeIcons.calendar, size: 12, color: AppColors.primaryBlue, ), diff --git a/lib/shared/widgets/custom_app_bar.dart b/lib/shared/widgets/custom_app_bar.dart index ef49390..af2fc89 100644 --- a/lib/shared/widgets/custom_app_bar.dart +++ b/lib/shared/widgets/custom_app_bar.dart @@ -4,6 +4,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import '../../core/constants/ui_constants.dart'; /// Custom app bar with consistent styling @@ -112,7 +113,7 @@ class SearchAppBar extends StatelessWidget implements PreferredSizeWidget { leading: leading ?? IconButton( - icon: const Icon(Icons.arrow_back), + icon: const FaIcon(FontAwesomeIcons.arrowLeft, size: 20), onPressed: () => Navigator.of(context).pop(), ), title: TextField( @@ -127,7 +128,7 @@ class SearchAppBar extends StatelessWidget implements PreferredSizeWidget { border: InputBorder.none, suffixIcon: controller?.text.isNotEmpty ?? false ? IconButton( - icon: const Icon(Icons.clear, color: Colors.white), + icon: const FaIcon(FontAwesomeIcons.xmark, color: Colors.white, size: 18), onPressed: () { controller?.clear(); onClear?.call(); diff --git a/lib/shared/widgets/date_picker_field.dart b/lib/shared/widgets/date_picker_field.dart index 9665d22..1c2d28a 100644 --- a/lib/shared/widgets/date_picker_field.dart +++ b/lib/shared/widgets/date_picker_field.dart @@ -5,6 +5,7 @@ library; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import '../../core/utils/formatters.dart'; import '../../core/utils/validators.dart'; import '../../core/constants/ui_constants.dart'; @@ -118,7 +119,7 @@ class _DatePickerFieldState extends State { InputDecoration( labelText: widget.labelText ?? 'Ngày', hintText: widget.hintText ?? 'dd/MM/yyyy', - prefixIcon: widget.prefixIcon ?? const Icon(Icons.calendar_today), + prefixIcon: widget.prefixIcon ?? const FaIcon(FontAwesomeIcons.calendar, size: 20), suffixIcon: widget.suffixIcon, border: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), @@ -219,7 +220,7 @@ class _DateRangePickerFieldState extends State { decoration: InputDecoration( labelText: widget.labelText ?? 'Khoảng thời gian', hintText: widget.hintText ?? 'Chọn khoảng thời gian', - prefixIcon: widget.prefixIcon ?? const Icon(Icons.date_range), + prefixIcon: widget.prefixIcon ?? const FaIcon(FontAwesomeIcons.calendarDays, size: 20), border: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), ), @@ -266,7 +267,7 @@ class DateOfBirthField extends StatelessWidget { onDateSelected: onDateSelected, validator: validator ?? (value) => Validators.age(value, minAge: minAge), enabled: enabled, - prefixIcon: const Icon(Icons.cake), + prefixIcon: const FaIcon(FontAwesomeIcons.cakeCandles, size: 20), ); } } @@ -364,7 +365,7 @@ class _TimePickerFieldState extends State { decoration: InputDecoration( labelText: widget.labelText ?? 'Thời gian', hintText: widget.hintText ?? 'HH:mm', - prefixIcon: widget.prefixIcon ?? const Icon(Icons.access_time), + prefixIcon: widget.prefixIcon ?? const FaIcon(FontAwesomeIcons.clock, size: 20), border: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), ), diff --git a/lib/shared/widgets/vietnamese_phone_field.dart b/lib/shared/widgets/vietnamese_phone_field.dart index b0c0a94..020a395 100644 --- a/lib/shared/widgets/vietnamese_phone_field.dart +++ b/lib/shared/widgets/vietnamese_phone_field.dart @@ -6,6 +6,7 @@ library; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/utils/formatters.dart'; import 'package:worker/core/utils/validators.dart'; @@ -89,7 +90,7 @@ class _VietnamesePhoneFieldState extends State { decoration: InputDecoration( labelText: widget.labelText ?? 'Số điện thoại', hintText: widget.hintText ?? '0xxx xxx xxx', - prefixIcon: widget.prefixIcon ?? const Icon(Icons.phone), + prefixIcon: widget.prefixIcon ?? const FaIcon(FontAwesomeIcons.phone, size: 20), suffixIcon: widget.suffixIcon, border: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), @@ -158,8 +159,8 @@ class PhoneDisplayField extends StatelessWidget { onTap: onTap, decoration: InputDecoration( labelText: labelText ?? 'Số điện thoại', - prefixIcon: prefixIcon ?? const Icon(Icons.phone), - suffixIcon: onTap != null ? const Icon(Icons.edit) : null, + prefixIcon: prefixIcon ?? const FaIcon(FontAwesomeIcons.phone, size: 20), + suffixIcon: onTap != null ? const FaIcon(FontAwesomeIcons.penToSquare, size: 18) : null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius), ), diff --git a/pubspec.lock b/pubspec.lock index 11d4c6a..e7a50da 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -578,6 +578,14 @@ packages: description: flutter source: sdk version: "0.0.0" + font_awesome_flutter: + dependency: "direct main" + description: + name: font_awesome_flutter + sha256: b9011df3a1fa02993630b8fb83526368cf2206a711259830325bab2f1d2a4eb0 + url: "https://pub.dev" + source: hosted + version: "10.12.0" freezed: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index c40c105..d38f7dc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,6 +62,7 @@ dependencies: lottie: ^3.1.2 qr_flutter: ^4.1.0 mobile_scanner: ^5.2.3 + font_awesome_flutter: ^10.7.0 # Utilities