Frontend first draft

This commit is contained in:
Arseni
2025-11-13 15:06:15 +03:00
parent e47f343afb
commit ddb54ddfdc
504 changed files with 25498 additions and 1 deletions

View File

@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:pweb/services/balance.dart';
class BalanceProvider with ChangeNotifier {
final BalanceService _service;
BalanceProvider(this._service);
double? _balance;
String? _walletName;
String? _walletId;
bool _isHidden = true;
double? get balance => _balance;
String? get walletName => _walletName;
String? get walletId => _walletId;
bool get isHidden => _isHidden;
Future<void> loadData() async {
_balance = await _service.getBalance();
_walletName = await _service.getWalletName();
_walletId = await _service.getWalletId();
notifyListeners();
}
void toggleVisibility() {
_isHidden = !_isHidden;
notifyListeners();
}
}

View File

@@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
class CarouselIndexProvider extends ChangeNotifier {
int _currentIndex = 0;
int get currentIndex => _currentIndex;
void updateIndex(int index) {
if (_currentIndex != index) {
_currentIndex = index;
notifyListeners();
}
}
}

View File

@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
class MockPaymentProvider with ChangeNotifier {
double _amount = 10.0;
bool _payerCoversFee = true;
double get amount => _amount;
bool get payerCoversFee => _payerCoversFee;
double get fee => _amount * 0.05;
double get total => payerCoversFee ? (_amount + fee) : _amount;
double get recipientGets => payerCoversFee ? _amount : (_amount - fee);
void setAmount(double value) {
_amount = value;
notifyListeners();
}
void setPayerCoversFee(bool value) {
_payerCoversFee = value;
notifyListeners();
}
}

View File

@@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pweb/models/wallet.dart';
import 'package:pweb/providers/wallets.dart';
import 'package:pweb/widgets/sidebar/destinations.dart';
import 'package:pweb/services/amplitude.dart';
import 'package:pweb/providers/recipient.dart';
class PageSelectorProvider extends ChangeNotifier {
PayoutDestination _selected = PayoutDestination.dashboard;
PaymentType? _type;
bool _cameFromRecipientList = false;
final RecipientProvider? recipientProvider;
final WalletsProvider? walletsProvider;
PayoutDestination get selected => _selected;
PaymentType? get type => _type;
PageSelectorProvider({this.recipientProvider, this.walletsProvider});
void selectPage(PayoutDestination dest) {
_selected = dest;
notifyListeners();
}
void selectRecipient(Recipient? recipient, {bool fromList = false}) {
if (recipientProvider != null) {
recipientProvider!.selectRecipient(recipient);
_cameFromRecipientList = fromList;
_selected = PayoutDestination.payment;
notifyListeners();
} else {
debugPrint("RecipientProvider is null — cannot select recipient");
}
}
void editRecipient(Recipient? recipient, {bool fromList = false}) {
if (recipientProvider != null) {
recipientProvider!.selectRecipient(recipient);
_cameFromRecipientList = fromList;
_selected = PayoutDestination.addrecipient;
notifyListeners();
} else {
debugPrint("RecipientProvider is null — cannot select recipient");
}
}
void goToAddRecipient() {
if (recipientProvider != null) {
AmplitudeService.recipientAddStarted();
recipientProvider!.selectRecipient(null);
_selected = PayoutDestination.addrecipient;
_cameFromRecipientList = false;
notifyListeners();
} else {
debugPrint("RecipientProvider is null — cannot go to add recipient");
}
}
void startPaymentWithoutRecipient(PaymentType type) {
if (recipientProvider != null) {
recipientProvider!.selectRecipient(null);
}
_type = type;
_cameFromRecipientList = false;
_selected = PayoutDestination.payment;
notifyListeners();
}
void goBackFromPayment() {
_selected = _cameFromRecipientList
? PayoutDestination.recipients
: PayoutDestination.dashboard;
_type = null;
notifyListeners();
}
void goBackFromWalletEdit() {
selectPage(PayoutDestination.methods);
}
void selectWallet(Wallet wallet) {
if (walletsProvider != null) {
walletsProvider!.selectWallet(wallet);
_selected = PayoutDestination.editwallet;
notifyListeners();
} else {
debugPrint("RecipientProvider is null — cannot select wallet");
}
}
Recipient? get selectedRecipient => recipientProvider?.selectedRecipient;
Wallet? get selectedWallet => walletsProvider?.selectedWallet;
}

