Files
FinanceApp2/lib/utils/category_utils.dart
T
2025-05-12 19:08:22 +03:00

248 lines
16 KiB
Dart

import 'package:flutter/material.dart';
import '../models/category.dart'; // Import the Category model for return types
// Helper class to manage category details (icon, color) based on name
class CategoryUtils {
// Private map storing details for each predefined category name.
// Using a record `({IconData icon, Color color})` for concise structure.
// This map is mainly for initial data and potentially fallback display logic.
// The actual icon/color for user-created categories will come from the database.
// DEPRECATED: Rely on _stringToIconData and database color instead.
// static final Map<String, ({IconData iconCode, Color colorCode})> _categoryDetails = { ... };
// Default details to return if a category name is not found (e.g., deleted category).
// DEPRECATED: Use getIconFromString and default color instead.
// static final _defaultDetails = (iconCode: Icons.category_outlined, colorCode: Colors.grey.shade500);
/// DEPRECATED: Returns the IconData and Color associated with a given category name (primarily for fallback).
/// It's better to rely on data fetched directly from the database (CategoryDb).
static ({Color colorCode, IconData iconCode}) getCategoryDetails(String categoryName) {
// Fallback logic using the string-to-icon map and a default color
final icon = getIconFromString(categoryName); // Use the reliable method
// Find color from initial data if possible, otherwise default grey
// This part is still weak, ideally color comes from DB.
Color color = Colors.grey.shade500; // Default color
// Quick check against some known initial names for color fallback
if (categoryName == 'Groceries') color = Colors.green.shade400;
if (categoryName == 'Subscriptions') color = Colors.orange.shade400;
if (categoryName == 'Restaurant') color = Colors.red.shade400;
if (categoryName == 'Shopping') color = Colors.blue.shade400;
if (categoryName == 'Transport') color = Colors.purple.shade400;
if (categoryName == 'Travel') color = Colors.cyan.shade400;
if (categoryName == 'Utilities') color = Colors.teal.shade400; // Updated from home_outlined
if (categoryName == 'Income') color = Colors.lightGreenAccent.shade700;
return (colorCode: color, iconCode: icon);
}
/// DEPRECATED: Returns a `Category` object based on its name and amount (primarily for UI models like Pie Chart).
/// Fetches icon/color details using `getCategoryDetails` as a fallback mechanism.
/// Should be replaced by logic that uses CategoryDb data directly.
static Category getCategoryByName(String name, double amount) {
final details = getCategoryDetails(name);
return Category(name, amount, details.colorCode, details.iconCode);
}
/// DEPRECATED: Returns a list of all predefined category names (excluding placeholders).
/// Might be less useful now that categories are fully dynamic.
static List<String> getAllCategoryNames() {
// Return keys from _stringToIconData, excluding special ones
return _stringToIconData.keys.where((key) =>
key != 'help_outline' &&
key != 'label_outline' &&
key != 'attach_money' && // Exclude Income
key != 'category_outlined' // Exclude Other/Default
).toList();
}
/// Converts a string icon name (like 'shopping_cart_outlined') to IconData.
/// This map is crucial for displaying icons based on the string stored in the DB.
static final Map<String, IconData> _stringToIconData = {
// Existing Icons
'shopping_cart_outlined': Icons.shopping_cart_outlined, // Groceries
'subscriptions_outlined': Icons.subscriptions_outlined, // Subscriptions
'restaurant_menu_outlined': Icons.restaurant_menu_outlined, // Restaurant
'shopping_bag_outlined': Icons.shopping_bag_outlined, // Shopping
'directions_bus_filled_outlined': Icons.directions_bus_filled_outlined, // Transport
'flight_takeoff_outlined': Icons.flight_takeoff_outlined, // Travel
'lightbulb_outline': Icons.lightbulb_outline, // Utilities (alternative)
'local_hospital_outlined': Icons.local_hospital_outlined, // Health
'movie_filter_outlined': Icons.movie_filter_outlined, // Entertainment
'attach_money': Icons.attach_money, // Income (Special)
'category_outlined': Icons.category_outlined, // Other/Default (Fallback)
'label_outline': Icons.label_outline, // Placeholder (Internal)
'help_outline': Icons.help_outline, // Placeholder/Error (Internal)
'home_outlined': Icons.home_outlined, // Home/Rent/Mortgage/Utilities
'pets_outlined': Icons.pets_outlined, // Pets
'school_outlined': Icons.school_outlined, // Education/School
'fitness_center_outlined': Icons.fitness_center_outlined, // Gym/Fitness
'checkroom_outlined': Icons.checkroom_outlined, // Clothing
'devices_other_outlined': Icons.devices_other_outlined, // Electronics
'card_giftcard_outlined': Icons.card_giftcard_outlined, // Gifts
'volunteer_activism_outlined': Icons.volunteer_activism_outlined, // Charity/Donations
'receipt_long_outlined': Icons.receipt_long_outlined, // Bills/Receipts
'savings_outlined': Icons.savings_outlined, // Savings/Investments
'credit_card_outlined': Icons.credit_card_outlined, // Credit Card Payment
'build_outlined': Icons.build_outlined, // Repairs/Maintenance
'child_friendly_outlined': Icons.child_friendly_outlined, // Child Care
'work_outline': Icons.work_outline, // Work related
'book_outlined': Icons.book_outlined, // Books/Magazines
'music_note_outlined': Icons.music_note_outlined, // Music
'sports_esports_outlined': Icons.sports_esports_outlined, // Games/Hobbies
'local_bar_outlined': Icons.local_bar_outlined, // Drinks/Bar
'cake_outlined': Icons.cake_outlined, // Celebrations/Party
'park_outlined': Icons.park_outlined, // Parks/Outdoors
'science_outlined': Icons.science_outlined, // Science/Tech
'palette_outlined': Icons.palette_outlined, // Art/Design
'account_balance_outlined': Icons.account_balance_outlined, // Bank/Finance Fees
'analytics_outlined': Icons.analytics_outlined, // Analysis/Reports (Maybe internal?)
'apartment_outlined': Icons.apartment_outlined, // Rent/Mortgage (Alternative)
'beach_access_outlined': Icons.beach_access_outlined, // Vacation/Beach
'brush_outlined': Icons.brush_outlined, // Personal Care/Cosmetics
'business_center_outlined': Icons.business_center_outlined, // Business Expenses
'call_outlined': Icons.call_outlined, // Phone Bill
'camera_alt_outlined': Icons.camera_alt_outlined, // Photography/Equipment
'car_rental_outlined': Icons.car_rental_outlined, // Car Rental
'car_repair_outlined': Icons.car_repair_outlined, // Car Repair
'celebration_outlined': Icons.celebration_outlined, // Party/Events (Alternative)
'computer_outlined': Icons.computer_outlined, // Computer/Software
'construction_outlined': Icons.construction_outlined, // Home Improvement
'cottage_outlined': Icons.cottage_outlined, // Vacation Home/Cottage
'delivery_dining_outlined': Icons.delivery_dining_outlined, // Food Delivery
'diamond_outlined': Icons.diamond_outlined, // Jewelry/Luxury
'dry_cleaning_outlined': Icons.dry_cleaning_outlined, // Laundry/Dry Cleaning
'electrical_services_outlined': Icons.electrical_services_outlined, // Electrician
'emoji_events_outlined': Icons.emoji_events_outlined, // Awards/Competitions
'fastfood_outlined': Icons.fastfood_outlined, // Fast Food
'fax_outlined': Icons.fax_outlined, // Office Supplies (Maybe outdated?)
'festival_outlined': Icons.festival_outlined, // Festivals/Events
'fireplace_outlined': Icons.fireplace_outlined, // Heating/Fuel
'flatware_outlined': Icons.flatware_outlined, // Kitchenware
'gas_meter_outlined': Icons.gas_meter_outlined, // Gas Bill
'gavel_outlined': Icons.gavel_outlined, // Legal Fees
'grass_outlined': Icons.grass_outlined, // Gardening/Lawn Care
'hardware_outlined': Icons.hardware_outlined, // Hardware Store
'hearing_outlined': Icons.hearing_outlined, // Audio/Headphones
'hiking_outlined': Icons.hiking_outlined, // Hiking/Outdoor Gear
'icecream_outlined': Icons.icecream_outlined, // Ice Cream/Desserts
'interests_outlined': Icons.interests_outlined, // Hobbies General
'key_outlined': Icons.key_outlined, // Keys/Locks
'liquor_outlined': Icons.liquor_outlined, // Alcohol
'local_activity_outlined': Icons.local_activity_outlined, // Tickets/Events
'local_atm_outlined': Icons.local_atm_outlined, // ATM Withdrawal (Maybe internal?)
'local_convenience_store_outlined': Icons.local_convenience_store_outlined, // Convenience Store
'local_florist_outlined': Icons.local_florist_outlined, // Flowers
'local_gas_station_outlined': Icons.local_gas_station_outlined, // Gas/Fuel
'local_laundry_service_outlined': Icons.local_laundry_service_outlined, // Laundry Service
'local_mall_outlined': Icons.local_mall_outlined, // Mall Shopping
'local_offer_outlined': Icons.local_offer_outlined, // Discounts/Sales/Coupons
'local_parking_outlined': Icons.local_parking_outlined, // Parking Fees
'local_pharmacy_outlined': Icons.local_pharmacy_outlined, // Pharmacy
'local_pizza_outlined': Icons.local_pizza_outlined, // Pizza
'local_shipping_outlined': Icons.local_shipping_outlined, // Shipping Costs
'local_taxi_outlined': Icons.local_taxi_outlined, // Taxi/Rideshare
'lunch_dining_outlined': Icons.lunch_dining_outlined, // Lunch
'medication_outlined': Icons.medication_outlined, // Medication
'museum_outlined': Icons.museum_outlined, // Museum/Exhibits
'newspaper_outlined': Icons.newspaper_outlined, // Newspapers/Magazines
'paid_outlined': Icons.paid_outlined, // Payments/Transfers (Maybe internal?)
'pedal_bike_outlined': Icons.pedal_bike_outlined, // Cycling
'plumbing_outlined': Icons.plumbing_outlined, // Plumber
'ramen_dining_outlined': Icons.ramen_dining_outlined, // Noodles/Asian Food
'recycling_outlined': Icons.recycling_outlined, // Recycling Fees
'redeem_outlined': Icons.redeem_outlined, // Gifts Received/Redeemed (Maybe internal?)
'request_quote_outlined': Icons.request_quote_outlined, // Invoices/Quotes (Maybe internal?)
'roller_skating_outlined': Icons.roller_skating_outlined, // Skating
'roofing_outlined': Icons.roofing_outlined, // Roofing Repair
'room_service_outlined': Icons.room_service_outlined, // Hotel Service
'shield_outlined': Icons.shield_outlined, // Insurance
'skateboarding_outlined': Icons.skateboarding_outlined, // Skateboarding
'smoking_rooms_outlined': Icons.smoking_rooms_outlined, // Tobacco
'spa_outlined': Icons.spa_outlined, // Spa/Wellness
'sports_bar_outlined': Icons.sports_bar_outlined, // Sports Bar
'sports_basketball_outlined': Icons.sports_basketball_outlined, // Basketball
'sports_football_outlined': Icons.sports_football_outlined, // Football
'sports_golf_outlined': Icons.sports_golf_outlined, // Golf
'sports_gymnastics_outlined': Icons.sports_gymnastics_outlined, // Gymnastics
'sports_handball_outlined': Icons.sports_handball_outlined, // Handball
'sports_hockey_outlined': Icons.sports_hockey_outlined, // Hockey
'sports_kabaddi_outlined': Icons.sports_kabaddi_outlined, // Kabaddi
'sports_mma_outlined': Icons.sports_mma_outlined, // MMA
'sports_motorsports_outlined': Icons.sports_motorsports_outlined, // Motorsports
'sports_soccer_outlined': Icons.sports_soccer_outlined, // Soccer
'sports_tennis_outlined': Icons.sports_tennis_outlined, // Tennis
'sports_volleyball_outlined': Icons.sports_volleyball_outlined, // Volleyball
'stadium_outlined': Icons.stadium_outlined, // Stadium/Events
'store_mall_directory_outlined': Icons.store_mall_directory_outlined, // Department Store
'stroller_outlined': Icons.stroller_outlined, // Baby Supplies
'subway_outlined': Icons.subway_outlined, // Subway/Metro
'surfing_outlined': Icons.surfing_outlined, // Surfing
'sync_alt_outlined': Icons.sync_alt_outlined, // Transfers (Maybe internal?)
'theater_comedy_outlined': Icons.theater_comedy_outlined, // Comedy Club
'theaters_outlined': Icons.theaters_outlined, // Cinema/Theater
'toys_outlined': Icons.toys_outlined, // Toys
'train_outlined': Icons.train_outlined, // Train Travel
'tram_outlined': Icons.tram_outlined, // Tram
'two_wheeler_outlined': Icons.two_wheeler_outlined, // Motorcycle/Scooter
'vape_free_outlined': Icons.vape_free_outlined, // Vaping (quit)
'vaping_rooms_outlined': Icons.vaping_rooms_outlined, // Vaping
'videogame_asset_outlined': Icons.videogame_asset_outlined, // Video Games
'water_drop_outlined': Icons.water_drop_outlined, // Water Bill
'wifi_outlined': Icons.wifi_outlined, // Internet Bill
'wine_bar_outlined': Icons.wine_bar_outlined, // Wine Bar
};
/// Returns the IconData corresponding to the given icon name string.
/// If the `iconName` is not found or is null/empty, returns a default fallback icon (`Icons.help_outline`).
static IconData getIconFromString(String? iconName) {
if (iconName == null || iconName.isEmpty) {
return Icons.help_outline; // Default for null or empty
}
return _stringToIconData[iconName] ?? Icons.help_outline; // Return default if not found in map
}
/// Returns a map of available icons for selection in UI (e.g., dropdowns, dialogs).
/// Excludes placeholder/internal icons like 'help_outline', 'label_outline',
/// 'category_outlined', and the special 'attach_money' (Income).
static Map<String, IconData> getAvailableIcons() {
final availableIcons = Map<String, IconData>.from(_stringToIconData);
// Remove icons not intended for user selection as expense categories
availableIcons.remove('help_outline'); // Internal fallback/error
availableIcons.remove('label_outline'); // Internal placeholder
availableIcons.remove('category_outlined'); // Internal generic fallback
availableIcons.remove('attach_money'); // Reserved for Income type
// Consider removing others if they represent internal states:
// availableIcons.remove('sync_alt_outlined'); // Transfers?
// availableIcons.remove('paid_outlined'); // Payments?
// availableIcons.remove('local_atm_outlined'); // ATM?
// availableIcons.remove('redeem_outlined'); // Gifts Received?
// availableIcons.remove('request_quote_outlined'); // Invoices?
// availableIcons.remove('analytics_outlined'); // Reports?
return availableIcons;
}
/// List of available colors for category selection in UI.
static const List<Color> availableColors = [
// Primary Colors (Good starting points)
Colors.red, Colors.pink, Colors.purple, Colors.deepPurple,
Colors.indigo, Colors.blue, Colors.lightBlue, Colors.cyan,
Colors.teal, Colors.green, Colors.lightGreen, Colors.lime,
Colors.yellow, Colors.amber, Colors.orange, Colors.deepOrange,
Colors.brown, Colors.grey, Colors.blueGrey,
// Accent Colors (Brighter, use with care)
Colors.redAccent, Colors.pinkAccent, Colors.purpleAccent, Colors.deepPurpleAccent,
Colors.indigoAccent, Colors.blueAccent, Colors.lightBlueAccent, Colors.cyanAccent,
Colors.tealAccent, Colors.greenAccent, Colors.limeAccent,
Colors.yellowAccent, Colors.amberAccent, Colors.orangeAccent, Colors.deepOrangeAccent,
// Shade variations (More subtle options)
/*Colors.red.shade300, Colors.pink.shade200, Colors.purple.shade300,
Colors.indigo.shade300, Colors.blue.shade300, Colors.lightBlue.shade300,
Colors.cyan.shade300, Colors.teal.shade300, Colors.green.shade300,
Colors.lightGreen.shade300, Colors.lime.shade300, Colors.yellow.shade600, // Darker yellow
Colors.amber.shade300, Colors.orange.shade300, Colors.deepOrange.shade300,
Colors.brown.shade300, Colors.grey.shade400, Colors.blueGrey.shade300,*/
];
}