Migrate away from helpers package
This commit is contained in:
		
							parent
							
								
									ddba989576
								
							
						
					
					
						commit
						1172e650aa
					
				@ -1,6 +1,5 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:rluv/features/account/signup.dart';
 | 
			
		||||
import 'package:rluv/global/styles.dart';
 | 
			
		||||
 | 
			
		||||
@ -13,8 +12,7 @@ class AccountCreateScreen extends ConsumerStatefulWidget {
 | 
			
		||||
  const AccountCreateScreen({super.key});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  ConsumerState<AccountCreateScreen> createState() =>
 | 
			
		||||
      _AccountCreateScreenState();
 | 
			
		||||
  ConsumerState<AccountCreateScreen> createState() => _AccountCreateScreenState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum _AccountScreen { options, login, signup }
 | 
			
		||||
@ -40,7 +38,7 @@ class _AccountCreateScreenState extends ConsumerState<AccountCreateScreen> {
 | 
			
		||||
        },
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    final screen = BuildMedia(context).size;
 | 
			
		||||
    final screen = MediaQuery.of(context).size;
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      backgroundColor: Styles.purpleNurple,
 | 
			
		||||
      body: SafeArea(
 | 
			
		||||
@ -60,11 +58,8 @@ class _AccountCreateScreenState extends ConsumerState<AccountCreateScreen> {
 | 
			
		||||
                        Padding(
 | 
			
		||||
                          padding: const EdgeInsets.symmetric(vertical: 40.0),
 | 
			
		||||
                          child: Image.asset("assets/app_icon.png",
 | 
			
		||||
                              height:
 | 
			
		||||
                                  screen.width > 500 ? 250 : screen.width * 0.5,
 | 
			
		||||
                              width: screen.width > 500
 | 
			
		||||
                                  ? 250
 | 
			
		||||
                                  : screen.width * 0.5),
 | 
			
		||||
                              height: screen.width > 500 ? 250 : screen.width * 0.5,
 | 
			
		||||
                              width: screen.width > 500 ? 250 : screen.width * 0.5),
 | 
			
		||||
                        ),
 | 
			
		||||
                        UiButton(
 | 
			
		||||
                          color: Styles.sunflower,
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:helpers/helpers/print.dart';
 | 
			
		||||
 | 
			
		||||
import '../../global/api.dart';
 | 
			
		||||
import '../../global/styles.dart';
 | 
			
		||||
@ -32,7 +30,7 @@ class _LoginState extends ConsumerState<Login> {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final screen = BuildMedia(context).size;
 | 
			
		||||
    final screen = MediaQuery.of(context).size;
 | 
			
		||||
    return Form(
 | 
			
		||||
      key: widget.formKey,
 | 
			
		||||
      child: Stack(
 | 
			
		||||
@ -205,14 +203,11 @@ class _LoginState extends ConsumerState<Login> {
 | 
			
		||||
 | 
			
		||||
  Future login() async {
 | 
			
		||||
    try {
 | 
			
		||||
      if (widget.formKey.currentState != null &&
 | 
			
		||||
          !widget.formKey.currentState!.validate()) {
 | 
			
		||||
      if (widget.formKey.currentState != null && !widget.formKey.currentState!.validate()) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      final data =
 | 
			
		||||
          await ref.read(apiProvider.notifier).post(path: 'auth/login', data: {
 | 
			
		||||
        'username':
 | 
			
		||||
            usernameController.text.isEmpty ? null : usernameController.text,
 | 
			
		||||
      final data = await ref.read(apiProvider.notifier).post(path: 'auth/login', data: {
 | 
			
		||||
        'username': usernameController.text.isEmpty ? null : usernameController.text,
 | 
			
		||||
        'email': emailController.text.isEmpty ? null : emailController.text,
 | 
			
		||||
        'password': passwordController.text,
 | 
			
		||||
      });
 | 
			
		||||
@ -227,13 +222,10 @@ class _LoginState extends ConsumerState<Login> {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // final bool success = data?['success'] ?? false;
 | 
			
		||||
      printAmber(data);
 | 
			
		||||
      showSnack(
 | 
			
		||||
          ref: ref,
 | 
			
		||||
          text: message,
 | 
			
		||||
          type: !success ? SnackType.error : SnackType.success);
 | 
			
		||||
      print(data);
 | 
			
		||||
      showSnack(ref: ref, text: message, type: !success ? SnackType.error : SnackType.success);
 | 
			
		||||
    } catch (err, st) {
 | 
			
		||||
      printRed('Error in login: $err\n$st');
 | 
			
		||||
      print('Error in login: $err\n$st');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:helpers/helpers/print.dart';
 | 
			
		||||
 | 
			
		||||
import '../../global/api.dart';
 | 
			
		||||
import '../../global/styles.dart';
 | 
			
		||||
@ -36,7 +34,7 @@ class _SignupState extends ConsumerState<Signup> {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final screen = BuildMedia(context).size;
 | 
			
		||||
    final screen = MediaQuery.of(context).size;
 | 
			
		||||
    return Form(
 | 
			
		||||
      key: widget.formKey,
 | 
			
		||||
      child: Stack(
 | 
			
		||||
@ -126,8 +124,7 @@ class _SignupState extends ConsumerState<Signup> {
 | 
			
		||||
                            ),
 | 
			
		||||
                            UiButton(
 | 
			
		||||
                              width: screen.width * 0.4,
 | 
			
		||||
                              icon: const Icon(Icons.cancel,
 | 
			
		||||
                                  color: Styles.washedStone, size: 20),
 | 
			
		||||
                              icon: const Icon(Icons.cancel, color: Styles.washedStone, size: 20),
 | 
			
		||||
                              onPressed: () {
 | 
			
		||||
                                setState(
 | 
			
		||||
                                  () => hasFamilyCode = false,
 | 
			
		||||
@ -140,9 +137,7 @@ class _SignupState extends ConsumerState<Signup> {
 | 
			
		||||
                      : Padding(
 | 
			
		||||
                          padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                          child: UiButton(
 | 
			
		||||
                            width: screen.width * 0.5 > 400
 | 
			
		||||
                                ? 400
 | 
			
		||||
                                : screen.width * 0.5,
 | 
			
		||||
                            width: screen.width * 0.5 > 400 ? 400 : screen.width * 0.5,
 | 
			
		||||
                            text: 'JOIN FAMILY',
 | 
			
		||||
                            // color: Styles.flounderBlue,
 | 
			
		||||
                            onPressed: () {
 | 
			
		||||
@ -190,8 +185,7 @@ class _SignupState extends ConsumerState<Signup> {
 | 
			
		||||
                  text,
 | 
			
		||||
                  style: TextStyle(fontSize: size.width < 350 ? 16 : 20),
 | 
			
		||||
                ),
 | 
			
		||||
                if (subtext != null)
 | 
			
		||||
                  Text(subtext, style: const TextStyle(fontSize: 12)),
 | 
			
		||||
                if (subtext != null) Text(subtext, style: const TextStyle(fontSize: 12)),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
@ -223,36 +217,29 @@ class _SignupState extends ConsumerState<Signup> {
 | 
			
		||||
 | 
			
		||||
  Future signup() async {
 | 
			
		||||
    try {
 | 
			
		||||
      if (widget.formKey.currentState != null &&
 | 
			
		||||
          !widget.formKey.currentState!.validate()) {
 | 
			
		||||
      if (widget.formKey.currentState != null && !widget.formKey.currentState!.validate()) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      final data =
 | 
			
		||||
          await ref.read(apiProvider.notifier).post(path: 'auth/signup', data: {
 | 
			
		||||
      final data = await ref.read(apiProvider.notifier).post(path: 'auth/signup', data: {
 | 
			
		||||
        'name': nameCotroller.text,
 | 
			
		||||
        'username':
 | 
			
		||||
            usernameController.text.isEmpty ? null : usernameController.text,
 | 
			
		||||
        'username': usernameController.text.isEmpty ? null : usernameController.text,
 | 
			
		||||
        'email': emailController.text.isEmpty ? null : emailController.text,
 | 
			
		||||
        'password': passwordController.text,
 | 
			
		||||
        'family_code': familyCodeController.text.isEmpty
 | 
			
		||||
            ? null
 | 
			
		||||
            : familyCodeController.text.toUpperCase(),
 | 
			
		||||
        'family_code': familyCodeController.text.isEmpty ? null : familyCodeController.text.toUpperCase(),
 | 
			
		||||
        'budget_name': 'Budget'
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      final success = data?['success'] ?? false;
 | 
			
		||||
      showSnack(
 | 
			
		||||
          ref: ref,
 | 
			
		||||
          text: data?['message'] ?? success
 | 
			
		||||
              ? 'Login successful'
 | 
			
		||||
              : 'Login unsuccessful',
 | 
			
		||||
          text: data?['message'] ?? success ? 'Login successful' : 'Login unsuccessful',
 | 
			
		||||
          type: !success ? SnackType.error : SnackType.success);
 | 
			
		||||
 | 
			
		||||
      printAmber(data);
 | 
			
		||||
      print(data);
 | 
			
		||||
      // final user = User.fromJson(data?['user']);
 | 
			
		||||
      // ref.read(tokenProvider.notifier).state =
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      printRed(err);
 | 
			
		||||
      print(err);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers.dart';
 | 
			
		||||
import 'package:rluv/features/budget/screens/transactions_listview.dart';
 | 
			
		||||
import 'package:rluv/features/budget/widgets/add_transaction_dialog.dart';
 | 
			
		||||
import 'package:rluv/features/budget/widgets/budget_category_bar.dart';
 | 
			
		||||
import 'package:rluv/features/budget/widgets/budget_net_bar.dart';
 | 
			
		||||
import 'package:rluv/global/styles.dart';
 | 
			
		||||
import 'package:rluv/global/utils.dart';
 | 
			
		||||
import 'package:rluv/models/budget_category_model.dart';
 | 
			
		||||
 | 
			
		||||
import '../../../global/store.dart';
 | 
			
		||||
import '../../../global/widgets/ui_button.dart';
 | 
			
		||||
@ -19,8 +19,7 @@ class BudgetOverviewScreen extends ConsumerStatefulWidget {
 | 
			
		||||
  final Map<String, dynamic> initialData;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  ConsumerState<BudgetOverviewScreen> createState() =>
 | 
			
		||||
      _BudgetOverviewScreenState();
 | 
			
		||||
  ConsumerState<BudgetOverviewScreen> createState() => _BudgetOverviewScreenState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
@ -30,23 +29,18 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
    final budget = ref.watch(budgetProvider);
 | 
			
		||||
    final budgetCategories = ref.watch(budgetCategoriesProvider);
 | 
			
		||||
    final transactions = ref.watch(transactionsProvider);
 | 
			
		||||
    final screen = BuildMedia(context).size;
 | 
			
		||||
    final screen = MediaQuery.of(context).size;
 | 
			
		||||
    double netExpense = 0.0;
 | 
			
		||||
    double netIncome = 0.0;
 | 
			
		||||
    double expectedExpenses = 0.0;
 | 
			
		||||
    Map<int, double> budgetCategoryNetMap = {};
 | 
			
		||||
    netExpense = transactions
 | 
			
		||||
        .where((t) => t.type == TransactionType.expense)
 | 
			
		||||
        .fold(netExpense, (net, t) => net + t.amount);
 | 
			
		||||
    netIncome = transactions
 | 
			
		||||
        .where((t) => t.type == TransactionType.income)
 | 
			
		||||
        .fold(netIncome, (net, t) => net + t.amount);
 | 
			
		||||
    netExpense =
 | 
			
		||||
        transactions.where((t) => t.type == TransactionType.expense).fold(netExpense, (net, t) => net + t.amount);
 | 
			
		||||
    netIncome = transactions.where((t) => t.type == TransactionType.income).fold(netIncome, (net, t) => net + t.amount);
 | 
			
		||||
    for (final bud in budgetCategories) {
 | 
			
		||||
      double net = 0.0;
 | 
			
		||||
      expectedExpenses += bud.amount;
 | 
			
		||||
      net = transactions
 | 
			
		||||
          .where((t) => t.budgetCategoryId == bud.id)
 | 
			
		||||
          .fold(net, (net, t) => net + t.amount);
 | 
			
		||||
      net = transactions.where((t) => t.budgetCategoryId == bud.id).fold(net, (net, t) => net + t.amount);
 | 
			
		||||
      budgetCategoryNetMap[bud.id!] = net;
 | 
			
		||||
    }
 | 
			
		||||
    return Stack(
 | 
			
		||||
@ -64,23 +58,14 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
                  const Spacer(flex: 2),
 | 
			
		||||
                  Text(
 | 
			
		||||
                    formatDate(DateTime.now()),
 | 
			
		||||
                    style: const TextStyle(
 | 
			
		||||
                        fontSize: 16, color: Styles.electricBlue),
 | 
			
		||||
                    style: const TextStyle(fontSize: 16, color: Styles.electricBlue),
 | 
			
		||||
                  ),
 | 
			
		||||
                  const Spacer(),
 | 
			
		||||
                  const Text('MONTHLY',
 | 
			
		||||
                      style:
 | 
			
		||||
                          TextStyle(fontSize: 42, color: Styles.electricBlue)),
 | 
			
		||||
                  const Text('MONTHLY', style: TextStyle(fontSize: 42, color: Styles.electricBlue)),
 | 
			
		||||
                  const Spacer(flex: 2),
 | 
			
		||||
                  BudgetNetBar(
 | 
			
		||||
                      isPositive: true,
 | 
			
		||||
                      net: netIncome,
 | 
			
		||||
                      expected: budget?.expectedIncome ?? 0.0),
 | 
			
		||||
                  BudgetNetBar(isPositive: true, net: netIncome, expected: budget?.expectedIncome ?? 0.0),
 | 
			
		||||
                  const Spacer(),
 | 
			
		||||
                  BudgetNetBar(
 | 
			
		||||
                      isPositive: false,
 | 
			
		||||
                      net: netExpense,
 | 
			
		||||
                      expected: expectedExpenses),
 | 
			
		||||
                  BudgetNetBar(isPositive: false, net: netExpense, expected: expectedExpenses),
 | 
			
		||||
                  const Spacer(),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
@ -107,8 +92,7 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
                              padding: EdgeInsets.all(8.0),
 | 
			
		||||
                              child: Text(
 | 
			
		||||
                                'BUDGET',
 | 
			
		||||
                                style: TextStyle(
 | 
			
		||||
                                    fontSize: 28, color: Styles.electricBlue),
 | 
			
		||||
                                style: TextStyle(fontSize: 28, color: Styles.electricBlue),
 | 
			
		||||
                              ),
 | 
			
		||||
                            ),
 | 
			
		||||
                            budgetCategories.isEmpty
 | 
			
		||||
@ -120,25 +104,18 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
                                        children: [
 | 
			
		||||
                                          const Padding(
 | 
			
		||||
                                            padding: EdgeInsets.all(8.0),
 | 
			
		||||
                                            child: Text(
 | 
			
		||||
                                                'No budget categories created yet, add some!'),
 | 
			
		||||
                                            child: Text('No budget categories created yet, add some!'),
 | 
			
		||||
                                          ),
 | 
			
		||||
                                          UiButton(
 | 
			
		||||
                                            onPressed:
 | 
			
		||||
                                                ref.watch(budgetProvider) ==
 | 
			
		||||
                                                        null
 | 
			
		||||
                                                    ? null
 | 
			
		||||
                                                    : () => showDialog(
 | 
			
		||||
                                                          context: context,
 | 
			
		||||
                                                          builder: (context) => Dialog(
 | 
			
		||||
                                                              shape: Styles
 | 
			
		||||
                                                                  .dialogShape,
 | 
			
		||||
                                                              backgroundColor:
 | 
			
		||||
                                                                  Styles
 | 
			
		||||
                                                                      .dialogColor,
 | 
			
		||||
                                                              child:
 | 
			
		||||
                                                                  const BudgetCategoryDialog()),
 | 
			
		||||
                                                        ),
 | 
			
		||||
                                            onPressed: ref.watch(budgetProvider) == null
 | 
			
		||||
                                                ? null
 | 
			
		||||
                                                : () => showDialog(
 | 
			
		||||
                                                      context: context,
 | 
			
		||||
                                                      builder: (context) => Dialog(
 | 
			
		||||
                                                          shape: Styles.dialogShape,
 | 
			
		||||
                                                          backgroundColor: Styles.dialogColor,
 | 
			
		||||
                                                          child: const BudgetCategoryDialog()),
 | 
			
		||||
                                                    ),
 | 
			
		||||
                                            text: 'Add Category',
 | 
			
		||||
                                          ),
 | 
			
		||||
                                        ],
 | 
			
		||||
@ -146,55 +123,42 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  )
 | 
			
		||||
                                : Padding(
 | 
			
		||||
                                    padding: const EdgeInsets.symmetric(
 | 
			
		||||
                                        horizontal: 2.0, vertical: 4.0),
 | 
			
		||||
                                    padding: const EdgeInsets.symmetric(horizontal: 2.0, vertical: 4.0),
 | 
			
		||||
                                    child: SizedBox(
 | 
			
		||||
                                      height: screen.height * 0.36,
 | 
			
		||||
                                      child: Scrollbar(
 | 
			
		||||
                                        controller: budgetListScrollController,
 | 
			
		||||
                                        thumbVisibility: true,
 | 
			
		||||
                                        child: ListView(
 | 
			
		||||
                                          physics:
 | 
			
		||||
                                              const BouncingScrollPhysics(),
 | 
			
		||||
                                          controller:
 | 
			
		||||
                                              budgetListScrollController,
 | 
			
		||||
                                          physics: const BouncingScrollPhysics(),
 | 
			
		||||
                                          controller: budgetListScrollController,
 | 
			
		||||
                                          shrinkWrap: true,
 | 
			
		||||
                                          children: [
 | 
			
		||||
                                            ...budgetCategories
 | 
			
		||||
                                                .mapIndexed((i, category) {
 | 
			
		||||
                                            ...budgetCategories.map((BudgetCategory category) {
 | 
			
		||||
                                              final i = budgetCategories.indexOf(category);
 | 
			
		||||
                                              return BudgetCategoryBar(
 | 
			
		||||
                                                budgetCategory: category,
 | 
			
		||||
                                                currentAmount:
 | 
			
		||||
                                                    budgetCategoryNetMap[
 | 
			
		||||
                                                        category.id]!,
 | 
			
		||||
                                                currentAmount: budgetCategoryNetMap[category.id]!,
 | 
			
		||||
                                                index: i,
 | 
			
		||||
                                              );
 | 
			
		||||
                                            }).toList(),
 | 
			
		||||
                                            const SizedBox(height: 20),
 | 
			
		||||
                                            Row(
 | 
			
		||||
                                              mainAxisAlignment:
 | 
			
		||||
                                                  MainAxisAlignment.center,
 | 
			
		||||
                                              mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
                                              children: [
 | 
			
		||||
                                                SizedBox(
 | 
			
		||||
                                                  width: 140,
 | 
			
		||||
                                                  child: ElevatedButton(
 | 
			
		||||
                                                    onPressed: ref.watch(
 | 
			
		||||
                                                                budgetProvider) ==
 | 
			
		||||
                                                            null
 | 
			
		||||
                                                    onPressed: ref.watch(budgetProvider) == null
 | 
			
		||||
                                                        ? null
 | 
			
		||||
                                                        : () => showDialog(
 | 
			
		||||
                                                              context: context,
 | 
			
		||||
                                                              builder: (context) => Dialog(
 | 
			
		||||
                                                                  shape: Styles
 | 
			
		||||
                                                                      .dialogShape,
 | 
			
		||||
                                                                  backgroundColor:
 | 
			
		||||
                                                                      Styles
 | 
			
		||||
                                                                          .dialogColor,
 | 
			
		||||
                                                                  child:
 | 
			
		||||
                                                                      const BudgetCategoryDialog()),
 | 
			
		||||
                                                                  shape: Styles.dialogShape,
 | 
			
		||||
                                                                  backgroundColor: Styles.dialogColor,
 | 
			
		||||
                                                                  child: const BudgetCategoryDialog()),
 | 
			
		||||
                                                            ),
 | 
			
		||||
                                                    child: const Text(
 | 
			
		||||
                                                        'Add Category'),
 | 
			
		||||
                                                    child: const Text('Add Category'),
 | 
			
		||||
                                                  ),
 | 
			
		||||
                                                ),
 | 
			
		||||
                                              ],
 | 
			
		||||
@ -214,8 +178,7 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
                      children: [
 | 
			
		||||
                        Expanded(
 | 
			
		||||
                          child: Padding(
 | 
			
		||||
                            padding:
 | 
			
		||||
                                const EdgeInsets.only(left: 20.0, right: 15.0),
 | 
			
		||||
                            padding: const EdgeInsets.only(left: 20.0, right: 15.0),
 | 
			
		||||
                            child: Container(
 | 
			
		||||
                              height: 70,
 | 
			
		||||
                              decoration: BoxDecoration(
 | 
			
		||||
@ -225,8 +188,7 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
                              child: InkWell(
 | 
			
		||||
                                child: const Center(
 | 
			
		||||
                                  child: Padding(
 | 
			
		||||
                                    padding: EdgeInsets.symmetric(
 | 
			
		||||
                                        horizontal: 20.0, vertical: 14.0),
 | 
			
		||||
                                    padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 14.0),
 | 
			
		||||
                                    child: FittedBox(
 | 
			
		||||
                                      child: Text(
 | 
			
		||||
                                        'Transaction History',
 | 
			
		||||
@ -238,10 +200,7 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
                                ),
 | 
			
		||||
                                onTap: () {
 | 
			
		||||
                                  Navigator.push(
 | 
			
		||||
                                      context,
 | 
			
		||||
                                      MaterialPageRoute(
 | 
			
		||||
                                          builder: (context) =>
 | 
			
		||||
                                              const TransactionsListview()));
 | 
			
		||||
                                      context, MaterialPageRoute(builder: (context) => const TransactionsListview()));
 | 
			
		||||
                                },
 | 
			
		||||
                              ),
 | 
			
		||||
                            ),
 | 
			
		||||
@ -292,8 +251,7 @@ class _BudgetOverviewScreenState extends ConsumerState<BudgetOverviewScreen> {
 | 
			
		||||
            child: IconButton(
 | 
			
		||||
              icon: const Icon(Icons.loop),
 | 
			
		||||
              color: Styles.seaweedGreen,
 | 
			
		||||
              onPressed: () =>
 | 
			
		||||
                  ref.read(dashboardProvider.notifier).fetchDashboard(),
 | 
			
		||||
              onPressed: () => ref.read(dashboardProvider.notifier).fetchDashboard(),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:rluv/features/budget/widgets/transaction_list_item.dart';
 | 
			
		||||
import 'package:rluv/global/styles.dart';
 | 
			
		||||
import 'package:rluv/models/transaction_model.dart';
 | 
			
		||||
@ -12,8 +11,7 @@ class TransactionsListview extends ConsumerStatefulWidget {
 | 
			
		||||
  const TransactionsListview({super.key});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  ConsumerState<TransactionsListview> createState() =>
 | 
			
		||||
      _TransactionsListviewState();
 | 
			
		||||
  ConsumerState<TransactionsListview> createState() => _TransactionsListviewState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
@ -23,8 +21,7 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
  void initState() {
 | 
			
		||||
    // TODO: implement initState
 | 
			
		||||
    WidgetsBinding.instance.addPostFrameCallback((_) {
 | 
			
		||||
      ref.read(selectedTransactionSortProvider.notifier).state =
 | 
			
		||||
          TransactionSort.all;
 | 
			
		||||
      ref.read(selectedTransactionSortProvider.notifier).state = TransactionSort.all;
 | 
			
		||||
      ref.read(selectedSortDateProvider.notifier).state = SortDate.decending;
 | 
			
		||||
    });
 | 
			
		||||
    super.initState();
 | 
			
		||||
@ -34,8 +31,8 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final budgetCategories = ref.watch(budgetCategoriesProvider);
 | 
			
		||||
    if (ref.read(selectedCategory) == null && budgetCategories.isNotEmpty) {
 | 
			
		||||
      WidgetsBinding.instance.addPostFrameCallback((_) =>
 | 
			
		||||
          ref.read(selectedCategory.notifier).state = budgetCategories.first);
 | 
			
		||||
      WidgetsBinding.instance
 | 
			
		||||
          .addPostFrameCallback((_) => ref.read(selectedCategory.notifier).state = budgetCategories.first);
 | 
			
		||||
    }
 | 
			
		||||
    final sortType = ref.watch(selectedTransactionSortProvider);
 | 
			
		||||
    final sortDate = ref.watch(selectedSortDateProvider);
 | 
			
		||||
@ -60,8 +57,7 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
        if (ref.read(selectedCategory) != null) {
 | 
			
		||||
          transactions = transactions
 | 
			
		||||
              .where(
 | 
			
		||||
                (element) =>
 | 
			
		||||
                    element.budgetCategoryId == ref.read(selectedCategory)!.id,
 | 
			
		||||
                (element) => element.budgetCategoryId == ref.read(selectedCategory)!.id,
 | 
			
		||||
              )
 | 
			
		||||
              .toList();
 | 
			
		||||
        }
 | 
			
		||||
@ -79,15 +75,15 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    WidgetsBinding.instance.addPostFrameCallback((_) =>
 | 
			
		||||
        ref.read(transactionHistoryListProvider.notifier).state = transactions);
 | 
			
		||||
    WidgetsBinding.instance
 | 
			
		||||
        .addPostFrameCallback((_) => ref.read(transactionHistoryListProvider.notifier).state = transactions);
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      endDrawer: Drawer(
 | 
			
		||||
        backgroundColor: Styles.purpleNurple,
 | 
			
		||||
        child: SafeArea(
 | 
			
		||||
          child: Column(
 | 
			
		||||
            children: [
 | 
			
		||||
              SizedBox(height: BuildMedia(context).height * 0.15),
 | 
			
		||||
              SizedBox(height: MediaQuery.of(context).size.height * 0.15),
 | 
			
		||||
              DropdownButton<TransactionSort>(
 | 
			
		||||
                  dropdownColor: Styles.lavender,
 | 
			
		||||
                  value: ref.watch(selectedTransactionSortProvider),
 | 
			
		||||
@ -108,8 +104,7 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
                      .toList(),
 | 
			
		||||
                  onChanged: (TransactionSort? value) {
 | 
			
		||||
                    if (value != null) {
 | 
			
		||||
                      ref.read(selectedTransactionSortProvider.notifier).state =
 | 
			
		||||
                          value;
 | 
			
		||||
                      ref.read(selectedTransactionSortProvider.notifier).state = value;
 | 
			
		||||
                    }
 | 
			
		||||
                  }),
 | 
			
		||||
              const SizedBox(height: 20),
 | 
			
		||||
@ -137,8 +132,7 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
                    }
 | 
			
		||||
                  }),
 | 
			
		||||
              const SizedBox(height: 20),
 | 
			
		||||
              if (ref.read(selectedTransactionSortProvider) ==
 | 
			
		||||
                  TransactionSort.category)
 | 
			
		||||
              if (ref.read(selectedTransactionSortProvider) == TransactionSort.category)
 | 
			
		||||
                DropdownButton<BudgetCategory>(
 | 
			
		||||
                  dropdownColor: Styles.lavender,
 | 
			
		||||
                  value: ref.watch(selectedCategory),
 | 
			
		||||
@ -154,8 +148,7 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
                                width: 18,
 | 
			
		||||
                                decoration: BoxDecoration(
 | 
			
		||||
                                  shape: BoxShape.circle,
 | 
			
		||||
                                  border: Border.all(
 | 
			
		||||
                                      color: Colors.black, width: 1.5),
 | 
			
		||||
                                  border: Border.all(color: Colors.black, width: 1.5),
 | 
			
		||||
                                  color: e.color,
 | 
			
		||||
                                ),
 | 
			
		||||
                              ),
 | 
			
		||||
@ -186,9 +179,7 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
                alignment: Alignment.topLeft,
 | 
			
		||||
                child: Padding(
 | 
			
		||||
                  padding: const EdgeInsets.only(left: 8.0, top: 16.0),
 | 
			
		||||
                  child: IconButton(
 | 
			
		||||
                      icon: const Icon(Icons.chevron_left),
 | 
			
		||||
                      onPressed: () => Navigator.pop(context)),
 | 
			
		||||
                  child: IconButton(icon: const Icon(Icons.chevron_left), onPressed: () => Navigator.pop(context)),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
              const Center(
 | 
			
		||||
@ -201,14 +192,11 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
                  Row(mainAxisAlignment: MainAxisAlignment.center, children: [
 | 
			
		||||
                    Padding(
 | 
			
		||||
                      padding: const EdgeInsets.only(left: 8.0, top: 16.0),
 | 
			
		||||
                      child: IconButton(
 | 
			
		||||
                          icon: const Icon(Icons.chevron_left),
 | 
			
		||||
                          onPressed: () => Navigator.pop(context)),
 | 
			
		||||
                      child: IconButton(icon: const Icon(Icons.chevron_left), onPressed: () => Navigator.pop(context)),
 | 
			
		||||
                    ),
 | 
			
		||||
                    const Spacer(),
 | 
			
		||||
                    const Padding(
 | 
			
		||||
                      padding:
 | 
			
		||||
                          EdgeInsets.symmetric(vertical: 18.0, horizontal: 0.0),
 | 
			
		||||
                      padding: EdgeInsets.symmetric(vertical: 18.0, horizontal: 0.0),
 | 
			
		||||
                      child: Text(
 | 
			
		||||
                        'Transaction History',
 | 
			
		||||
                        style: TextStyle(fontSize: 28),
 | 
			
		||||
@ -245,8 +233,7 @@ class _TransactionsListviewState extends ConsumerState<TransactionsListview> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void toggleDrawer() {
 | 
			
		||||
    if (scaffoldKey.currentState != null &&
 | 
			
		||||
        scaffoldKey.currentState!.isDrawerOpen) {
 | 
			
		||||
    if (scaffoldKey.currentState != null && scaffoldKey.currentState!.isDrawerOpen) {
 | 
			
		||||
      scaffoldKey.currentState!.openDrawer();
 | 
			
		||||
    } else if (scaffoldKey.currentState != null) {
 | 
			
		||||
      scaffoldKey.currentState!.openEndDrawer();
 | 
			
		||||
@ -292,8 +279,7 @@ final selectedTransactionSortProvider = StateProvider<TransactionSort>(
 | 
			
		||||
  (ref) => TransactionSort.all,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
final selectedSortDateProvider =
 | 
			
		||||
    StateProvider<SortDate>((ref) => SortDate.decending);
 | 
			
		||||
final selectedSortDateProvider = StateProvider<SortDate>((ref) => SortDate.decending);
 | 
			
		||||
 | 
			
		||||
final transactionHistoryListProvider = StateProvider<List<Transaction>>(
 | 
			
		||||
  (ref) => [],
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:helpers/helpers/print.dart';
 | 
			
		||||
import 'package:rluv/global/styles.dart';
 | 
			
		||||
import 'package:rluv/models/budget.dart';
 | 
			
		||||
import 'package:rluv/models/budget_category_model.dart';
 | 
			
		||||
@ -17,12 +15,10 @@ class BudgetCategoryDialog extends ConsumerStatefulWidget {
 | 
			
		||||
  final BudgetCategory? category;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  ConsumerState<BudgetCategoryDialog> createState() =>
 | 
			
		||||
      _AddBudgetCategoryDialogState();
 | 
			
		||||
  ConsumerState<BudgetCategoryDialog> createState() => _AddBudgetCategoryDialogState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AddBudgetCategoryDialogState
 | 
			
		||||
    extends ConsumerState<BudgetCategoryDialog> {
 | 
			
		||||
class _AddBudgetCategoryDialogState extends ConsumerState<BudgetCategoryDialog> {
 | 
			
		||||
  late final Budget? budget;
 | 
			
		||||
  final categoryNameController = TextEditingController();
 | 
			
		||||
  final amountController = TextEditingController();
 | 
			
		||||
@ -65,12 +61,11 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
      return Container();
 | 
			
		||||
    }
 | 
			
		||||
    return SizedBox(
 | 
			
		||||
      width: BuildMedia(context).width * Styles.dialogScreenWidthFactor,
 | 
			
		||||
      width: MediaQuery.of(context).size.width * Styles.dialogScreenWidthFactor,
 | 
			
		||||
      child: Stack(
 | 
			
		||||
        children: [
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding:
 | 
			
		||||
                const EdgeInsets.symmetric(vertical: 18.0, horizontal: 32.0),
 | 
			
		||||
            padding: const EdgeInsets.symmetric(vertical: 18.0, horizontal: 32.0),
 | 
			
		||||
            child: Form(
 | 
			
		||||
              key: formKey,
 | 
			
		||||
              child: Column(
 | 
			
		||||
@ -78,9 +73,7 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
                children: [
 | 
			
		||||
                  Padding(
 | 
			
		||||
                    padding: const EdgeInsets.only(bottom: 18.0),
 | 
			
		||||
                    child: Text(widget.category == null
 | 
			
		||||
                        ? 'Add Category:'
 | 
			
		||||
                        : 'Edit Category'),
 | 
			
		||||
                    child: Text(widget.category == null ? 'Add Category:' : 'Edit Category'),
 | 
			
		||||
                  ),
 | 
			
		||||
                  Row(
 | 
			
		||||
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
 | 
			
		||||
@ -149,8 +142,7 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
                    ],
 | 
			
		||||
                  ),
 | 
			
		||||
                  Padding(
 | 
			
		||||
                    padding: const EdgeInsets.symmetric(
 | 
			
		||||
                        vertical: 6.0, horizontal: 16.0),
 | 
			
		||||
                    padding: const EdgeInsets.symmetric(vertical: 6.0, horizontal: 16.0),
 | 
			
		||||
                    child: SizedBox(
 | 
			
		||||
                      height: 76,
 | 
			
		||||
                      child: ListView.builder(
 | 
			
		||||
@ -164,23 +156,21 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
                              } else {
 | 
			
		||||
                                setState(() => selectedColorIndex = -1);
 | 
			
		||||
                              }
 | 
			
		||||
                              printBlue(selectedColorIndex);
 | 
			
		||||
                              print(selectedColorIndex);
 | 
			
		||||
                            },
 | 
			
		||||
                            child: Padding(
 | 
			
		||||
                              padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                              child: AnimatedContainer(
 | 
			
		||||
                                decoration: selectedColorIndex == index
 | 
			
		||||
                                    ? BoxDecoration(
 | 
			
		||||
                                        borderRadius:
 | 
			
		||||
                                            BorderRadius.circular(15.0),
 | 
			
		||||
                                        borderRadius: BorderRadius.circular(15.0),
 | 
			
		||||
                                        border: Border.all(
 | 
			
		||||
                                          color: Styles.washedStone,
 | 
			
		||||
                                          width: 2.0,
 | 
			
		||||
                                        ),
 | 
			
		||||
                                      )
 | 
			
		||||
                                    : BoxDecoration(
 | 
			
		||||
                                        borderRadius:
 | 
			
		||||
                                            BorderRadius.circular(5.0),
 | 
			
		||||
                                        borderRadius: BorderRadius.circular(5.0),
 | 
			
		||||
                                        border: Border.all(
 | 
			
		||||
                                          color: Colors.transparent,
 | 
			
		||||
                                          width: 2.0,
 | 
			
		||||
@ -205,8 +195,7 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
                                        decoration: BoxDecoration(
 | 
			
		||||
                                          color: colors[index],
 | 
			
		||||
                                          shape: BoxShape.circle,
 | 
			
		||||
                                          border: Border.all(
 | 
			
		||||
                                              color: Colors.black, width: 1.5),
 | 
			
		||||
                                          border: Border.all(color: Colors.black, width: 1.5),
 | 
			
		||||
                                        ),
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    ],
 | 
			
		||||
@ -227,8 +216,7 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
                        color: Styles.expensesRed,
 | 
			
		||||
                        text: 'DELETE',
 | 
			
		||||
                        onPressed: () {
 | 
			
		||||
                          if (formKey.currentState != null &&
 | 
			
		||||
                              formKey.currentState!.validate()) {
 | 
			
		||||
                          if (formKey.currentState != null && formKey.currentState!.validate()) {
 | 
			
		||||
                            removeCategory().then((success) {
 | 
			
		||||
                              Navigator.pop(context);
 | 
			
		||||
                              if (success) {
 | 
			
		||||
@ -254,8 +242,7 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
                    color: Styles.lavender,
 | 
			
		||||
                    text: 'SAVE',
 | 
			
		||||
                    onPressed: () {
 | 
			
		||||
                      if (formKey.currentState != null &&
 | 
			
		||||
                          formKey.currentState!.validate()) {
 | 
			
		||||
                      if (formKey.currentState != null && formKey.currentState!.validate()) {
 | 
			
		||||
                        submitCategory(colors[selectedColorIndex]).then((_) {
 | 
			
		||||
                          Navigator.pop(context);
 | 
			
		||||
                          showSnack(
 | 
			
		||||
@ -282,7 +269,7 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
 | 
			
		||||
  Future submitCategory(Color categoryColor) async {
 | 
			
		||||
    if (formKey.currentState != null && !formKey.currentState!.validate()) {
 | 
			
		||||
      printPink('Failed validation');
 | 
			
		||||
      print('Failed validation');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    Map<String, dynamic>? budgetData;
 | 
			
		||||
@ -296,58 +283,41 @@ class _AddBudgetCategoryDialogState
 | 
			
		||||
        name: categoryNameController.text,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      budgetData = await ref
 | 
			
		||||
          .read(apiProvider.notifier)
 | 
			
		||||
          .post(path: 'budget_category', data: newBudget.toJson());
 | 
			
		||||
      budgetData = await ref.read(apiProvider.notifier).post(path: 'budget_category', data: newBudget.toJson());
 | 
			
		||||
      success = budgetData != null ? budgetData['success'] as bool : false;
 | 
			
		||||
      if (success) {
 | 
			
		||||
        ref
 | 
			
		||||
            .read(dashboardProvider.notifier)
 | 
			
		||||
            .add({'budget_categories': budgetData});
 | 
			
		||||
        ref.read(dashboardProvider.notifier).add({'budget_categories': budgetData});
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      final newBudget =
 | 
			
		||||
          BudgetCategory.copyWith(category: widget.category!, data: {
 | 
			
		||||
      final newBudget = BudgetCategory.copyWith(category: widget.category!, data: {
 | 
			
		||||
        'amount': double.parse(amountController.text),
 | 
			
		||||
        'color': categoryColor,
 | 
			
		||||
        'name': categoryNameController.text
 | 
			
		||||
      });
 | 
			
		||||
      budgetData = await ref
 | 
			
		||||
          .read(apiProvider.notifier)
 | 
			
		||||
          .put(path: 'budget_category', data: newBudget.toJson());
 | 
			
		||||
      budgetData = await ref.read(apiProvider.notifier).put(path: 'budget_category', data: newBudget.toJson());
 | 
			
		||||
      success = budgetData != null ? budgetData['success'] as bool : false;
 | 
			
		||||
      if (success) {
 | 
			
		||||
        ref
 | 
			
		||||
            .read(dashboardProvider.notifier)
 | 
			
		||||
            .update({'budget_categories': budgetData});
 | 
			
		||||
        ref.read(dashboardProvider.notifier).update({'budget_categories': budgetData});
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (success) {
 | 
			
		||||
      showSnack(
 | 
			
		||||
          ref: ref,
 | 
			
		||||
          text: widget.category == null
 | 
			
		||||
              ? 'Added budget category!'
 | 
			
		||||
              : 'Updated category!',
 | 
			
		||||
          text: widget.category == null ? 'Added budget category!' : 'Updated category!',
 | 
			
		||||
          type: SnackType.error);
 | 
			
		||||
    } else {
 | 
			
		||||
      showSnack(
 | 
			
		||||
          ref: ref,
 | 
			
		||||
          text: widget.category == null
 | 
			
		||||
              ? 'Could not add budget category'
 | 
			
		||||
              : 'Could not update category',
 | 
			
		||||
          text: widget.category == null ? 'Could not add budget category' : 'Could not update category',
 | 
			
		||||
          type: SnackType.error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<bool> removeCategory() async {
 | 
			
		||||
    final res = await ref
 | 
			
		||||
        .read(apiProvider.notifier)
 | 
			
		||||
        .delete(path: 'budget_category', data: {'id': widget.category!.id});
 | 
			
		||||
    final res = await ref.read(apiProvider.notifier).delete(path: 'budget_category', data: {'id': widget.category!.id});
 | 
			
		||||
    final success = res != null ? res['success'] as bool : false;
 | 
			
		||||
    if (success) {
 | 
			
		||||
      ref
 | 
			
		||||
          .read(dashboardProvider.notifier)
 | 
			
		||||
          .removeWithId('budget_categories', widget.category!.id!);
 | 
			
		||||
      ref.read(dashboardProvider.notifier).removeWithId('budget_categories', widget.category!.id!);
 | 
			
		||||
    }
 | 
			
		||||
    return success;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import 'package:flutter/foundation.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:rluv/global/utils.dart';
 | 
			
		||||
 | 
			
		||||
import '../../../global/api.dart';
 | 
			
		||||
@ -18,8 +17,7 @@ class TransactionDialog extends ConsumerStatefulWidget {
 | 
			
		||||
  final Transaction? transaction;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  ConsumerState<TransactionDialog> createState() =>
 | 
			
		||||
      _AddTransactionDialogState();
 | 
			
		||||
  ConsumerState<TransactionDialog> createState() => _AddTransactionDialogState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
@ -37,8 +35,7 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    if (widget.transaction != null) {
 | 
			
		||||
      amountController =
 | 
			
		||||
          TextEditingController(text: widget.transaction!.amount.toString());
 | 
			
		||||
      amountController = TextEditingController(text: widget.transaction!.amount.toString());
 | 
			
		||||
      memoController = TextEditingController(text: widget.transaction!.memo);
 | 
			
		||||
      transactionType = widget.transaction!.type;
 | 
			
		||||
      selectedDate = widget.transaction!.date;
 | 
			
		||||
@ -53,8 +50,7 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
    }
 | 
			
		||||
    final u = ref.read(userProvider);
 | 
			
		||||
    if (u == null) {
 | 
			
		||||
      WidgetsBinding.instance.addPostFrameCallback(
 | 
			
		||||
          (_) => ref.read(jwtProvider.notifier).revokeToken());
 | 
			
		||||
      WidgetsBinding.instance.addPostFrameCallback((_) => ref.read(jwtProvider.notifier).revokeToken());
 | 
			
		||||
    } else {
 | 
			
		||||
      user = u;
 | 
			
		||||
    }
 | 
			
		||||
@ -65,10 +61,9 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    if (user == null) return Container();
 | 
			
		||||
    final List<BudgetCategory> budgetCategories =
 | 
			
		||||
        ref.read(budgetCategoriesProvider);
 | 
			
		||||
    final List<BudgetCategory> budgetCategories = ref.read(budgetCategoriesProvider);
 | 
			
		||||
    return SizedBox(
 | 
			
		||||
        width: BuildMedia(context).width * Styles.dialogScreenWidthFactor,
 | 
			
		||||
        width: MediaQuery.of(context).size.width * Styles.dialogScreenWidthFactor,
 | 
			
		||||
        child: budgetCategories.isEmpty
 | 
			
		||||
            ? const Padding(
 | 
			
		||||
                padding: EdgeInsets.all(8.0),
 | 
			
		||||
@ -91,25 +86,21 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
                              onTap: transactionType == TransactionType.expense
 | 
			
		||||
                                  ? null
 | 
			
		||||
                                  : () {
 | 
			
		||||
                                      setState(() => transactionType =
 | 
			
		||||
                                          TransactionType.expense);
 | 
			
		||||
                                      setState(() => transactionType = TransactionType.expense);
 | 
			
		||||
                                    },
 | 
			
		||||
                              child: AnimatedContainer(
 | 
			
		||||
                                height: 38,
 | 
			
		||||
                                width: 80,
 | 
			
		||||
                                decoration: BoxDecoration(
 | 
			
		||||
                                    borderRadius: const BorderRadius.only(
 | 
			
		||||
                                        topLeft: Radius.circular(8.0),
 | 
			
		||||
                                        topRight: Radius.circular(8.0)),
 | 
			
		||||
                                    color: transactionType ==
 | 
			
		||||
                                            TransactionType.expense
 | 
			
		||||
                                        topLeft: Radius.circular(8.0), topRight: Radius.circular(8.0)),
 | 
			
		||||
                                    color: transactionType == TransactionType.expense
 | 
			
		||||
                                        ? Styles.lavender
 | 
			
		||||
                                        : Styles.washedStone),
 | 
			
		||||
                                duration: const Duration(milliseconds: 300),
 | 
			
		||||
                                child: const Padding(
 | 
			
		||||
                                  padding: EdgeInsets.all(8.0),
 | 
			
		||||
                                  child: Text('Expense',
 | 
			
		||||
                                      style: TextStyle(fontSize: 16)),
 | 
			
		||||
                                  child: Text('Expense', style: TextStyle(fontSize: 16)),
 | 
			
		||||
                                ),
 | 
			
		||||
                              ),
 | 
			
		||||
                            ),
 | 
			
		||||
@ -117,25 +108,20 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
                            onTap: transactionType == TransactionType.income
 | 
			
		||||
                                ? null
 | 
			
		||||
                                : () {
 | 
			
		||||
                                    setState(() => transactionType =
 | 
			
		||||
                                        TransactionType.income);
 | 
			
		||||
                                    setState(() => transactionType = TransactionType.income);
 | 
			
		||||
                                  },
 | 
			
		||||
                            child: AnimatedContainer(
 | 
			
		||||
                              height: 38,
 | 
			
		||||
                              width: 80,
 | 
			
		||||
                              decoration: BoxDecoration(
 | 
			
		||||
                                  borderRadius: const BorderRadius.only(
 | 
			
		||||
                                      topLeft: Radius.circular(8.0),
 | 
			
		||||
                                      topRight: Radius.circular(8.0)),
 | 
			
		||||
                                      topLeft: Radius.circular(8.0), topRight: Radius.circular(8.0)),
 | 
			
		||||
                                  color:
 | 
			
		||||
                                      transactionType == TransactionType.income
 | 
			
		||||
                                          ? Styles.lavender
 | 
			
		||||
                                          : Styles.washedStone),
 | 
			
		||||
                                      transactionType == TransactionType.income ? Styles.lavender : Styles.washedStone),
 | 
			
		||||
                              duration: const Duration(milliseconds: 300),
 | 
			
		||||
                              child: const Padding(
 | 
			
		||||
                                padding: EdgeInsets.all(8.0),
 | 
			
		||||
                                child: Text('Income',
 | 
			
		||||
                                    style: TextStyle(fontSize: 16)),
 | 
			
		||||
                                child: Text('Income', style: TextStyle(fontSize: 16)),
 | 
			
		||||
                              ),
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
@ -208,9 +194,7 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
                                                    width: 18,
 | 
			
		||||
                                                    decoration: BoxDecoration(
 | 
			
		||||
                                                      shape: BoxShape.circle,
 | 
			
		||||
                                                      border: Border.all(
 | 
			
		||||
                                                          color: Colors.black,
 | 
			
		||||
                                                          width: 1.5),
 | 
			
		||||
                                                      border: Border.all(color: Colors.black, width: 1.5),
 | 
			
		||||
                                                      color: e.color,
 | 
			
		||||
                                                    ),
 | 
			
		||||
                                                  ),
 | 
			
		||||
@ -226,8 +210,7 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
                                          if (kDebugMode) {
 | 
			
		||||
                                            print('${value.name} selected');
 | 
			
		||||
                                          }
 | 
			
		||||
                                          setState(() =>
 | 
			
		||||
                                              selectedBudgetCategory = value);
 | 
			
		||||
                                          setState(() => selectedBudgetCategory = value);
 | 
			
		||||
                                        }
 | 
			
		||||
                                      },
 | 
			
		||||
                                    ),
 | 
			
		||||
@ -247,7 +230,7 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    Container(
 | 
			
		||||
                      width: BuildMedia(context).width * 0.65,
 | 
			
		||||
                      width: MediaQuery.of(context).size.width * 0.65,
 | 
			
		||||
                      height: 100,
 | 
			
		||||
                      decoration: Styles.boxLavenderBubble,
 | 
			
		||||
                      child: TextFormField(
 | 
			
		||||
@ -266,12 +249,12 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
                      text: 'ADD',
 | 
			
		||||
                      color: Styles.lavender,
 | 
			
		||||
                      onPressed: () => submitTransaction().then((_) {
 | 
			
		||||
                        Navigator.pop(context);
 | 
			
		||||
                        if (mounted) {
 | 
			
		||||
                          Navigator.pop(context);
 | 
			
		||||
                        }
 | 
			
		||||
                        showSnack(
 | 
			
		||||
                          ref: ref,
 | 
			
		||||
                          text: widget.transaction != null
 | 
			
		||||
                              ? 'Transaction updated!'
 | 
			
		||||
                              : 'Transaction added!',
 | 
			
		||||
                          text: widget.transaction != null ? 'Transaction updated!' : 'Transaction added!',
 | 
			
		||||
                          type: SnackType.success,
 | 
			
		||||
                        );
 | 
			
		||||
                      }),
 | 
			
		||||
@ -289,9 +272,7 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
          data: Transaction.copyWith(widget.transaction!, {
 | 
			
		||||
            'memo': memoController.text.isNotEmpty ? memoController.text : null,
 | 
			
		||||
            'amount': double.parse(amountController.text),
 | 
			
		||||
            'budget_category_id': transactionType == TransactionType.income
 | 
			
		||||
                ? null
 | 
			
		||||
                : selectedBudgetCategory.id,
 | 
			
		||||
            'budget_category_id': transactionType == TransactionType.income ? null : selectedBudgetCategory.id,
 | 
			
		||||
          }).toJson());
 | 
			
		||||
    } else {
 | 
			
		||||
      data = await ref.read(apiProvider.notifier).post(
 | 
			
		||||
@ -299,15 +280,11 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
          data: Transaction(
 | 
			
		||||
                  amount: double.parse(amountController.text),
 | 
			
		||||
                  createdByUserId: user!.id!,
 | 
			
		||||
                  budgetCategoryId: transactionType == TransactionType.income
 | 
			
		||||
                      ? null
 | 
			
		||||
                      : selectedBudgetCategory.id,
 | 
			
		||||
                  budgetCategoryId: transactionType == TransactionType.income ? null : selectedBudgetCategory.id,
 | 
			
		||||
                  budgetId: user!.budgetId,
 | 
			
		||||
                  date: DateTime.now(),
 | 
			
		||||
                  type: transactionType,
 | 
			
		||||
                  memo: memoController.text.isNotEmpty
 | 
			
		||||
                      ? memoController.text
 | 
			
		||||
                      : null)
 | 
			
		||||
                  memo: memoController.text.isNotEmpty ? memoController.text : null)
 | 
			
		||||
              .toJson());
 | 
			
		||||
    }
 | 
			
		||||
    final success = data != null ? data['success'] as bool : false;
 | 
			
		||||
@ -320,9 +297,7 @@ class _AddTransactionDialogState extends ConsumerState<TransactionDialog> {
 | 
			
		||||
    } else {
 | 
			
		||||
      showSnack(
 | 
			
		||||
          ref: ref,
 | 
			
		||||
          text: widget.transaction != null
 | 
			
		||||
              ? 'Failed to edit transaction'
 | 
			
		||||
              : 'Failed to add transaction',
 | 
			
		||||
          text: widget.transaction != null ? 'Failed to edit transaction' : 'Failed to add transaction',
 | 
			
		||||
          type: SnackType.error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import 'dart:math';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:helpers/helpers/print.dart';
 | 
			
		||||
import 'package:rluv/features/budget/widgets/add_budget_category_dialog.dart';
 | 
			
		||||
import 'package:rluv/global/utils.dart';
 | 
			
		||||
import 'package:rluv/models/budget_category_model.dart';
 | 
			
		||||
@ -45,8 +44,7 @@ class _BudgetCategoryBarState extends State<BudgetCategoryBar> {
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    final innerHeight = widget.height - widget.innerPadding * 2;
 | 
			
		||||
    final isBright =
 | 
			
		||||
        getBrightness(widget.budgetCategory.color) == Brightness.light;
 | 
			
		||||
    final isBright = getBrightness(widget.budgetCategory.color) == Brightness.light;
 | 
			
		||||
    final textStyle = TextStyle(
 | 
			
		||||
        fontSize: 14,
 | 
			
		||||
        fontWeight: FontWeight.bold,
 | 
			
		||||
@ -155,7 +153,6 @@ class _BudgetCategoryBarState extends State<BudgetCategoryBar> {
 | 
			
		||||
    if (!name.contains(' ') || name.indexOf(' ') == name.length - 1) {
 | 
			
		||||
      return name;
 | 
			
		||||
    }
 | 
			
		||||
    printLime('here');
 | 
			
		||||
    final words = name.split(' ');
 | 
			
		||||
    int index = 0;
 | 
			
		||||
    String firstLine = words[index];
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,9 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:helpers/helpers.dart';
 | 
			
		||||
import 'package:rluv/global/styles.dart';
 | 
			
		||||
import 'package:rluv/global/utils.dart';
 | 
			
		||||
 | 
			
		||||
class BudgetNetBar extends StatelessWidget {
 | 
			
		||||
  const BudgetNetBar(
 | 
			
		||||
      {super.key,
 | 
			
		||||
      required this.isPositive,
 | 
			
		||||
      required this.net,
 | 
			
		||||
      required this.expected});
 | 
			
		||||
  const BudgetNetBar({super.key, required this.isPositive, required this.net, required this.expected});
 | 
			
		||||
 | 
			
		||||
  final bool isPositive;
 | 
			
		||||
  final double net;
 | 
			
		||||
@ -16,7 +11,7 @@ class BudgetNetBar extends StatelessWidget {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final screenWidth = BuildMedia(context).width;
 | 
			
		||||
    final screenWidth = MediaQuery.of(context).size.width;
 | 
			
		||||
    return Container(
 | 
			
		||||
      width: screenWidth * 0.85,
 | 
			
		||||
      decoration: BoxDecoration(
 | 
			
		||||
@ -25,8 +20,7 @@ class BudgetNetBar extends StatelessWidget {
 | 
			
		||||
      ),
 | 
			
		||||
      child: Padding(
 | 
			
		||||
        padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 12.0),
 | 
			
		||||
        child:
 | 
			
		||||
            Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
 | 
			
		||||
        child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
 | 
			
		||||
          Text(
 | 
			
		||||
            isPositive ? 'Income' : 'Expenses',
 | 
			
		||||
            style: const TextStyle(
 | 
			
		||||
@ -35,9 +29,7 @@ class BudgetNetBar extends StatelessWidget {
 | 
			
		||||
          ),
 | 
			
		||||
          Text(
 | 
			
		||||
            '${net.currency()} / ${expected.currency()}',
 | 
			
		||||
            style: TextStyle(
 | 
			
		||||
                fontSize: 20,
 | 
			
		||||
                color: isPositive ? Styles.incomeGreen : Styles.expensesRed),
 | 
			
		||||
            style: TextStyle(fontSize: 20, color: isPositive ? Styles.incomeGreen : Styles.expensesRed),
 | 
			
		||||
          ),
 | 
			
		||||
        ]),
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:intl/intl.dart';
 | 
			
		||||
import 'package:rluv/features/budget/screens/transactions_listview.dart';
 | 
			
		||||
import 'package:rluv/features/budget/widgets/add_transaction_dialog.dart';
 | 
			
		||||
@ -19,8 +18,7 @@ class TransactionListItem extends ConsumerStatefulWidget {
 | 
			
		||||
  final int index;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  ConsumerState<TransactionListItem> createState() =>
 | 
			
		||||
      _TransactionListItemState();
 | 
			
		||||
  ConsumerState<TransactionListItem> createState() => _TransactionListItemState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _TransactionListItemState extends ConsumerState<TransactionListItem> {
 | 
			
		||||
@ -54,17 +52,13 @@ class _TransactionListItemState extends ConsumerState<TransactionListItem> {
 | 
			
		||||
      child: Padding(
 | 
			
		||||
        padding: const EdgeInsets.only(top: 8.0, left: 8.0, bottom: 8.0),
 | 
			
		||||
        child: ClipRRect(
 | 
			
		||||
          borderRadius: const BorderRadius.only(
 | 
			
		||||
              topLeft: Radius.circular(10.0),
 | 
			
		||||
              bottomLeft: Radius.circular(10.0)),
 | 
			
		||||
          borderRadius: const BorderRadius.only(topLeft: Radius.circular(10.0), bottomLeft: Radius.circular(10.0)),
 | 
			
		||||
          child: AnimatedContainer(
 | 
			
		||||
            curve: Curves.easeOut,
 | 
			
		||||
            duration: const Duration(milliseconds: 200),
 | 
			
		||||
            height: cardHeight,
 | 
			
		||||
            decoration: const BoxDecoration(
 | 
			
		||||
              borderRadius: BorderRadius.only(
 | 
			
		||||
                  topLeft: Radius.circular(10.0),
 | 
			
		||||
                  bottomLeft: Radius.circular(10.0)),
 | 
			
		||||
              borderRadius: BorderRadius.only(topLeft: Radius.circular(10.0), bottomLeft: Radius.circular(10.0)),
 | 
			
		||||
              color: Styles.washedStone,
 | 
			
		||||
            ),
 | 
			
		||||
            child: Row(
 | 
			
		||||
@ -74,19 +68,16 @@ class _TransactionListItemState extends ConsumerState<TransactionListItem> {
 | 
			
		||||
                    duration: const Duration(milliseconds: 200),
 | 
			
		||||
                    height: cardHeight,
 | 
			
		||||
                    width: 6,
 | 
			
		||||
                    color: transaction!.type == TransactionType.income
 | 
			
		||||
                        ? Styles.incomeBlue
 | 
			
		||||
                        : Styles.expensesOrange),
 | 
			
		||||
                    color: transaction!.type == TransactionType.income ? Styles.incomeBlue : Styles.expensesOrange),
 | 
			
		||||
                SizedBox(
 | 
			
		||||
                  width: BuildMedia(context).width * 0.65,
 | 
			
		||||
                  width: MediaQuery.of(context).size.width * 0.65,
 | 
			
		||||
                  child: Padding(
 | 
			
		||||
                    padding: const EdgeInsets.only(left: 8.0),
 | 
			
		||||
                    child: Column(
 | 
			
		||||
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
 | 
			
		||||
                      crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
                      children: [
 | 
			
		||||
                        Text(DateFormat('EEE MMM d, h:mm a')
 | 
			
		||||
                            .format(transaction!.date)),
 | 
			
		||||
                        Text(DateFormat('EEE MMM d, h:mm a').format(transaction!.date)),
 | 
			
		||||
                        Row(
 | 
			
		||||
                          children: [
 | 
			
		||||
                            const SizedBox(
 | 
			
		||||
@ -101,9 +92,7 @@ class _TransactionListItemState extends ConsumerState<TransactionListItem> {
 | 
			
		||||
                              ),
 | 
			
		||||
                            ],
 | 
			
		||||
                            Text(
 | 
			
		||||
                              transaction!.type == TransactionType.income
 | 
			
		||||
                                  ? 'Income'
 | 
			
		||||
                                  : budgetCategory!.name,
 | 
			
		||||
                              transaction!.type == TransactionType.income ? 'Income' : budgetCategory!.name,
 | 
			
		||||
                              style: const TextStyle(fontSize: 20),
 | 
			
		||||
                            ),
 | 
			
		||||
                          ],
 | 
			
		||||
@ -125,9 +114,7 @@ class _TransactionListItemState extends ConsumerState<TransactionListItem> {
 | 
			
		||||
                      transaction!.amount.currency(),
 | 
			
		||||
                      style: TextStyle(
 | 
			
		||||
                          fontSize: 24,
 | 
			
		||||
                          color: transaction!.type == TransactionType.income
 | 
			
		||||
                              ? Styles.incomeGreen
 | 
			
		||||
                              : Styles.expensesRed),
 | 
			
		||||
                          color: transaction!.type == TransactionType.income ? Styles.incomeGreen : Styles.expensesRed),
 | 
			
		||||
                    ),
 | 
			
		||||
                    if (showDetails) ...[
 | 
			
		||||
                      IconButton(
 | 
			
		||||
@ -140,8 +127,7 @@ class _TransactionListItemState extends ConsumerState<TransactionListItem> {
 | 
			
		||||
                            builder: (context) => Dialog(
 | 
			
		||||
                              backgroundColor: Styles.dialogColor,
 | 
			
		||||
                              shape: Styles.dialogShape,
 | 
			
		||||
                              child:
 | 
			
		||||
                                  TransactionDialog(transaction: transaction),
 | 
			
		||||
                              child: TransactionDialog(transaction: transaction),
 | 
			
		||||
                            ),
 | 
			
		||||
                          );
 | 
			
		||||
                        },
 | 
			
		||||
@ -182,21 +168,14 @@ class _TransactionListItemState extends ConsumerState<TransactionListItem> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future deleteTransaction() async {
 | 
			
		||||
    final res = await ref
 | 
			
		||||
        .read(apiProvider.notifier)
 | 
			
		||||
        .delete(path: 'transaction', data: {'id': transaction!.id});
 | 
			
		||||
    final res = await ref.read(apiProvider.notifier).delete(path: 'transaction', data: {'id': transaction!.id});
 | 
			
		||||
 | 
			
		||||
    final success = res != null ? res['success'] as bool : false;
 | 
			
		||||
    if (success) {
 | 
			
		||||
      ref
 | 
			
		||||
          .read(dashboardProvider.notifier)
 | 
			
		||||
          .removeWithId('transactions', transaction!.id!);
 | 
			
		||||
      ref.read(dashboardProvider.notifier).removeWithId('transactions', transaction!.id!);
 | 
			
		||||
      showSnack(ref: ref, text: 'Transaction removed', type: SnackType.success);
 | 
			
		||||
    } else {
 | 
			
		||||
      showSnack(
 | 
			
		||||
          ref: ref,
 | 
			
		||||
          text: 'Could not delete transaction',
 | 
			
		||||
          type: SnackType.error);
 | 
			
		||||
      showSnack(ref: ref, text: 'Could not delete transaction', type: SnackType.error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
import 'package:dio/dio.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:helpers/helpers/print.dart';
 | 
			
		||||
import 'package:rluv/global/utils.dart';
 | 
			
		||||
import 'package:rluv/models/shared_note.dart';
 | 
			
		||||
 | 
			
		||||
@ -22,7 +20,7 @@ class SharedNotesScreen extends ConsumerStatefulWidget {
 | 
			
		||||
class _SharedNotesScreenState extends ConsumerState<SharedNotesScreen> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final screen = BuildMedia(context).size;
 | 
			
		||||
    final screen = MediaQuery.of(context).size;
 | 
			
		||||
    final sharedNotes = ref.watch(sharedNotesProvider);
 | 
			
		||||
    return Column(
 | 
			
		||||
      children: [
 | 
			
		||||
@ -47,14 +45,10 @@ class _SharedNotesScreenState extends ConsumerState<SharedNotesScreen> {
 | 
			
		||||
              ),
 | 
			
		||||
              itemBuilder: (BuildContext context, int index) {
 | 
			
		||||
                final note = sharedNotes[index];
 | 
			
		||||
                final colorBrightness = note.color == null
 | 
			
		||||
                    ? Brightness.light
 | 
			
		||||
                    : getBrightness(note.color!);
 | 
			
		||||
                final colorBrightness = note.color == null ? Brightness.light : getBrightness(note.color!);
 | 
			
		||||
                final textStyle = TextStyle(
 | 
			
		||||
                  fontSize: 16.0,
 | 
			
		||||
                  color: colorBrightness == Brightness.light
 | 
			
		||||
                      ? Colors.black54
 | 
			
		||||
                      : Colors.white70,
 | 
			
		||||
                  color: colorBrightness == Brightness.light ? Colors.black54 : Colors.white70,
 | 
			
		||||
                );
 | 
			
		||||
                return Padding(
 | 
			
		||||
                  padding: const EdgeInsets.all(8.0),
 | 
			
		||||
@ -67,14 +61,10 @@ class _SharedNotesScreenState extends ConsumerState<SharedNotesScreen> {
 | 
			
		||||
                          padding: const EdgeInsets.all(8.0),
 | 
			
		||||
                          child: Column(
 | 
			
		||||
                            children: [
 | 
			
		||||
                              FittedBox(
 | 
			
		||||
                                  child: Text(note.title,
 | 
			
		||||
                                      style: const TextStyle(fontSize: 20))),
 | 
			
		||||
                              FittedBox(child: Text(note.title, style: const TextStyle(fontSize: 20))),
 | 
			
		||||
                              Flexible(
 | 
			
		||||
                                child: Text(
 | 
			
		||||
                                  note.content.length > 80
 | 
			
		||||
                                      ? "${note.content.substring(0, 75)}..."
 | 
			
		||||
                                      : note.content,
 | 
			
		||||
                                  note.content.length > 80 ? "${note.content.substring(0, 75)}..." : note.content,
 | 
			
		||||
                                  style: textStyle,
 | 
			
		||||
                                ),
 | 
			
		||||
                              ),
 | 
			
		||||
@ -93,9 +83,7 @@ class _SharedNotesScreenState extends ConsumerState<SharedNotesScreen> {
 | 
			
		||||
                          context: context,
 | 
			
		||||
                          builder: (BuildContext context) {
 | 
			
		||||
                            return Padding(
 | 
			
		||||
                              padding: EdgeInsets.only(
 | 
			
		||||
                                  bottom:
 | 
			
		||||
                                      MediaQuery.of(context).viewInsets.bottom),
 | 
			
		||||
                              padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
 | 
			
		||||
                              child: NoteBottomSheet(
 | 
			
		||||
                                index: index,
 | 
			
		||||
                              ),
 | 
			
		||||
@ -121,8 +109,7 @@ class _SharedNotesScreenState extends ConsumerState<SharedNotesScreen> {
 | 
			
		||||
                    context: context,
 | 
			
		||||
                    builder: (BuildContext context) {
 | 
			
		||||
                      return Padding(
 | 
			
		||||
                        padding: EdgeInsets.only(
 | 
			
		||||
                            bottom: MediaQuery.of(context).viewInsets.bottom),
 | 
			
		||||
                        padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
 | 
			
		||||
                        child: const NoteBottomSheet(
 | 
			
		||||
                          index: null,
 | 
			
		||||
                        ),
 | 
			
		||||
@ -182,19 +169,14 @@ class _NoteBottomSheetState extends ConsumerState<NoteBottomSheet> {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final screen = BuildMedia(context).size;
 | 
			
		||||
    final screen = MediaQuery.of(context).size;
 | 
			
		||||
    return Container(
 | 
			
		||||
      width: screen.width,
 | 
			
		||||
      decoration: BoxDecoration(
 | 
			
		||||
          color: newNote.color ?? Styles.washedStone,
 | 
			
		||||
          borderRadius: const BorderRadius.only(
 | 
			
		||||
              topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
 | 
			
		||||
          borderRadius: const BorderRadius.only(topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
 | 
			
		||||
          boxShadow: const [
 | 
			
		||||
            BoxShadow(
 | 
			
		||||
                color: Colors.black26,
 | 
			
		||||
                spreadRadius: 5.0,
 | 
			
		||||
                blurRadius: 2.0,
 | 
			
		||||
                offset: Offset(0, -2))
 | 
			
		||||
            BoxShadow(color: Colors.black26, spreadRadius: 5.0, blurRadius: 2.0, offset: Offset(0, -2))
 | 
			
		||||
          ]),
 | 
			
		||||
      child: Padding(
 | 
			
		||||
        padding: const EdgeInsets.all(16.0),
 | 
			
		||||
@ -218,8 +200,7 @@ class _NoteBottomSheetState extends ConsumerState<NoteBottomSheet> {
 | 
			
		||||
              // decoration: Styles.inputLavenderBubble(),
 | 
			
		||||
            ),
 | 
			
		||||
            Padding(
 | 
			
		||||
              padding:
 | 
			
		||||
                  const EdgeInsets.symmetric(vertical: 28.0, horizontal: 36.0),
 | 
			
		||||
              padding: const EdgeInsets.symmetric(vertical: 28.0, horizontal: 36.0),
 | 
			
		||||
              child: UiButton(
 | 
			
		||||
                onPressed: !noteChanged(oldNote, newNote)
 | 
			
		||||
                    ? null
 | 
			
		||||
@ -229,41 +210,26 @@ class _NoteBottomSheetState extends ConsumerState<NoteBottomSheet> {
 | 
			
		||||
                        try {
 | 
			
		||||
                          Response? res;
 | 
			
		||||
                          if (widget.index == null) {
 | 
			
		||||
                            res = await ref
 | 
			
		||||
                                .read(apiProvider)
 | 
			
		||||
                                .post('shared_note', data: newNote.toJson());
 | 
			
		||||
                            res = await ref.read(apiProvider).post('shared_note', data: newNote.toJson());
 | 
			
		||||
                          } else {
 | 
			
		||||
                            res = await ref
 | 
			
		||||
                                .read(apiProvider)
 | 
			
		||||
                                .put('shared_note', data: newNote.toJson());
 | 
			
		||||
                            res = await ref.read(apiProvider).put('shared_note', data: newNote.toJson());
 | 
			
		||||
                          }
 | 
			
		||||
                          if (res.data != null && res.data['success']) {
 | 
			
		||||
                            if (widget.index == null) {
 | 
			
		||||
                              ref
 | 
			
		||||
                                  .read(dashboardProvider.notifier)
 | 
			
		||||
                                  .add({'shared_notes': res.data});
 | 
			
		||||
                              ref.read(dashboardProvider.notifier).add({'shared_notes': res.data});
 | 
			
		||||
                            } else {
 | 
			
		||||
                              ref
 | 
			
		||||
                                  .read(dashboardProvider.notifier)
 | 
			
		||||
                                  .update({'shared_notes': res.data});
 | 
			
		||||
                              ref.read(dashboardProvider.notifier).update({'shared_notes': res.data});
 | 
			
		||||
                            }
 | 
			
		||||
                            showSnack(
 | 
			
		||||
                                ref: ref,
 | 
			
		||||
                                text: 'Added note',
 | 
			
		||||
                                type: SnackType.success);
 | 
			
		||||
                            showSnack(ref: ref, text: 'Added note', type: SnackType.success);
 | 
			
		||||
                          } else {
 | 
			
		||||
                            showSnack(
 | 
			
		||||
                                ref: ref,
 | 
			
		||||
                                text: res.data['message'] ??
 | 
			
		||||
                                    'Unexpected error occurred',
 | 
			
		||||
                                text: res.data['message'] ?? 'Unexpected error occurred',
 | 
			
		||||
                                type: SnackType.error);
 | 
			
		||||
                          }
 | 
			
		||||
                        } catch (err) {
 | 
			
		||||
                          showSnack(
 | 
			
		||||
                              ref: ref,
 | 
			
		||||
                              text: 'Unexpected error occurred',
 | 
			
		||||
                              type: SnackType.error);
 | 
			
		||||
                          printRed(err);
 | 
			
		||||
                          showSnack(ref: ref, text: 'Unexpected error occurred', type: SnackType.error);
 | 
			
		||||
                          print(err);
 | 
			
		||||
                        }
 | 
			
		||||
                        // ignore: use_build_context_synchronously
 | 
			
		||||
                        Navigator.pop(context);
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@ import 'dart:convert';
 | 
			
		||||
import 'package:dio/dio.dart';
 | 
			
		||||
import 'package:flutter/foundation.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/print.dart';
 | 
			
		||||
import 'package:jwt_decoder/jwt_decoder.dart';
 | 
			
		||||
import 'package:rluv/global/store.dart';
 | 
			
		||||
 | 
			
		||||
@ -11,7 +10,7 @@ import '../models/token.dart';
 | 
			
		||||
 | 
			
		||||
final tokenProvider = StateProvider<Token?>((ref) {
 | 
			
		||||
  final jwt = ref.watch(jwtProvider);
 | 
			
		||||
  printLime('Current token: $jwt');
 | 
			
		||||
  print('Current token: $jwt');
 | 
			
		||||
  if (jwt == null) return null;
 | 
			
		||||
  try {
 | 
			
		||||
    return Token.fromJson(JwtDecoder.decode(jwt));
 | 
			
		||||
@ -37,12 +36,12 @@ class _JwtNotifier extends StateNotifier<String?> {
 | 
			
		||||
 | 
			
		||||
  void setToken(String jwt) {
 | 
			
		||||
    state = jwt;
 | 
			
		||||
    printCyan('Loaded jwt into client: $jwt');
 | 
			
		||||
    print('Loaded jwt into client: $jwt');
 | 
			
		||||
    ref.read(prefsProvider)?.setString('jwt', jwt);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void revokeToken() {
 | 
			
		||||
    printCyan('jwt token revoked');
 | 
			
		||||
    print('jwt token revoked');
 | 
			
		||||
    state = null;
 | 
			
		||||
    ref.read(prefsProvider)?.remove('jwt');
 | 
			
		||||
  }
 | 
			
		||||
@ -58,8 +57,7 @@ class _ApiNotifier extends StateNotifier<Dio> {
 | 
			
		||||
    // dio.options.baseUrl = "http://localhost:8081/";
 | 
			
		||||
    dio.options.baseUrl = "https://rluv.fosscat.com/";
 | 
			
		||||
    dio.interceptors.addAll([
 | 
			
		||||
      InterceptorsWrapper(onRequest:
 | 
			
		||||
          (RequestOptions options, RequestInterceptorHandler handler) {
 | 
			
		||||
      InterceptorsWrapper(onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
 | 
			
		||||
        final jwt = ref.read(jwtProvider);
 | 
			
		||||
        if (jwt != null) {
 | 
			
		||||
          options.headers['token'] = jwt;
 | 
			
		||||
@ -69,12 +67,10 @@ class _ApiNotifier extends StateNotifier<Dio> {
 | 
			
		||||
        if (response.statusCode != null) {
 | 
			
		||||
          if (response.statusCode == 200) {
 | 
			
		||||
            try {
 | 
			
		||||
              if ((response.data as Map<String, dynamic>)
 | 
			
		||||
                  .containsKey('success')) {
 | 
			
		||||
              if ((response.data as Map<String, dynamic>).containsKey('success')) {
 | 
			
		||||
                if (!response.data['success']) return handler.next(response);
 | 
			
		||||
              }
 | 
			
		||||
              if ((response.data as Map<String, dynamic>)
 | 
			
		||||
                  .containsKey('token')) {
 | 
			
		||||
              if ((response.data as Map<String, dynamic>).containsKey('token')) {
 | 
			
		||||
                final jwt = response.data['token'];
 | 
			
		||||
                if (jwt != null) {
 | 
			
		||||
                  ref.read(jwtProvider.notifier).setToken(jwt);
 | 
			
		||||
@ -83,7 +79,7 @@ class _ApiNotifier extends StateNotifier<Dio> {
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
              printRed('Error in interceptor for token: $err');
 | 
			
		||||
              print('Error in interceptor for token: $err');
 | 
			
		||||
              return handler.next(response);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
@ -115,8 +111,7 @@ class _ApiNotifier extends StateNotifier<Dio> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<Map<String, dynamic>?> put(
 | 
			
		||||
      {required String path, Object? data}) async {
 | 
			
		||||
  Future<Map<String, dynamic>?> put({required String path, Object? data}) async {
 | 
			
		||||
    try {
 | 
			
		||||
      final res = await dio.put(path, data: data);
 | 
			
		||||
 | 
			
		||||
@ -129,8 +124,7 @@ class _ApiNotifier extends StateNotifier<Dio> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<Map<String, dynamic>?> post(
 | 
			
		||||
      {required String path, Object? data}) async {
 | 
			
		||||
  Future<Map<String, dynamic>?> post({required String path, Object? data}) async {
 | 
			
		||||
    try {
 | 
			
		||||
      final res = await dio.post(path, data: data);
 | 
			
		||||
 | 
			
		||||
@ -143,8 +137,7 @@ class _ApiNotifier extends StateNotifier<Dio> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<Map<String, dynamic>?> delete(
 | 
			
		||||
      {required String path, Object? data}) async {
 | 
			
		||||
  Future<Map<String, dynamic>?> delete({required String path, Object? data}) async {
 | 
			
		||||
    try {
 | 
			
		||||
      final res = await dio.delete(path, data: data);
 | 
			
		||||
 | 
			
		||||
@ -162,8 +155,7 @@ class _LoggingInterceptor extends Interceptor {
 | 
			
		||||
  _LoggingInterceptor();
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Future onRequest(
 | 
			
		||||
      RequestOptions options, RequestInterceptorHandler handler) async {
 | 
			
		||||
  Future onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
 | 
			
		||||
    logPrint('///*** REQUEST ***\\\\\\');
 | 
			
		||||
    printKV('URI', options.uri);
 | 
			
		||||
    printKV('METHOD', options.method);
 | 
			
		||||
@ -177,7 +169,7 @@ class _LoggingInterceptor extends Interceptor {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void onError(DioException err, ErrorInterceptorHandler handler) {
 | 
			
		||||
    printRed('///*** ERROR RESPONSE ***\\\\\\');
 | 
			
		||||
    print('///*** ERROR RESPONSE ***\\\\\\');
 | 
			
		||||
    logPrint('URI: ${err.requestOptions.uri}');
 | 
			
		||||
    if (err.response != null) {
 | 
			
		||||
      logPrint('STATUS CODE: ${err.response?.statusCode?.toString()}');
 | 
			
		||||
@ -192,8 +184,7 @@ class _LoggingInterceptor extends Interceptor {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Future onResponse(
 | 
			
		||||
      Response response, ResponseInterceptorHandler handler) async {
 | 
			
		||||
  Future onResponse(Response response, ResponseInterceptorHandler handler) async {
 | 
			
		||||
    logPrint('///*** RESPONSE ***\\\\\\');
 | 
			
		||||
    printKV('URI', response.requestOptions.uri);
 | 
			
		||||
    printKV('STATUS CODE', response.statusCode ?? '');
 | 
			
		||||
@ -206,7 +197,7 @@ class _LoggingInterceptor extends Interceptor {
 | 
			
		||||
 | 
			
		||||
  void printKV(String key, Object v) {
 | 
			
		||||
    if (kDebugMode) {
 | 
			
		||||
      printOrange('$key: $v');
 | 
			
		||||
      print('$key: $v');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -215,21 +206,21 @@ class _LoggingInterceptor extends Interceptor {
 | 
			
		||||
      final data = (s as Map<String, dynamic>?);
 | 
			
		||||
      if (kDebugMode) {
 | 
			
		||||
        if (data == null) {
 | 
			
		||||
          printAmber({});
 | 
			
		||||
          print({});
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        JsonEncoder encoder = const JsonEncoder.withIndent('  ');
 | 
			
		||||
        String prettyprint = encoder.convert(s);
 | 
			
		||||
        printAmber(prettyprint);
 | 
			
		||||
        print(prettyprint);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (_) {
 | 
			
		||||
      printAmber(s);
 | 
			
		||||
      print(s);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void logPrint(String s) {
 | 
			
		||||
    if (kDebugMode) {
 | 
			
		||||
      printOrange(s);
 | 
			
		||||
      print(s);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,6 @@ 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';
 | 
			
		||||
@ -13,8 +12,7 @@ import '../models/shared_note.dart';
 | 
			
		||||
import '../models/transaction_model.dart';
 | 
			
		||||
import '../models/user.dart';
 | 
			
		||||
 | 
			
		||||
StateProvider<SharedPreferences?> prefsProvider =
 | 
			
		||||
    StateProvider<SharedPreferences?>((ref) => null);
 | 
			
		||||
StateProvider<SharedPreferences?> prefsProvider = StateProvider<SharedPreferences?>((ref) => null);
 | 
			
		||||
 | 
			
		||||
// final StateProvider<Token?> tokenProvider = StateProvider<Token?>((ref) {
 | 
			
		||||
//   // final tokenStr = prefs.getString('jwt');
 | 
			
		||||
@ -42,8 +40,7 @@ final Provider<FamilyModel?> familyProvider = Provider<FamilyModel?>(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
final Provider<List<BudgetCategory>> budgetCategoriesProvider =
 | 
			
		||||
    Provider<List<BudgetCategory>>((ref) {
 | 
			
		||||
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>;
 | 
			
		||||
@ -55,7 +52,7 @@ final Provider<List<BudgetCategory>> budgetCategoriesProvider =
 | 
			
		||||
 | 
			
		||||
  final prefs = ref.read(prefsProvider);
 | 
			
		||||
  final budgetJson = jsonEncode({'budget_categories': categoriesData});
 | 
			
		||||
  printBlue('updated prefs stored categories');
 | 
			
		||||
  print('updated prefs stored categories');
 | 
			
		||||
  prefs?.setString('budget_categories', budgetJson);
 | 
			
		||||
 | 
			
		||||
  return categories;
 | 
			
		||||
@ -71,8 +68,7 @@ final Provider<Budget?> budgetProvider = Provider<Budget?>(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
final Provider<List<Transaction>> transactionsProvider =
 | 
			
		||||
    Provider<List<Transaction>>((ref) {
 | 
			
		||||
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>;
 | 
			
		||||
@ -83,8 +79,7 @@ final Provider<List<Transaction>> transactionsProvider =
 | 
			
		||||
      .toList();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
final Provider<List<SharedNote>> sharedNotesProvider =
 | 
			
		||||
    Provider<List<SharedNote>>(
 | 
			
		||||
final Provider<List<SharedNote>> sharedNotesProvider = Provider<List<SharedNote>>(
 | 
			
		||||
  (ref) {
 | 
			
		||||
    final dash = ref.watch(dashboardProvider);
 | 
			
		||||
    if (dash == null) return [];
 | 
			
		||||
@ -97,8 +92,7 @@ final Provider<List<SharedNote>> sharedNotesProvider =
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
final dashboardProvider =
 | 
			
		||||
    StateNotifierProvider<DashBoardStateNotifier, Map<String, dynamic>?>(
 | 
			
		||||
final dashboardProvider = StateNotifierProvider<DashBoardStateNotifier, Map<String, dynamic>?>(
 | 
			
		||||
  (ref) {
 | 
			
		||||
    return DashBoardStateNotifier(ref);
 | 
			
		||||
  },
 | 
			
		||||
@ -119,10 +113,10 @@ class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
 | 
			
		||||
    );
 | 
			
		||||
    final token = ref.read(tokenProvider);
 | 
			
		||||
    if (token?.familyId == null) {
 | 
			
		||||
      printPink('No token, cannot fetch dashboard');
 | 
			
		||||
      print('No token, cannot fetch dashboard');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    printAmber('Fetching dashboard');
 | 
			
		||||
    print('Fetching dashboard');
 | 
			
		||||
    state = await ref.read(apiProvider.notifier).get("dashboard");
 | 
			
		||||
    WidgetsBinding.instance.addPostFrameCallback(
 | 
			
		||||
      (_) => ref.read(loadingStateProvider.notifier).state = false,
 | 
			
		||||
@ -131,7 +125,7 @@ class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
 | 
			
		||||
 | 
			
		||||
  void update(Map<String, dynamic> data) {
 | 
			
		||||
    if (state == null) {
 | 
			
		||||
      printPink('Cant update data, state is null');
 | 
			
		||||
      print('Cant update data, state is null');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (data.keys.length != 1 || data.values.length != 1) {
 | 
			
		||||
@ -149,16 +143,14 @@ class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
 | 
			
		||||
            )
 | 
			
		||||
            .toList();
 | 
			
		||||
        subStateListObj.removeWhere(
 | 
			
		||||
          (element) =>
 | 
			
		||||
              element['id'] ==
 | 
			
		||||
              (data.values.first as Map<String, dynamic>)['id'],
 | 
			
		||||
          (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);
 | 
			
		||||
        // print(state);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
@ -167,7 +159,7 @@ class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
 | 
			
		||||
 | 
			
		||||
  void add(Map<String, dynamic> data) {
 | 
			
		||||
    if (state == null) {
 | 
			
		||||
      printPink('Cant add data, state is null');
 | 
			
		||||
      print('Cant add data, state is null');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (data.keys.length != 1 || data.values.length != 1) {
 | 
			
		||||
@ -183,7 +175,7 @@ class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
 | 
			
		||||
        subStateList.add(data.values.first);
 | 
			
		||||
        newState![key] = subStateList;
 | 
			
		||||
        state = {...newState};
 | 
			
		||||
        // printBlue(state);
 | 
			
		||||
        // print(state);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
@ -192,7 +184,7 @@ class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
 | 
			
		||||
 | 
			
		||||
  void removeWithId(String stateKey, int id) {
 | 
			
		||||
    if (state == null) {
 | 
			
		||||
      printPink('Cant remove data, state is null');
 | 
			
		||||
      print('Cant remove data, state is null');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    switch (stateKey) {
 | 
			
		||||
@ -201,11 +193,10 @@ class DashBoardStateNotifier extends StateNotifier<Map<String, dynamic>?> {
 | 
			
		||||
      case 'shared_noted':
 | 
			
		||||
        final subStateList = state![stateKey] as List<dynamic>;
 | 
			
		||||
        final newState = state;
 | 
			
		||||
        subStateList
 | 
			
		||||
            .removeWhere((e) => (e as Map<String, dynamic>)['id'] == id);
 | 
			
		||||
        subStateList.removeWhere((e) => (e as Map<String, dynamic>)['id'] == id);
 | 
			
		||||
        newState![stateKey] = subStateList;
 | 
			
		||||
        state = {...newState};
 | 
			
		||||
        // printBlue(state);
 | 
			
		||||
        // print(state);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@ import 'dart:math';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/print.dart';
 | 
			
		||||
import 'package:intl/intl.dart';
 | 
			
		||||
import 'package:rluv/global/styles.dart';
 | 
			
		||||
import 'package:rluv/main.dart';
 | 
			
		||||
@ -20,20 +19,16 @@ bool boolFromJson(int value) => value == 1;
 | 
			
		||||
 | 
			
		||||
int boolToJson(bool hide) => hide ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
String colorToJson(Color color) =>
 | 
			
		||||
    color.toString().split('(0x')[1].split(')')[0];
 | 
			
		||||
String colorToJson(Color color) => color.toString().split('(0x')[1].split(')')[0];
 | 
			
		||||
 | 
			
		||||
Color colorFromJson(String hex) => Color(int.parse(hex, radix: 16));
 | 
			
		||||
 | 
			
		||||
String? optionalColorToJson(Color? optionalColor) => optionalColor == null
 | 
			
		||||
    ? null
 | 
			
		||||
    : optionalColor.toString().split('(0x')[1].split(')')[0];
 | 
			
		||||
String? optionalColorToJson(Color? optionalColor) =>
 | 
			
		||||
    optionalColor == null ? null : optionalColor.toString().split('(0x')[1].split(')')[0];
 | 
			
		||||
 | 
			
		||||
Color? optionalColorFromJson(String? hex) =>
 | 
			
		||||
    hex == null ? null : Color(int.parse(hex, radix: 16));
 | 
			
		||||
Color? optionalColorFromJson(String? hex) => hex == null ? null : Color(int.parse(hex, radix: 16));
 | 
			
		||||
 | 
			
		||||
Brightness getBrightness(Color color) =>
 | 
			
		||||
    ThemeData.estimateBrightnessForColor(color);
 | 
			
		||||
Brightness getBrightness(Color color) => ThemeData.estimateBrightnessForColor(color);
 | 
			
		||||
 | 
			
		||||
List<Color> generateColorList() {
 | 
			
		||||
  List<Color> colors = [];
 | 
			
		||||
@ -60,7 +55,7 @@ extension MonetaryExtension on double {
 | 
			
		||||
      return "\$${pieces.first}.00";
 | 
			
		||||
    } else {
 | 
			
		||||
      if (pieces.length > 2) {
 | 
			
		||||
        printBlue(pieces);
 | 
			
		||||
        print(pieces);
 | 
			
		||||
      }
 | 
			
		||||
      return '\$${pieces[0]}.${pieces[1].padRight(2, "0")}';
 | 
			
		||||
    }
 | 
			
		||||
@ -83,7 +78,7 @@ void showSnack(
 | 
			
		||||
    Duration duration = const Duration(seconds: 2)}) {
 | 
			
		||||
  final messengerKey = ref.read(scaffoldMessengerKeyProvider);
 | 
			
		||||
  if (messengerKey.currentState == null) {
 | 
			
		||||
    printPink('Cannot show snackbar, state == null');
 | 
			
		||||
    print('Cannot show snackbar, state == null');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  final color = type == SnackType.info
 | 
			
		||||
@ -99,8 +94,7 @@ void showSnack(
 | 
			
		||||
    elevation: 8,
 | 
			
		||||
    backgroundColor: Styles.deepPurpleNurple,
 | 
			
		||||
    shape: const RoundedRectangleBorder(
 | 
			
		||||
      borderRadius: BorderRadius.only(
 | 
			
		||||
          topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
 | 
			
		||||
      borderRadius: BorderRadius.only(topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0)),
 | 
			
		||||
    ),
 | 
			
		||||
    content: Padding(
 | 
			
		||||
      padding: const EdgeInsets.all(8.0),
 | 
			
		||||
@ -108,9 +102,7 @@ void showSnack(
 | 
			
		||||
        children: [
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.only(right: 14.0),
 | 
			
		||||
            child: Icon(
 | 
			
		||||
                type == SnackType.success ? Icons.check_circle : Icons.info,
 | 
			
		||||
                color: color),
 | 
			
		||||
            child: Icon(type == SnackType.success ? Icons.check_circle : Icons.info, color: color),
 | 
			
		||||
          ),
 | 
			
		||||
          Text(text, style: textStyle),
 | 
			
		||||
        ],
 | 
			
		||||
@ -120,8 +112,7 @@ void showSnack(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool isEmailValid(String email) {
 | 
			
		||||
  final RegExp regex =
 | 
			
		||||
      RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$");
 | 
			
		||||
  final RegExp regex = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$");
 | 
			
		||||
  return regex.hasMatch(email);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
import 'package:animated_splash_screen/animated_splash_screen.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:helpers/helpers/misc_build/build_media.dart';
 | 
			
		||||
import 'package:rluv/features/account/account_create_screen.dart';
 | 
			
		||||
import 'package:rluv/features/budget/screens/budget_overview.dart';
 | 
			
		||||
import 'package:rluv/features/notes/screens/notes_screen.dart';
 | 
			
		||||
@ -74,8 +73,7 @@ class _HomeState extends ConsumerState<Home> {
 | 
			
		||||
    }
 | 
			
		||||
    WidgetsBinding.instance.addPostFrameCallback(
 | 
			
		||||
      (_) {
 | 
			
		||||
        ref.read(currentHomePageProvider.notifier).state =
 | 
			
		||||
            const BudgetOverviewScreen(initialData: {});
 | 
			
		||||
        ref.read(currentHomePageProvider.notifier).state = const BudgetOverviewScreen(initialData: {});
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
    super.initState();
 | 
			
		||||
@ -92,8 +90,7 @@ class _HomeState extends ConsumerState<Home> {
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    if (ref.watch(currentHomePageProvider).toString() ==
 | 
			
		||||
        "BudgetOverviewScreen") {
 | 
			
		||||
    if (ref.watch(currentHomePageProvider).toString() == "BudgetOverviewScreen") {
 | 
			
		||||
      initData = {};
 | 
			
		||||
    }
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
@ -104,15 +101,13 @@ class _HomeState extends ConsumerState<Home> {
 | 
			
		||||
        child: SafeArea(
 | 
			
		||||
          child: Column(
 | 
			
		||||
            children: [
 | 
			
		||||
              SizedBox(height: BuildMedia(context).height * 0.15),
 | 
			
		||||
              SizedBox(height: MediaQuery.of(context).size.height * 0.15),
 | 
			
		||||
              UiButton(
 | 
			
		||||
                text: 'Budget',
 | 
			
		||||
                color: drawerColors[4],
 | 
			
		||||
                onPressed: () {
 | 
			
		||||
                  if (ref.read(currentHomePageProvider).toString() !=
 | 
			
		||||
                      "BudgetOverviewScreen") {
 | 
			
		||||
                    ref.read(currentHomePageProvider.notifier).state =
 | 
			
		||||
                        BudgetOverviewScreen(initialData: initData);
 | 
			
		||||
                  if (ref.read(currentHomePageProvider).toString() != "BudgetOverviewScreen") {
 | 
			
		||||
                    ref.read(currentHomePageProvider.notifier).state = BudgetOverviewScreen(initialData: initData);
 | 
			
		||||
                  }
 | 
			
		||||
                  toggleDrawer();
 | 
			
		||||
                },
 | 
			
		||||
@ -121,10 +116,8 @@ class _HomeState extends ConsumerState<Home> {
 | 
			
		||||
                text: 'Notes',
 | 
			
		||||
                color: drawerColors[5],
 | 
			
		||||
                onPressed: () {
 | 
			
		||||
                  if (ref.read(currentHomePageProvider).toString() !=
 | 
			
		||||
                      "SharedNotesScreen") {
 | 
			
		||||
                    ref.read(currentHomePageProvider.notifier).state =
 | 
			
		||||
                        SharedNotesScreen(initialData: initData);
 | 
			
		||||
                  if (ref.read(currentHomePageProvider).toString() != "SharedNotesScreen") {
 | 
			
		||||
                    ref.read(currentHomePageProvider.notifier).state = SharedNotesScreen(initialData: initData);
 | 
			
		||||
                  }
 | 
			
		||||
                  toggleDrawer();
 | 
			
		||||
                },
 | 
			
		||||
@ -134,10 +127,8 @@ class _HomeState extends ConsumerState<Home> {
 | 
			
		||||
                text: 'Settings',
 | 
			
		||||
                color: drawerColors[0],
 | 
			
		||||
                onPressed: () {
 | 
			
		||||
                  if (ref.read(currentHomePageProvider).toString() !=
 | 
			
		||||
                      "SettingsScreen") {
 | 
			
		||||
                    ref.read(currentHomePageProvider.notifier).state =
 | 
			
		||||
                        const SettingsScreen();
 | 
			
		||||
                  if (ref.read(currentHomePageProvider).toString() != "SettingsScreen") {
 | 
			
		||||
                    ref.read(currentHomePageProvider.notifier).state = const SettingsScreen();
 | 
			
		||||
                  }
 | 
			
		||||
                  toggleDrawer();
 | 
			
		||||
                },
 | 
			
		||||
@ -190,5 +181,4 @@ final appBarTitleProvider = Provider<String>(
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
final scaffoldMessengerKeyProvider =
 | 
			
		||||
    Provider<GlobalKey<ScaffoldMessengerState>>(
 | 
			
		||||
        (ref) => GlobalKey<ScaffoldMessengerState>());
 | 
			
		||||
    Provider<GlobalKey<ScaffoldMessengerState>>((ref) => GlobalKey<ScaffoldMessengerState>());
 | 
			
		||||
 | 
			
		||||
@ -6,10 +6,6 @@
 | 
			
		||||
 | 
			
		||||
#include "generated_plugin_registrant.h"
 | 
			
		||||
 | 
			
		||||
#include <url_launcher_linux/url_launcher_plugin.h>
 | 
			
		||||
 | 
			
		||||
void fl_register_plugins(FlPluginRegistry* registry) {
 | 
			
		||||
  g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
 | 
			
		||||
      fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
 | 
			
		||||
  url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
list(APPEND FLUTTER_PLUGIN_LIST
 | 
			
		||||
  url_launcher_linux
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										406
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										406
									
								
								pubspec.lock
									
									
									
									
									
								
							@ -5,18 +5,23 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: _fe_analyzer_shared
 | 
			
		||||
      sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
 | 
			
		||||
      sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "64.0.0"
 | 
			
		||||
    version: "72.0.0"
 | 
			
		||||
  _macros:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description: dart
 | 
			
		||||
    source: sdk
 | 
			
		||||
    version: "0.3.2"
 | 
			
		||||
  analyzer:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: analyzer
 | 
			
		||||
      sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
 | 
			
		||||
      sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.2.0"
 | 
			
		||||
    version: "6.7.0"
 | 
			
		||||
  animated_splash_screen:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@ -29,18 +34,18 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: archive
 | 
			
		||||
      sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
 | 
			
		||||
      sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.3.7"
 | 
			
		||||
    version: "3.6.1"
 | 
			
		||||
  args:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: args
 | 
			
		||||
      sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
 | 
			
		||||
      sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.2"
 | 
			
		||||
    version: "2.5.0"
 | 
			
		||||
  async:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -77,34 +82,34 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: build_daemon
 | 
			
		||||
      sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65"
 | 
			
		||||
      sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.0.0"
 | 
			
		||||
    version: "4.0.2"
 | 
			
		||||
  build_resolvers:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: build_resolvers
 | 
			
		||||
      sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20"
 | 
			
		||||
      sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.1"
 | 
			
		||||
    version: "2.4.2"
 | 
			
		||||
  build_runner:
 | 
			
		||||
    dependency: "direct dev"
 | 
			
		||||
    description:
 | 
			
		||||
      name: build_runner
 | 
			
		||||
      sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b"
 | 
			
		||||
      sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.6"
 | 
			
		||||
    version: "2.4.12"
 | 
			
		||||
  build_runner_core:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: build_runner_core
 | 
			
		||||
      sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41"
 | 
			
		||||
      sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "7.2.10"
 | 
			
		||||
    version: "7.3.2"
 | 
			
		||||
  built_collection:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -117,10 +122,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: built_value
 | 
			
		||||
      sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166"
 | 
			
		||||
      sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "8.6.1"
 | 
			
		||||
    version: "8.9.2"
 | 
			
		||||
  characters:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -149,10 +154,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: code_builder
 | 
			
		||||
      sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189"
 | 
			
		||||
      sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.5.0"
 | 
			
		||||
    version: "4.10.0"
 | 
			
		||||
  collection:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -173,42 +178,50 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: crypto
 | 
			
		||||
      sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
 | 
			
		||||
      sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.3"
 | 
			
		||||
    version: "3.0.5"
 | 
			
		||||
  cupertino_icons:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: cupertino_icons
 | 
			
		||||
      sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
 | 
			
		||||
      sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.5"
 | 
			
		||||
    version: "1.0.8"
 | 
			
		||||
  custom_refresh_indicator:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: custom_refresh_indicator
 | 
			
		||||
      sha256: "65a463f09623f6baf75e45e0c9034e9304810be3f5dfb00a54edde7252f4a524"
 | 
			
		||||
      sha256: c34dd1dfb1f6b9ee2db9c5972586dba5e4445d79f8431f6ab098a6e963ccd39c
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.1"
 | 
			
		||||
    version: "4.0.1"
 | 
			
		||||
  dart_style:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: dart_style
 | 
			
		||||
      sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55"
 | 
			
		||||
      sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.2"
 | 
			
		||||
    version: "2.3.7"
 | 
			
		||||
  dio:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: dio
 | 
			
		||||
      sha256: ce75a1b40947fea0a0e16ce73337122a86762e38b982e1ccb909daa3b9bc4197
 | 
			
		||||
      sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "5.3.2"
 | 
			
		||||
    version: "5.7.0"
 | 
			
		||||
  dio_web_adapter:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: dio_web_adapter
 | 
			
		||||
      sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.0"
 | 
			
		||||
  fake_async:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -221,18 +234,18 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: ffi
 | 
			
		||||
      sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
 | 
			
		||||
      sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.0"
 | 
			
		||||
    version: "2.1.3"
 | 
			
		||||
  file:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: file
 | 
			
		||||
      sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
 | 
			
		||||
      sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.1.4"
 | 
			
		||||
    version: "7.0.0"
 | 
			
		||||
  fixnum:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -246,30 +259,22 @@ packages:
 | 
			
		||||
    description: flutter
 | 
			
		||||
    source: sdk
 | 
			
		||||
    version: "0.0.0"
 | 
			
		||||
  flutter_highlight:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: flutter_highlight
 | 
			
		||||
      sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.7.0"
 | 
			
		||||
  flutter_lints:
 | 
			
		||||
    dependency: "direct dev"
 | 
			
		||||
    description:
 | 
			
		||||
      name: flutter_lints
 | 
			
		||||
      sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4"
 | 
			
		||||
      sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.2"
 | 
			
		||||
    version: "4.0.0"
 | 
			
		||||
  flutter_riverpod:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: flutter_riverpod
 | 
			
		||||
      sha256: b6cb0041c6c11cefb2dcb97ef436eba43c6d41287ac6d8ca93e02a497f53a4f3
 | 
			
		||||
      sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.7"
 | 
			
		||||
    version: "2.5.1"
 | 
			
		||||
  flutter_test:
 | 
			
		||||
    dependency: "direct dev"
 | 
			
		||||
    description: flutter
 | 
			
		||||
@ -284,10 +289,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: frontend_server_client
 | 
			
		||||
      sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
 | 
			
		||||
      sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.2.0"
 | 
			
		||||
    version: "4.0.0"
 | 
			
		||||
  glob:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -300,27 +305,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: graphs
 | 
			
		||||
      sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
 | 
			
		||||
      sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.1"
 | 
			
		||||
  helpers:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      path: "."
 | 
			
		||||
      ref: main
 | 
			
		||||
      resolved-ref: e9486562cb1ec5ac31fdd91ff573e99d51b2d57f
 | 
			
		||||
      url: "https://github.com/mitch2na/helpers.git"
 | 
			
		||||
    source: git
 | 
			
		||||
    version: "1.2.0"
 | 
			
		||||
  highlight:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: highlight
 | 
			
		||||
      sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.7.0"
 | 
			
		||||
    version: "2.3.2"
 | 
			
		||||
  http_multi_server:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -341,26 +329,26 @@ packages:
 | 
			
		||||
    dependency: "direct dev"
 | 
			
		||||
    description:
 | 
			
		||||
      name: icons_launcher
 | 
			
		||||
      sha256: af05397792f6d82b93375a8a0253b8db0d3f816ef1dd1bf5c35cbab55321d327
 | 
			
		||||
      sha256: "9b514ffed6ed69b232fd2bf34c44878c8526be71fc74129a658f35c04c9d4a9d"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.3"
 | 
			
		||||
    version: "2.1.7"
 | 
			
		||||
  image:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: image
 | 
			
		||||
      sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf
 | 
			
		||||
      sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.0.17"
 | 
			
		||||
    version: "4.2.0"
 | 
			
		||||
  intl:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: intl
 | 
			
		||||
      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
 | 
			
		||||
      sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.18.1"
 | 
			
		||||
    version: "0.19.0"
 | 
			
		||||
  io:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -373,26 +361,26 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: js
 | 
			
		||||
      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
 | 
			
		||||
      sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.6.7"
 | 
			
		||||
    version: "0.7.1"
 | 
			
		||||
  json_annotation:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: json_annotation
 | 
			
		||||
      sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
 | 
			
		||||
      sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.8.1"
 | 
			
		||||
    version: "4.9.0"
 | 
			
		||||
  json_serializable:
 | 
			
		||||
    dependency: "direct dev"
 | 
			
		||||
    description:
 | 
			
		||||
      name: json_serializable
 | 
			
		||||
      sha256: aa1f5a8912615733e0fdc7a02af03308933c93235bdc8d50d0b0c8a8ccb0b969
 | 
			
		||||
      sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.7.1"
 | 
			
		||||
    version: "6.8.0"
 | 
			
		||||
  jwt_decoder:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@ -405,34 +393,34 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: leak_tracker
 | 
			
		||||
      sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
 | 
			
		||||
      sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "10.0.0"
 | 
			
		||||
    version: "10.0.5"
 | 
			
		||||
  leak_tracker_flutter_testing:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: leak_tracker_flutter_testing
 | 
			
		||||
      sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
 | 
			
		||||
      sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.1"
 | 
			
		||||
    version: "3.0.5"
 | 
			
		||||
  leak_tracker_testing:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: leak_tracker_testing
 | 
			
		||||
      sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
 | 
			
		||||
      sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.1"
 | 
			
		||||
    version: "3.0.1"
 | 
			
		||||
  lints:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: lints
 | 
			
		||||
      sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
 | 
			
		||||
      sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.1"
 | 
			
		||||
    version: "4.0.0"
 | 
			
		||||
  logging:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -441,22 +429,14 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.2.0"
 | 
			
		||||
  markdown:
 | 
			
		||||
  macros:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: markdown
 | 
			
		||||
      sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd
 | 
			
		||||
      name: macros
 | 
			
		||||
      sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "7.1.1"
 | 
			
		||||
  markdown_widget:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: markdown_widget
 | 
			
		||||
      sha256: "088feae6be2dd527c7dd54e06ad104a3e70505aff2ce14a3b464482551a0e273"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.0"
 | 
			
		||||
    version: "0.1.2-main.4"
 | 
			
		||||
  matcher:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -469,26 +449,26 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: material_color_utilities
 | 
			
		||||
      sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
 | 
			
		||||
      sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.8.0"
 | 
			
		||||
    version: "0.11.1"
 | 
			
		||||
  meta:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: meta
 | 
			
		||||
      sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
 | 
			
		||||
      sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.11.0"
 | 
			
		||||
    version: "1.15.0"
 | 
			
		||||
  mime:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: mime
 | 
			
		||||
      sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
 | 
			
		||||
      sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.4"
 | 
			
		||||
    version: "1.0.6"
 | 
			
		||||
  package_config:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -501,10 +481,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: page_transition
 | 
			
		||||
      sha256: a7694bc120b7064a7f57c336914bb8885acf4f70bb3772c30c2fcfe6a85e43ff
 | 
			
		||||
      sha256: dee976b1f23de9bbef5cd512fe567e9f6278caee11f5eaca9a2115c19dc49ef6
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.9"
 | 
			
		||||
    version: "2.1.0"
 | 
			
		||||
  path:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -517,58 +497,50 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: path_provider_linux
 | 
			
		||||
      sha256: ba2b77f0c52a33db09fc8caf85b12df691bf28d983e84cf87ff6d693cfa007b3
 | 
			
		||||
      sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.0"
 | 
			
		||||
    version: "2.2.1"
 | 
			
		||||
  path_provider_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: path_provider_platform_interface
 | 
			
		||||
      sha256: bced5679c7df11190e1ddc35f3222c858f328fff85c3942e46e7f5589bf9eb84
 | 
			
		||||
      sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.0"
 | 
			
		||||
    version: "2.1.2"
 | 
			
		||||
  path_provider_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: path_provider_windows
 | 
			
		||||
      sha256: ee0e0d164516b90ae1f970bdf29f726f1aa730d7cfc449ecc74c495378b705da
 | 
			
		||||
      sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.0"
 | 
			
		||||
    version: "2.3.0"
 | 
			
		||||
  petitparser:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: petitparser
 | 
			
		||||
      sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
 | 
			
		||||
      sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "5.4.0"
 | 
			
		||||
    version: "6.0.2"
 | 
			
		||||
  platform:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: platform
 | 
			
		||||
      sha256: "57c07bf82207aee366dfaa3867b3164e4f03a238a461a11b0e8a3a510d51203d"
 | 
			
		||||
      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.1.1"
 | 
			
		||||
    version: "3.1.5"
 | 
			
		||||
  plugin_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: plugin_platform_interface
 | 
			
		||||
      sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
 | 
			
		||||
      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.5"
 | 
			
		||||
  pointycastle:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: pointycastle
 | 
			
		||||
      sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.7.3"
 | 
			
		||||
    version: "2.1.8"
 | 
			
		||||
  pool:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -589,82 +561,74 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: pubspec_parse
 | 
			
		||||
      sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
 | 
			
		||||
      sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.2.3"
 | 
			
		||||
    version: "1.3.0"
 | 
			
		||||
  riverpod:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: riverpod
 | 
			
		||||
      sha256: b0657b5b30c81a3184bdaab353045f0a403ebd60bb381591a8b7ad77dcade793
 | 
			
		||||
      sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.7"
 | 
			
		||||
  scroll_to_index:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: scroll_to_index
 | 
			
		||||
      sha256: b707546e7500d9f070d63e5acf74fd437ec7eeeb68d3412ef7b0afada0b4f176
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.1"
 | 
			
		||||
    version: "2.5.1"
 | 
			
		||||
  shared_preferences:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences
 | 
			
		||||
      sha256: "0344316c947ffeb3a529eac929e1978fcd37c26be4e8468628bac399365a3ca1"
 | 
			
		||||
      sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.0"
 | 
			
		||||
    version: "2.3.2"
 | 
			
		||||
  shared_preferences_android:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_android
 | 
			
		||||
      sha256: fe8401ec5b6dcd739a0fe9588802069e608c3fdbfd3c3c93e546cf2f90438076
 | 
			
		||||
      sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.0"
 | 
			
		||||
    version: "2.3.2"
 | 
			
		||||
  shared_preferences_foundation:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_foundation
 | 
			
		||||
      sha256: d29753996d8eb8f7619a1f13df6ce65e34bc107bef6330739ed76f18b22310ef
 | 
			
		||||
      sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.3"
 | 
			
		||||
    version: "2.5.2"
 | 
			
		||||
  shared_preferences_linux:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_linux
 | 
			
		||||
      sha256: "71d6806d1449b0a9d4e85e0c7a917771e672a3d5dc61149cc9fac871115018e1"
 | 
			
		||||
      sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.0"
 | 
			
		||||
    version: "2.4.1"
 | 
			
		||||
  shared_preferences_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_platform_interface
 | 
			
		||||
      sha256: "23b052f17a25b90ff2b61aad4cc962154da76fb62848a9ce088efe30d7c50ab1"
 | 
			
		||||
      sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.0"
 | 
			
		||||
    version: "2.4.1"
 | 
			
		||||
  shared_preferences_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_web
 | 
			
		||||
      sha256: "7347b194fb0bbeb4058e6a4e87ee70350b6b2b90f8ac5f8bd5b3a01548f6d33a"
 | 
			
		||||
      sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.0"
 | 
			
		||||
    version: "2.4.2"
 | 
			
		||||
  shared_preferences_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_windows
 | 
			
		||||
      sha256: f95e6a43162bce43c9c3405f3eb6f39e5b5d11f65fab19196cf8225e2777624d
 | 
			
		||||
      sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.0"
 | 
			
		||||
    version: "2.4.1"
 | 
			
		||||
  shelf:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -677,10 +641,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shelf_web_socket
 | 
			
		||||
      sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
 | 
			
		||||
      sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.4"
 | 
			
		||||
    version: "2.0.0"
 | 
			
		||||
  sky_engine:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description: flutter
 | 
			
		||||
@ -690,10 +654,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: source_gen
 | 
			
		||||
      sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16
 | 
			
		||||
      sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.4.0"
 | 
			
		||||
    version: "1.5.0"
 | 
			
		||||
  source_helper:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -762,10 +726,10 @@ packages:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: test_api
 | 
			
		||||
      sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
 | 
			
		||||
      sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.6.1"
 | 
			
		||||
    version: "0.7.2"
 | 
			
		||||
  timing:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -790,78 +754,6 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.2"
 | 
			
		||||
  url_launcher:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher
 | 
			
		||||
      sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.1.12"
 | 
			
		||||
  url_launcher_android:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_android
 | 
			
		||||
      sha256: "3dd2388cc0c42912eee04434531a26a82512b9cb1827e0214430c9bcbddfe025"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.0.38"
 | 
			
		||||
  url_launcher_ios:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_ios
 | 
			
		||||
      sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.1.4"
 | 
			
		||||
  url_launcher_linux:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_linux
 | 
			
		||||
      sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.5"
 | 
			
		||||
  url_launcher_macos:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_macos
 | 
			
		||||
      sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.6"
 | 
			
		||||
  url_launcher_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_platform_interface
 | 
			
		||||
      sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.3"
 | 
			
		||||
  url_launcher_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_web
 | 
			
		||||
      sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.18"
 | 
			
		||||
  url_launcher_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_windows
 | 
			
		||||
      sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.7"
 | 
			
		||||
  uuid:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: uuid
 | 
			
		||||
      sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.7"
 | 
			
		||||
  vector_math:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -870,22 +762,14 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.4"
 | 
			
		||||
  visibility_detector:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: visibility_detector
 | 
			
		||||
      sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.4.0+2"
 | 
			
		||||
  vm_service:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: vm_service
 | 
			
		||||
      sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
 | 
			
		||||
      sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "13.0.0"
 | 
			
		||||
    version: "14.2.5"
 | 
			
		||||
  watcher:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -894,38 +778,46 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.1.0"
 | 
			
		||||
  web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: web
 | 
			
		||||
      sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.0"
 | 
			
		||||
  web_socket:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: web_socket
 | 
			
		||||
      sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.1.6"
 | 
			
		||||
  web_socket_channel:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: web_socket_channel
 | 
			
		||||
      sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
 | 
			
		||||
      sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.0"
 | 
			
		||||
  win32:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: win32
 | 
			
		||||
      sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "5.0.6"
 | 
			
		||||
    version: "3.0.1"
 | 
			
		||||
  xdg_directories:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: xdg_directories
 | 
			
		||||
      sha256: f0c26453a2d47aa4c2570c6a033246a3fc62da2fe23c7ffdd0a7495086dc0247
 | 
			
		||||
      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.2"
 | 
			
		||||
    version: "1.0.4"
 | 
			
		||||
  xml:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: xml
 | 
			
		||||
      sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
 | 
			
		||||
      sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.3.0"
 | 
			
		||||
    version: "6.5.0"
 | 
			
		||||
  yaml:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -935,5 +827,5 @@ packages:
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.1.2"
 | 
			
		||||
sdks:
 | 
			
		||||
  dart: ">=3.3.0 <4.0.0"
 | 
			
		||||
  flutter: ">=3.19.0"
 | 
			
		||||
  dart: ">=3.5.0-259.0.dev <4.0.0"
 | 
			
		||||
  flutter: ">=3.22.0"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								pubspec.yaml
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								pubspec.yaml
									
									
									
									
									
								
							@ -37,16 +37,16 @@ dependencies:
 | 
			
		||||
  cupertino_icons: ^1.0.2
 | 
			
		||||
  dio: ^5.2.1+1
 | 
			
		||||
  flutter_riverpod: ^2.1.3
 | 
			
		||||
  helpers:
 | 
			
		||||
    git:
 | 
			
		||||
      url: https://github.com/mitch2na/helpers.git
 | 
			
		||||
      ref: main
 | 
			
		||||
  uuid: ^3.0.7
 | 
			
		||||
  # helpers:
 | 
			
		||||
  #   git:
 | 
			
		||||
  #     url: https://github.com/mitch2na/helpers.git
 | 
			
		||||
  #     ref: main
 | 
			
		||||
  # uuid: ^3.0.7
 | 
			
		||||
  json_annotation: ^4.8.0
 | 
			
		||||
  shared_preferences: ^2.1.2
 | 
			
		||||
  intl: ^0.18.1
 | 
			
		||||
  markdown_widget: ^2.2.0
 | 
			
		||||
  custom_refresh_indicator: ^2.2.1
 | 
			
		||||
  intl: ^0.19.0
 | 
			
		||||
  # markdown_widget: ^2.2.0
 | 
			
		||||
  custom_refresh_indicator: ^4.0.1
 | 
			
		||||
  jwt_decoder: ^2.0.1
 | 
			
		||||
  animated_splash_screen: ^1.3.0
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ dev_dependencies:
 | 
			
		||||
 | 
			
		||||
  build_runner: ^2.3.3
 | 
			
		||||
  json_serializable: ^6.6.0
 | 
			
		||||
  flutter_lints: ^2.0.0
 | 
			
		||||
  flutter_lints: ^4.0.0
 | 
			
		||||
  icons_launcher: ^2.1.3
 | 
			
		||||
 | 
			
		||||
# For information on the generic Dart part of this file, see the
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user