View File

@@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import 'package:pshared/models/payment/methods/type.dart';
import 'package:pweb/services/payments/payment_methods.dart';
class PaymentMethodsProvider extends ChangeNotifier {
final PaymentMethodsService service;
List<PaymentMethod> _methods = [];
PaymentMethod? _selectedMethod;
bool _isLoading = false;
String? _error;
PaymentMethodsProvider({required this.service});
List<PaymentMethod> get methods => _methods;
PaymentMethod? get selectedMethod => _selectedMethod;
bool get isLoading => _isLoading;
String? get error => _error;
Future<void> loadMethods() async {
_isLoading = true;
_error = null;
notifyListeners();
try {
_methods = await service.fetchMethods();
_selectedMethod = _methods.firstWhere((m) => m.isMain, orElse: () => _methods.first);
} catch (e) {
_error = e.toString();
}
_isLoading = false;
notifyListeners();
}
void selectMethod(PaymentMethod method) {
_selectedMethod = method;
notifyListeners();
}
void deleteMethod(PaymentMethod method) {
_methods.remove(method);
notifyListeners();
}
void reorderMethods(int oldIndex, int newIndex) {
if (newIndex > oldIndex) newIndex--;
final item = _methods.removeAt(oldIndex);
_methods.insert(newIndex, item);
notifyListeners();
}
void toggleEnabled(PaymentMethod method, bool value) {
method.isEnabled = value;
notifyListeners();
}
void makeMain(PaymentMethod method) {
for (final m in _methods) m.isMain = false;
method.isMain = true;
selectMethod(method);
}
}

View File

@@ -0,0 +1,80 @@
import 'package:flutter/foundation.dart';
import 'package:pshared/models/recipient/filter.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pshared/models/recipient/status.dart';
import 'package:pweb/services/recipient/recipient.dart';
class RecipientProvider extends ChangeNotifier {
final RecipientService _service;
RecipientProvider(this._service);
List<Recipient> _recipients = [];
bool _isLoading = false;
String? _error;
RecipientFilter _selectedFilter = RecipientFilter.all;
String _query = '';
Recipient? _selectedRecipient;
List<Recipient> get recipients => _recipients;
bool get isLoading => _isLoading;
String? get error => _error;
RecipientFilter get selectedFilter => _selectedFilter;
String get query => _query;
Recipient? get selectedRecipient => _selectedRecipient;
List<Recipient> get filteredRecipients {
List<Recipient> filtered = _recipients.where((r) {
switch (_selectedFilter) {
case RecipientFilter.ready:
return r.status == RecipientStatus.ready;
case RecipientFilter.registered:
return r.status == RecipientStatus.registered;
case RecipientFilter.notRegistered:
return r.status == RecipientStatus.notRegistered;
case RecipientFilter.all:
return true;
}
}).toList();
if (_query.isNotEmpty) {
filtered = filtered.where((r) => r.matchesQuery(_query)).toList();
}
return filtered;
}
Future<void> loadRecipients() async {
_isLoading = true;
_error = null;
notifyListeners();
try {
_recipients = await _service.fetchRecipients();
} catch (e) {
_error = e.toString();
} finally {
_isLoading = false;
notifyListeners();
}
}
void setFilter(RecipientFilter filter) {
_selectedFilter = filter;
notifyListeners();
}
void setQuery(String query) {
_query = query.trim().toLowerCase();
notifyListeners();
}
void selectRecipient(Recipient? recipient) {
_selectedRecipient = recipient;
notifyListeners();
}
}

View File

@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
class FutureProviderTemplate<T> extends ChangeNotifier {
FutureProviderTemplate({required this.loader});
final Future<T> Function() loader;
T? _data;
bool _isLoading = false;
String? _error;
T? get data => _data;
bool get isLoading => _isLoading;
String? get error => _error;
Future<void> load() async {
_isLoading = true;
_error = null;
notifyListeners();
try {
_data = await loader();
} catch (e) {
_error = e.toString();
}
_isLoading = false;
notifyListeners();
}
}

