import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:helpers/helpers/print.dart'; import 'package:rluv/global/api.dart'; import 'package:rluv/models/budget.dart'; import 'package:rluv/models/budget_category_model.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../models/family_model.dart'; import '../models/shared_note.dart'; import '../models/transaction_model.dart'; import '../models/user.dart'; StateProvider prefsProvider = StateProvider((ref) => null); // final StateProvider tokenProvider = StateProvider((ref) { // // final tokenStr = prefs.getString('jwt'); // // if (tokenStr != null) { // // return Token.fromJson(jsonDecode(tokenStr)); // // } // return null; // }); final Provider userProvider = Provider( (ref) { final dash = ref.watch(dashboardProvider); if (dash == null) return null; final userData = dash['user'] as Map; return User.fromJson(userData); }, ); final Provider familyProvider = Provider( (ref) { final dash = ref.watch(dashboardProvider); if (dash == null) return null; final familyData = dash['family'] as Map; return FamilyModel.fromJson(familyData); }, ); final Provider> budgetCategoriesProvider = Provider>((ref) { final dash = ref.watch(dashboardProvider); if (dash == null) return []; final categoriesData = dash['budget_categories'] as List; final categories = categoriesData .map( (e) => BudgetCategory.fromJson(e as Map), ) .toList(); final prefs = ref.read(prefsProvider); final budgetJson = jsonEncode({'budget_categories': categoriesData}); printBlue('updated prefs stored categories'); prefs?.setString('budget_categories', budgetJson); return categories; }); final Provider budgetProvider = Provider( (ref) { final dash = ref.watch(dashboardProvider); if (dash == null) return null; final budgetData = dash['budget'] as Map?; if (budgetData == null) return null; return Budget.fromJson(budgetData); }, ); final Provider> transactionsProvider = Provider>((ref) { final dash = ref.watch(dashboardProvider); if (dash == null) return []; final transactions = dash['transactions'] as List; return transactions .map( (e) => Transaction.fromJson(e as Map), ) .toList(); }); final Provider> sharedNotesProvider = Provider>( (ref) { final dash = ref.watch(dashboardProvider); if (dash == null) return []; final sharedNotes = dash['shared_notes'] as List; return sharedNotes .map( (e) => SharedNote.fromJson(e as Map), ) .toList(); }, ); final dashboardProvider = StateNotifierProvider?>( (ref) { return DashBoardStateNotifier(ref); }, ); final loadingStateProvider = StateProvider( (ref) => false, ); class DashBoardStateNotifier extends StateNotifier?> { DashBoardStateNotifier(this.ref) : super(null); StateNotifierProviderRef ref; Future fetchDashboard() async { WidgetsBinding.instance.addPostFrameCallback( (_) => ref.read(loadingStateProvider.notifier).state = true, ); final token = ref.read(tokenProvider); if (token?.familyId == null) { printPink('No token, cannot fetch dashboard'); return; } printAmber('Fetching dashboard'); state = await ref.read(apiProvider.notifier).get("dashboard"); WidgetsBinding.instance.addPostFrameCallback( (_) => ref.read(loadingStateProvider.notifier).state = false, ); } void update(Map data) { if (state == null) { printPink('Cant update data, state is null'); return; } if (data.keys.length != 1 || data.values.length != 1) { throw Exception('Only one key/val used in update'); } final key = data.keys.first; switch (key) { case 'transactions': case 'budget_categories': case 'shared_notes': final subStateList = state![key] as List; final subStateListObj = subStateList .map( (e) => e as Map, ) .toList(); subStateListObj.removeWhere( (element) => element['id'] == (data.values.first as Map)['id'], ); subStateListObj.add(data.values.first); final newState = state; newState![key] = subStateListObj; state = {...newState}; // printBlue(state); break; default: break; } } void add(Map data) { if (state == null) { printPink('Cant add data, state is null'); return; } if (data.keys.length != 1 || data.values.length != 1) { throw Exception('Only one key/val used in add'); } final key = data.keys.first; switch (key) { case 'transactions': case 'budget_categories': case 'shared_noted': final subStateList = state![key] as List; final newState = state; subStateList.add(data.values.first); newState![key] = subStateList; state = {...newState}; // printBlue(state); break; default: break; } } void removeWithId(String stateKey, int id) { if (state == null) { printPink('Cant remove data, state is null'); return; } switch (stateKey) { case 'transactions': case 'budget_categories': case 'shared_noted': final subStateList = state![stateKey] as List; final newState = state; subStateList .removeWhere((e) => (e as Map)['id'] == id); newState![stateKey] = subStateList; state = {...newState}; // printBlue(state); break; default: break; } } }