rluv_client/lib/global/store.dart

207 lines
6.3 KiB
Dart

import 'dart:convert';
import 'package:colorful_print/colorful_print.dart';
import 'package:flutter/material.dart';
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';
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<SharedPreferences?> prefsProvider = StateProvider<SharedPreferences?>((ref) => null);
// final StateProvider<Token?> tokenProvider = StateProvider<Token?>((ref) {
// // final tokenStr = prefs.getString('jwt');
// // if (tokenStr != null) {
// // return Token.fromJson(jsonDecode(tokenStr));
// // }
// return null;
// });
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);
},
);
final Provider<List<BudgetCategory>> budgetCategoriesProvider = Provider<List<BudgetCategory>>((ref) {
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});
printColor('updated prefs stored categories', textColor: TextColor.blue);
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);
},
);
final Provider<List<Transaction>> transactionsProvider = Provider<List<Transaction>>((ref) {
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();
});
final Provider<List<SharedNote>> sharedNotesProvider = Provider<List<SharedNote>>(
(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();
},
);
final dashboardProvider = StateNotifierProvider<DashBoardStateNotifier, Map<String, dynamic>?>(
(ref) {
return DashBoardStateNotifier(ref);
},
);
final loadingStateProvider = StateProvider<bool>(
(ref) => false,
);
class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
DashBoardStateNotifier(this.ref) : super(null);
StateNotifierProviderRef ref;
Future<void> fetchDashboard() async {
WidgetsBinding.instance.addPostFrameCallback(
(_) => ref.read(loadingStateProvider.notifier).state = true,
);
final token = ref.read(tokenProvider);
if (token?.familyId == null) {
printColor('No token, cannot fetch dashboard', textColor: TextColor.red);
return;
}
printColor('Fetching dashboard', textColor: TextColor.yellow);
state = await ref.read(apiProvider.notifier).get("dashboard");
WidgetsBinding.instance.addPostFrameCallback(
(_) => ref.read(loadingStateProvider.notifier).state = false,
);
}
void update(Map<String, dynamic> data) {
if (state == null) {
printColor('Cant update data, state is null', textColor: TextColor.red);
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<dynamic>;
final subStateListObj = subStateList
.map(
(e) => e as Map<String, dynamic>,
)
.toList();
subStateListObj.removeWhere(
(element) => element['id'] == (data.values.first as Map<String, dynamic>)['id'],
);
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) {
printColor('Cant add data, state is null', textColor: TextColor.red);
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<dynamic>;
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) {
printColor('Cant remove data, state is null', textColor: TextColor.red);
return;
}
switch (stateKey) {
case 'transactions':
case 'budget_categories':
case 'shared_noted':
final subStateList = state![stateKey] as List<dynamic>;
final newState = state;
subStateList.removeWhere((e) => (e as Map<String, dynamic>)['id'] == id);
newState![stateKey] = subStateList;
state = {...newState};
// printBlue(state);
break;
default:
break;
}
}
}