View File

@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:pweb/services/auth.dart';
class TwoFactorProvider extends ChangeNotifier {
final AuthenticationService _authService;
TwoFactorProvider(this._authService);
bool _isSubmitting = false;
bool _hasError = false;
bool _verificationSuccess = false;
bool get isSubmitting => _isSubmitting;
bool get hasError => _hasError;
bool get verificationSuccess => _verificationSuccess;
Future<void> submitCode(String code) async {
_isSubmitting = true;
_hasError = false;
_verificationSuccess = false;
notifyListeners();
try {
final success = await _authService.verifyTwoFactorCode(code);
if (success) {
_verificationSuccess = true;
}
} catch (e) {
_hasError = true;
} finally {
_isSubmitting = false;
notifyListeners();
}
}
}

View File

@@ -0,0 +1,10 @@
import 'package:pshared/models/payment/upload_history_item.dart';
import 'package:pweb/providers/template.dart';
import 'package:pweb/services/payments/upload_history.dart';
class UploadHistoryProvider extends FutureProviderTemplate<List<UploadHistoryItem>> {
UploadHistoryProvider({required UploadHistoryService service})
: super(loader: service.fetchHistory);
}

View File

@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:pweb/models/wallet.dart';
import 'package:pweb/services/wallets.dart';
class WalletsProvider with ChangeNotifier {
final WalletsService _service;
WalletsProvider(this._service);
List<Wallet>? _wallets;
bool _isLoading = false;
String? _error;
Wallet? _selectedWallet;
bool _isHidden = true;
List<Wallet>? get wallets => _wallets;
bool get isLoading => _isLoading;
String? get error => _error;
Wallet? get selectedWallet => _selectedWallet;
bool get isHidden => _isHidden;
void selectWallet(Wallet wallet) {
_selectedWallet = wallet;
notifyListeners();
}
Future<void> loadData() async {
_isLoading = true;
_error = null;
notifyListeners();
try {
_wallets = await _service.getWallets();
} catch (e) {
_error = e.toString();
} finally {
_isLoading = false;
notifyListeners();
}
}
Future<Wallet?> getWalletById(String walletId) async {
_isLoading = true;
_error = null;
notifyListeners();
try {
final wallet = await _service.getWallet(walletId);
return wallet;
} catch (e) {
_error = e.toString();
return null;
} finally {
_isLoading = false;
notifyListeners();
}
}
void updateName(String walletRef, String newName) {
final index = _wallets?.indexWhere((w) => w.id == walletRef);
if (index != null && index >= 0) {
_wallets![index] = _wallets![index].copyWith(name: newName);
notifyListeners();
}
}
void updateBalance(String walletRef, double newBalance) {
final index = _wallets?.indexWhere((w) => w.id == walletRef);
if (index != null && index >= 0) {
_wallets![index] = _wallets![index].copyWith(balance: newBalance);
notifyListeners();
}
}
Future<void> updateWallet(Wallet wallet) async {
try {
await _service.updateWallet();
final index = _wallets?.indexWhere((w) => w.id == wallet.id);
if (index != null && index >= 0) {
_wallets![index] = wallet;
notifyListeners();
}
} catch (e) {
_error = e.toString();
notifyListeners();
}
}
Future<void> addWallet(Wallet wallet) async {
try {
final newWallet = await _service.createWallet(); // Pass the wallet parameter
_wallets = [...?_wallets, ]; // Add the new wallet
notifyListeners();
} catch (e) {
_error = e.toString();
notifyListeners();
}
}
Future<void> deleteWallet(String walletId) async {
try {
await _service.deleteWallet(); // Pass the walletId parameter
_wallets?.removeWhere((w) => w.id == walletId);
notifyListeners();
} catch (e) {
_error = e.toString();
notifyListeners();
}
}
void toggleVisibility(String walletId) {
final index = _wallets?.indexWhere((w) => w.id == walletId);
if (index != null && index >= 0) {
final wallet = _wallets![index];
_wallets![index] = wallet.copyWith(isHidden: !wallet.isHidden);
notifyListeners();
}
}
}