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,19 @@
import 'package:flutter/material.dart';
class RecipientActions extends StatelessWidget {
final VoidCallback onEdit;
final VoidCallback onDelete;
const RecipientActions({super.key, required this.onEdit, required this.onDelete});
@override
Widget build(BuildContext context) {
return Row(
children: [
IconButton(icon: Icon(Icons.edit, color: Theme.of(context).colorScheme.primary), onPressed: onEdit),
IconButton(icon: Icon(Icons.delete, color: Theme.of(context).colorScheme.error), onPressed: onDelete),
],
);
}
}

View File

@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
class RecipientInfoColumn extends StatelessWidget {
final String name;
final String email;
const RecipientInfoColumn({super.key, required this.name, required this.email});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(name, style: Theme.of(context).textTheme.titleMedium!.copyWith(fontSize: 19)),
Text(email, style: Theme.of(context).textTheme.bodyMedium),
],
);
}
}

View File

@@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pweb/pages/payment_methods/icon.dart';
import 'package:pweb/utils/payment/label.dart';
class RecipientAddressBookInfoRow extends StatelessWidget {
final PaymentType type;
final String value;
final double spacingWidth;
final double spacingHeight;
final double iconSize;
final double titleFontSize;
final double valueFontSize;
final TextStyle? textStyle;
const RecipientAddressBookInfoRow({
super.key,
required this.type,
required this.value,
this.spacingWidth = 8.0,
this.spacingHeight = 2.0,
this.iconSize = 20.0,
this.titleFontSize = 16.0,
this.valueFontSize = 12.0,
this.textStyle,
});
@override
Widget build(BuildContext context) {
final style = textStyle ?? Theme.of(context).textTheme.bodySmall!;
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(iconForPaymentType(type), size: iconSize),
SizedBox(width: spacingWidth),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
getPaymentTypeLabel(context, type),
style: style.copyWith(fontSize: titleFontSize),
),
SizedBox(height: spacingHeight),
Text(
value,
style: style.copyWith(fontSize: valueFontSize),
),
],
),
],
);
}
}

View File

@@ -0,0 +1,97 @@
import 'package:flutter/material.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pweb/pages/address_book/page/recipient/actions.dart';
import 'package:pweb/pages/address_book/page/recipient/info_column.dart';
import 'package:pweb/pages/address_book/page/recipient/payment_row.dart';
import 'package:pweb/pages/address_book/page/recipient/status.dart';
import 'package:pweb/pages/dashboard/payouts/single/adress_book/avatar.dart';
class RecipientAddressBookItem extends StatefulWidget {
final Recipient recipient;
final VoidCallback onTap;
final VoidCallback onEdit;
final VoidCallback onDelete;
final double borderRadius;
final double elevation;
final EdgeInsetsGeometry padding;
final double spacingDotAvatar;
final double spacingAvatarInfo;
final double spacingBottom;
final double avatarRadius;
const RecipientAddressBookItem({
super.key,
required this.recipient,
required this.onTap,
required this.onEdit,
required this.onDelete,
this.borderRadius = 12,
this.elevation = 4,
this.padding = const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
this.spacingDotAvatar = 8,
this.spacingAvatarInfo = 16,
this.spacingBottom = 10,
this.avatarRadius = 24,
});
@override
State<RecipientAddressBookItem> createState() => _RecipientAddressBookItemState();
}
class _RecipientAddressBookItemState extends State<RecipientAddressBookItem> {
bool _isHovered = false;
@override
Widget build(BuildContext context) {
final recipient = widget.recipient;
return MouseRegion(
onEnter: (_) => setState(() => _isHovered = true),
onExit: (_) => setState(() => _isHovered = false),
child: InkWell(
onTap: widget.onTap,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(widget.borderRadius)),
elevation: widget.elevation,
color: Theme.of(context).colorScheme.onSecondary,
child: Padding(
padding: widget.padding,
child: Column(
children: [
Row(
children: [
RecipientStatusDot(status: recipient.status),
SizedBox(width: widget.spacingDotAvatar),
RecipientAvatar(
name: recipient.name,
avatarUrl: recipient.avatarUrl,
isVisible: false,
avatarRadius: widget.avatarRadius,
),
SizedBox(width: widget.spacingAvatarInfo),
Expanded(
child: RecipientInfoColumn(
name: recipient.name,
email: recipient.email,
),
),
if (_isHovered)
RecipientActions(
onEdit: widget.onEdit, onDelete: widget.onDelete),
],
),
SizedBox(height: widget.spacingBottom),
RecipientPaymentRow(recipient: recipient),
],
),
),
),
),
);
}
}

View File

@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pweb/pages/address_book/page/recipient/info_row.dart';
class RecipientPaymentRow extends StatelessWidget {
final Recipient recipient;
final double spacing;
const RecipientPaymentRow({
super.key,
required this.recipient,
this.spacing = 18
});
@override
Widget build(BuildContext context) {
return Row(
spacing: spacing,
children: [
if (recipient.bank?.accountNumber.isNotEmpty ?? false)
RecipientAddressBookInfoRow(
type: PaymentType.bankAccount,
value: recipient.bank!.accountNumber
),
if (recipient.card?.pan.isNotEmpty ?? false)
RecipientAddressBookInfoRow(
type: PaymentType.card,
value: recipient.card!.pan
),
if (recipient.iban?.iban.isNotEmpty ?? false)
RecipientAddressBookInfoRow(
type: PaymentType.iban,
value: recipient.iban!.iban
),
if (recipient.wallet?.walletId.isNotEmpty ?? false)
RecipientAddressBookInfoRow(
type: PaymentType.wallet,
value: recipient.wallet!.walletId
),
],
);
}
}

View File

@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:pshared/models/recipient/status.dart';
class RecipientStatusDot extends StatelessWidget {
final RecipientStatus status;
const RecipientStatusDot({super.key, required this.status});
@override
Widget build(BuildContext context) {
Color color;
switch (status) {
case RecipientStatus.ready:
color = Colors.green;
break;
case RecipientStatus.notRegistered:
color = Theme.of(context).colorScheme.error;
break;
case RecipientStatus.registered:
color = Colors.yellow;
break;
}
return Container(
width: 12,
height: 12,
decoration: BoxDecoration(shape: BoxShape.circle, color: color),
);
}
}