Frontend first draft
This commit is contained in:
70
frontend/pweb/lib/pages/dashboard/payouts/multiple/csv.dart
Normal file
70
frontend/pweb/lib/pages/dashboard/payouts/multiple/csv.dart
Normal file
@@ -0,0 +1,70 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
|
||||
class UploadCSVSection extends StatelessWidget {
|
||||
const UploadCSVSection({super.key});
|
||||
|
||||
static const double _verticalSpacing = 10;
|
||||
static const double _iconTextSpacing = 5;
|
||||
static const double _buttonVerticalPadding = 12;
|
||||
static const double _buttonHorizontalPadding = 24;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.upload),
|
||||
const SizedBox(width: _iconTextSpacing),
|
||||
Text(
|
||||
l10n.uploadCSV,
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: _verticalSpacing),
|
||||
Container(
|
||||
height: 140,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: theme.colorScheme.outline),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.upload_file, size: 36, color: theme.colorScheme.primary),
|
||||
const SizedBox(height: 8),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: _buttonHorizontalPadding,
|
||||
vertical: _buttonVerticalPadding,
|
||||
),
|
||||
),
|
||||
child: Text(l10n.upload),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
l10n.hintUpload,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
13
frontend/pweb/lib/pages/dashboard/payouts/multiple/form.dart
Normal file
13
frontend/pweb/lib/pages/dashboard/payouts/multiple/form.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
class MultiplePayoutRow {
|
||||
final String token;
|
||||
final String amount;
|
||||
final String currency;
|
||||
final String comment;
|
||||
|
||||
const MultiplePayoutRow({
|
||||
required this.token,
|
||||
required this.amount,
|
||||
required this.currency,
|
||||
required this.comment,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
import 'package:pweb/providers/upload_history.dart';
|
||||
|
||||
|
||||
class UploadHistorySection extends StatelessWidget {
|
||||
const UploadHistorySection({super.key});
|
||||
|
||||
static const double _smallBox = 5;
|
||||
static const double _radius = 6;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final provider = context.watch<UploadHistoryProvider>();
|
||||
final theme = Theme.of(context);
|
||||
final l10 = AppLocalizations.of(context)!;
|
||||
|
||||
|
||||
if (provider.isLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
if (provider.error != null) {
|
||||
return Text("Error: ${provider.error}");
|
||||
}
|
||||
final items = provider.data ?? [];
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.history),
|
||||
const SizedBox(width: _smallBox),
|
||||
Text(l10.uploadHistory, style: theme.textTheme.bodyLarge),
|
||||
],
|
||||
),
|
||||
DataTable(
|
||||
columns: [
|
||||
DataColumn(label: Text(l10.fileNameColumn)),
|
||||
DataColumn(label: Text(l10.colStatus)),
|
||||
DataColumn(label: Text(l10.dateColumn)),
|
||||
DataColumn(label: Text(l10.details)),
|
||||
],
|
||||
rows: items.map((file) {
|
||||
final isError = file.status == "Error";
|
||||
final statusColor = isError ? Colors.red : Colors.green;
|
||||
return DataRow(
|
||||
cells: [
|
||||
DataCell(Text(file.name)),
|
||||
DataCell(Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: statusColor.withAlpha(20),
|
||||
borderRadius: BorderRadius.circular(_radius),
|
||||
),
|
||||
child: Text(file.status, style: TextStyle(color: statusColor)),
|
||||
)),
|
||||
DataCell(Text(file.time)),
|
||||
DataCell(TextButton(onPressed: () {}, child: Text(l10.showDetails))),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
import 'package:pweb/pages/dashboard/payouts/multiple/form.dart';
|
||||
|
||||
|
||||
class FileFormatSampleSection extends StatelessWidget {
|
||||
const FileFormatSampleSection({super.key});
|
||||
|
||||
static final List<MultiplePayoutRow> sampleRows = [
|
||||
MultiplePayoutRow(token: "d921...161", amount: "500", currency: "RUB", comment: "cashback001"),
|
||||
MultiplePayoutRow(token: "d921...162", amount: "100", currency: "USD", comment: "cashback002"),
|
||||
MultiplePayoutRow(token: "d921...163", amount: "120", currency: "EUR", comment: "cashback003"),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
|
||||
final titleStyle = theme.textTheme.bodyLarge?.copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
|
||||
final linkStyle = theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
);
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.filter_list),
|
||||
const SizedBox(width: 5),
|
||||
Text(l10n.exampleTitle, style: titleStyle),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildDataTable(l10n),
|
||||
const SizedBox(height: 10),
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||
child: Text(l10n.downloadSampleCSV, style: linkStyle),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDataTable(AppLocalizations l10n) {
|
||||
return DataTable(
|
||||
columnSpacing: 20,
|
||||
columns: [
|
||||
DataColumn(label: Text(l10n.tokenColumn)),
|
||||
DataColumn(label: Text(l10n.amount)),
|
||||
DataColumn(label: Text(l10n.currency)),
|
||||
DataColumn(label: Text(l10n.comment)),
|
||||
],
|
||||
rows: sampleRows.map((row) {
|
||||
return DataRow(cells: [
|
||||
DataCell(Text(row.token)),
|
||||
DataCell(Text(row.amount)),
|
||||
DataCell(Text(row.currency)),
|
||||
DataCell(Text(row.comment)),
|
||||
]);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
|
||||
class TitleMultiplePayout extends StatelessWidget {
|
||||
const TitleMultiplePayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context)!.multiplePayout,
|
||||
style: theme.textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.howItWorks,
|
||||
style: theme.textTheme.bodyLarge!.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pweb/pages/dashboard/payouts/multiple/csv.dart';
|
||||
import 'package:pweb/pages/dashboard/payouts/multiple/history.dart';
|
||||
import 'package:pweb/pages/dashboard/payouts/multiple/sample.dart';
|
||||
|
||||
|
||||
class MultiplePayoutForm extends StatelessWidget {
|
||||
const MultiplePayoutForm({super.key});
|
||||
|
||||
static const double _spacing = 12;
|
||||
static const double _bottomSpacing = 40;
|
||||
|
||||
static final List<Widget> _cards = const [
|
||||
FileFormatSampleSection(),
|
||||
UploadCSVSection(),
|
||||
UploadHistorySection(),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
for (int i = 0; i < _cards.length; i++) ...[
|
||||
_StyledCard(child: _cards[i]),
|
||||
if (i < _cards.length - 1) const SizedBox(height: _spacing),
|
||||
],
|
||||
const SizedBox(height: _bottomSpacing),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StyledCard extends StatelessWidget {
|
||||
final Widget child;
|
||||
const _StyledCard({required this.child});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: Card(
|
||||
margin: const EdgeInsets.all(1),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
elevation: 4,
|
||||
color: theme.colorScheme.onSecondary,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user