2023-07-22 21:29:32 -06:00
|
|
|
import 'dart:convert';
|
|
|
|
|
2024-05-30 20:44:06 -06:00
|
|
|
import 'package:colorful_print/colorful_print.dart';
|
2023-07-27 01:40:26 -06:00
|
|
|
import 'package:flutter/material.dart';
|
2023-07-19 02:16:13 -06:00
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'package:rluv/global/api.dart';
|
|
|
|
import 'package:rluv/models/budget.dart';
|
|
|
|
import 'package:rluv/models/budget_category_model.dart';
|
2023-07-22 21:29:32 -06:00
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
2023-07-19 02:16:13 -06:00
|
|
|
|
|
|
|
import '../models/family_model.dart';
|
2023-07-22 21:29:32 -06:00
|
|
|
import '../models/shared_note.dart';
|
2023-07-19 02:16:13 -06:00
|
|
|
import '../models/transaction_model.dart';
|
|
|
|
import '../models/user.dart';
|
|
|
|
|
2024-05-30 20:44:06 -06:00
|
|
|
StateProvider<SharedPreferences?> prefsProvider = StateProvider<SharedPreferences?>((ref) => null);
|
2023-07-19 02:16:13 -06:00
|
|
|
|
2023-07-27 01:40:26 -06:00
|
|
|
// final StateProvider<Token?> tokenProvider = StateProvider<Token?>((ref) {
|
|
|
|
// // final tokenStr = prefs.getString('jwt');
|
|
|
|
// // if (tokenStr != null) {
|
|
|
|
// // return Token.fromJson(jsonDecode(tokenStr));
|
|
|
|
// // }
|
|
|
|
// return null;
|
|
|
|
// });
|
2023-07-19 02:16:13 -06:00
|
|
|
|
2023-07-27 01:40:26 -06:00
|
|
|
final Provider<User?> userProvider = Provider<User?>(
|
|
|
|
(ref) {
|
|
|
|
final dash = ref.watch(dashboardProvider);
|
|
|
|
if (dash == null) return null;
|
|
|
|
final userData = dash['user'] as Map<String, dynamic>;
|
|
|
|
return User.fromJson(userData);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
final Provider<FamilyModel?> familyProvider = Provider<FamilyModel?>(
|
|
|
|
(ref) {
|
|
|
|
final dash = ref.watch(dashboardProvider);
|
|
|
|
if (dash == null) return null;
|
|
|
|
final familyData = dash['family'] as Map<String, dynamic>;
|
|
|
|
return FamilyModel.fromJson(familyData);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2024-05-30 20:44:06 -06:00
|
|
|
final Provider<List<BudgetCategory>> budgetCategoriesProvider = Provider<List<BudgetCategory>>((ref) {
|
2023-07-27 01:40:26 -06:00
|
|
|
final dash = ref.watch(dashboardProvider);
|
|
|
|
if (dash == null) return [];
|
|
|
|
final categoriesData = dash['budget_categories'] as List<dynamic>;
|
|
|
|
final categories = categoriesData
|
|
|
|
.map(
|
|
|
|
(e) => BudgetCategory.fromJson(e as Map<String, dynamic>),
|
|
|
|
)
|
|
|
|
.toList();
|
|
|
|
|
|
|
|
final prefs = ref.read(prefsProvider);
|
|
|
|
final budgetJson = jsonEncode({'budget_categories': categoriesData});
|
2024-05-30 20:44:06 -06:00
|
|
|
printColor('updated prefs stored categories', textColor: TextColor.blue);
|
2023-07-27 01:40:26 -06:00
|
|
|
prefs?.setString('budget_categories', budgetJson);
|
|
|
|
|
|
|
|
return categories;
|
|
|
|
});
|
|
|
|
|
|
|
|
final Provider<Budget?> budgetProvider = Provider<Budget?>(
|
|
|
|
(ref) {
|
|
|
|
final dash = ref.watch(dashboardProvider);
|
|
|
|
if (dash == null) return null;
|
|
|
|
final budgetData = dash['budget'] as Map<String, dynamic>?;
|
|
|
|
if (budgetData == null) return null;
|
|
|
|
return Budget.fromJson(budgetData);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2024-05-30 20:44:06 -06:00
|
|
|
final Provider<List<Transaction>> transactionsProvider = Provider<List<Transaction>>((ref) {
|
2023-07-27 01:40:26 -06:00
|
|
|
final dash = ref.watch(dashboardProvider);
|
|
|
|
if (dash == null) return [];
|
|
|
|
final transactions = dash['transactions'] as List<dynamic>;
|
|
|
|
return transactions
|
|
|
|
.map(
|
|
|
|
(e) => Transaction.fromJson(e as Map<String, dynamic>),
|
|
|
|
)
|
|
|
|
.toList();
|
|
|
|
});
|
|
|
|
|
2024-05-30 20:44:06 -06:00
|
|
|
final Provider<List<SharedNote>> sharedNotesProvider = Provider<List<SharedNote>>(
|
2023-07-27 01:40:26 -06:00
|
|
|
(ref) {
|
|
|
|
final dash = ref.watch(dashboardProvider);
|
|
|
|
if (dash == null) return [];
|
|
|
|
final sharedNotes = dash['shared_notes'] as List<dynamic>;
|
|
|
|
return sharedNotes
|
|
|
|
.map(
|
|
|
|
(e) => SharedNote.fromJson(e as Map<String, dynamic>),
|
|
|
|
)
|
|
|
|
.toList();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2024-05-30 20:44:06 -06:00
|
|
|
final dashboardProvider = StateNotifierProvider<DashBoardStateNotifier, Map<String, dynamic>?>(
|
2023-07-27 01:40:26 -06:00
|
|
|
(ref) {
|
|
|
|
return DashBoardStateNotifier(ref);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
final loadingStateProvider = StateProvider<bool>(
|
|
|
|
(ref) => false,
|
|
|
|
);
|
2023-07-22 21:29:32 -06:00
|
|
|
|
|
|
|
class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
|
2023-07-27 01:40:26 -06:00
|
|
|
DashBoardStateNotifier(this.ref) : super(null);
|
|
|
|
|
|
|
|
StateNotifierProviderRef ref;
|
2023-07-22 21:29:32 -06:00
|
|
|
|
2023-07-27 01:40:26 -06:00
|
|
|
Future<void> fetchDashboard() async {
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback(
|
|
|
|
(_) => ref.read(loadingStateProvider.notifier).state = true,
|
|
|
|
);
|
|
|
|
final token = ref.read(tokenProvider);
|
|
|
|
if (token?.familyId == null) {
|
2024-05-30 20:44:06 -06:00
|
|
|
printColor('No token, cannot fetch dashboard', textColor: TextColor.red);
|
2023-07-22 21:29:32 -06:00
|
|
|
return;
|
|
|
|
}
|
2024-05-30 20:44:06 -06:00
|
|
|
printColor('Fetching dashboard', textColor: TextColor.yellow);
|
2023-07-27 01:40:26 -06:00
|
|
|
state = await ref.read(apiProvider.notifier).get("dashboard");
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback(
|
|
|
|
(_) => ref.read(loadingStateProvider.notifier).state = false,
|
|
|
|
);
|
2023-07-22 21:29:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void update(Map<String, dynamic> data) {
|
|
|
|
if (state == null) {
|
2024-05-30 20:44:06 -06:00
|
|
|
printColor('Cant update data, state is null', textColor: TextColor.red);
|
2023-07-22 21:29:32 -06:00
|
|
|
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':
|
2023-07-27 01:40:26 -06:00
|
|
|
case 'shared_notes':
|
2023-07-22 21:29:32 -06:00
|
|
|
final subStateList = state![key] as List<dynamic>;
|
|
|
|
final subStateListObj = subStateList
|
|
|
|
.map(
|
|
|
|
(e) => e as Map<String, dynamic>,
|
|
|
|
)
|
|
|
|
.toList();
|
|
|
|
subStateListObj.removeWhere(
|
2024-05-30 20:44:06 -06:00
|
|
|
(element) => element['id'] == (data.values.first as Map<String, dynamic>)['id'],
|
2023-07-22 21:29:32 -06:00
|
|
|
);
|
|
|
|
subStateListObj.add(data.values.first);
|
|
|
|
|
|
|
|
final newState = state;
|
|
|
|
newState![key] = subStateListObj;
|
|
|
|
state = {...newState};
|
|
|
|
// printBlue(state);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(Map<String, dynamic> data) {
|
|
|
|
if (state == null) {
|
2024-05-30 20:44:06 -06:00
|
|
|
printColor('Cant add data, state is null', textColor: TextColor.red);
|
2023-07-22 21:29:32 -06:00
|
|
|
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':
|
2023-07-27 01:40:26 -06:00
|
|
|
case 'shared_noted':
|
2023-07-22 21:29:32 -06:00
|
|
|
final subStateList = state![key] as List<dynamic>;
|
|
|
|
final newState = state;
|
|
|
|
subStateList.add(data.values.first);
|
|
|
|
newState![key] = subStateList;
|
|
|
|
state = {...newState};
|
|
|
|
// printBlue(state);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-08-17 13:34:30 -06:00
|
|
|
|
|
|
|
void removeWithId(String stateKey, int id) {
|
|
|
|
if (state == null) {
|
2024-05-30 20:44:06 -06:00
|
|
|
printColor('Cant remove data, state is null', textColor: TextColor.red);
|
2023-08-17 13:34:30 -06:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (stateKey) {
|
|
|
|
case 'transactions':
|
|
|
|
case 'budget_categories':
|
|
|
|
case 'shared_noted':
|
|
|
|
final subStateList = state![stateKey] as List<dynamic>;
|
|
|
|
final newState = state;
|
2024-05-30 20:44:06 -06:00
|
|
|
subStateList.removeWhere((e) => (e as Map<String, dynamic>)['id'] == id);
|
2023-08-17 13:34:30 -06:00
|
|
|
newState![stateKey] = subStateList;
|
|
|
|
state = {...newState};
|
|
|
|
// printBlue(state);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-07-22 21:29:32 -06:00
|
|
|
}
|