Compare commits

...

2 Commits

Author SHA1 Message Date
faa52dcaa2 fix: interface fixes 2024-06-24 14:56:06 +03:00
946d2ada41 fix: some fixes in example app 2024-06-24 14:08:02 +03:00
9 changed files with 104 additions and 127 deletions

View File

@@ -166,13 +166,14 @@ class GymHistoryItem {
final String date; final String date;
final String sum; final String sum;
final String photo; final String photo;
final String timestamp;
GymHistoryItem({ GymHistoryItem(
required this.id, {required this.id,
required this.date, required this.date,
required this.sum, required this.sum,
required this.photo, required this.photo,
}); required this.timestamp});
factory GymHistoryItem.fromRawJson(String str) => factory GymHistoryItem.fromRawJson(String str) =>
GymHistoryItem.fromJson(json.decode(str)); GymHistoryItem.fromJson(json.decode(str));
@@ -184,12 +185,14 @@ class GymHistoryItem {
date: json["date"], date: json["date"],
sum: json["sum"], sum: json["sum"],
photo: json["photo"], photo: json["photo"],
timestamp: json["timestamp"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
"date": date, "date": date,
"sum": sum, "sum": sum,
"timestamp": timestamp,
"photo": photo, "photo": photo,
}; };
} }
@@ -201,19 +204,20 @@ class GymHistoryItemDetail {
String? payUrl; String? payUrl;
final String receiver; final String receiver;
final String email; final String email;
final String timestamp;
final String address; final String address;
final List<GymHistoryItemDetailProvider> providers; final List<GymHistoryItemDetailProvider> providers;
GymHistoryItemDetail({ GymHistoryItemDetail(
required this.id, {required this.id,
required this.date, required this.date,
required this.sum, required this.sum,
this.payUrl, this.payUrl,
required this.providers, required this.providers,
required this.receiver, required this.receiver,
required this.email, required this.email,
required this.address, required this.address,
}); required this.timestamp});
factory GymHistoryItemDetail.fromRawJson(String str) => factory GymHistoryItemDetail.fromRawJson(String str) =>
GymHistoryItemDetail.fromJson(json.decode(str)); GymHistoryItemDetail.fromJson(json.decode(str));
@@ -222,16 +226,16 @@ class GymHistoryItemDetail {
factory GymHistoryItemDetail.fromJson(Map<String, dynamic> json) => factory GymHistoryItemDetail.fromJson(Map<String, dynamic> json) =>
GymHistoryItemDetail( GymHistoryItemDetail(
id: json["id"], id: json["id"],
date: json["date"], date: json["date"],
sum: json["sum"], sum: json["sum"],
receiver: json["receiver"], receiver: json["receiver"],
email: json["email"], email: json["email"],
address: json["address"], address: json["address"],
payUrl: json["pay_url"] as String?, payUrl: json["pay_url"] as String?,
providers: List<GymHistoryItemDetailProvider>.from(json["providers"] providers: List<GymHistoryItemDetailProvider>.from(json["providers"]
.map((x) => GymHistoryItemDetailProvider.fromJson(x))), .map((x) => GymHistoryItemDetailProvider.fromJson(x))),
); timestamp: json["timestamp"]);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
@@ -241,6 +245,7 @@ class GymHistoryItemDetail {
"providers": List<dynamic>.from(providers.map((x) => x.toJson())), "providers": List<dynamic>.from(providers.map((x) => x.toJson())),
"receiver": receiver, "receiver": receiver,
"email": email, "email": email,
"timestamp": timestamp,
"address": address, "address": address,
}; };
} }

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gymlink_module_web/main_mobile.dart'; import 'package:gymlink_module_web/main_mobile.dart';
import 'package:gymlink_module_web/providers/main.dart'; import 'package:gymlink_module_web/providers/main.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@@ -32,6 +33,8 @@ class MyExampleApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
return MaterialApp( return MaterialApp(
title: 'GymLink Example App', title: 'GymLink Example App',
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
@@ -53,32 +56,49 @@ Widget getDrawer(BuildContext context) => Drawer(
children: [ children: [
const DrawerHeader(child: Text('Drawer Header')), const DrawerHeader(child: Text('Drawer Header')),
ListTile( ListTile(
leading: const Icon(Icons.home), leading: const Icon(Icons.home),
title: const Text('Home'), title: const Text('Home'),
onTap: () => Navigator.of(context).push( onTap: () {
MaterialPageRoute( Future.microtask(() async {
builder: (context) => const ExampleMainPage(), final prefs = await SharedPreferences.getInstance();
), prefs.remove('token');
), prefs.remove('history');
), prefs.remove('cart');
ListTile( prefs.remove('detail_history');
leading: const Icon(Icons.sell), });
title: const Text('Club 2'), Navigator.of(context).pushReplacement(
onTap: () => Navigator.of(context).push( MaterialPageRoute(
MaterialPageRoute( builder: (context) => const ExampleMainPage(),
builder: (context) => ChangeNotifierProvider(
create: (_) => GymLinkProvider(),
child: Consumer<GymLinkProvider>(
builder: (_, value, __) => const ExampleClub2Page(),
), ),
), );
), }),
), ListTile(
), leading: const Icon(Icons.sell),
title: const Text('Club 2'),
onTap: () {
Future.microtask(() async {
final prefs = await SharedPreferences.getInstance();
prefs.remove('token');
prefs.remove('history');
prefs.remove('cart');
prefs.remove('detail_history');
});
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => ChangeNotifierProvider(
create: (_) => GymLinkProvider(),
child: Consumer<GymLinkProvider>(
builder: (_, value, __) => const ExampleClub2Page(),
),
),
),
);
}),
ListTile( ListTile(
leading: const Icon(Icons.search), leading: const Icon(Icons.search),
title: const Text('Example page'), title: const Text('Example page'),
onTap: () => Navigator.of(context).push(MaterialPageRoute( onTap: () =>
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const ExampleSecondPage(), builder: (context) => const ExampleSecondPage(),
)), )),
), ),
@@ -143,26 +163,25 @@ class _ExamplePageState extends State<ExamplePage> {
), ),
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
drawer: getDrawer(context), drawer: getDrawer(context),
body: const Column( body: Column(
children: [ children: [
Text('test'), IconButton(
Expanded( icon: const Icon(Icons.colorize),
onPressed: () {
context.read<GymLinkProvider>().changeTheme(
Random().nextInt(0xffffff + 1),
blackTheme: Random().nextBool());
},
),
const Expanded(
child: MyApp(), child: MyApp(),
), ),
SizedBox( const SizedBox(
height: 20, height: 20,
), ),
Text('Bottom text') const Text('Bottom text')
], ],
), ),
floatingActionButton: IconButton(
icon: const Icon(Icons.search),
onPressed: () {
context.read<GymLinkProvider>().changeTheme(
Random().nextInt(0xffffff + 1),
blackTheme: Random().nextBool());
},
),
); );
} }
} }
@@ -231,12 +250,6 @@ class _ExampleClub2PageState extends State<ExampleClub2Page> {
Text('Bottom text') Text('Bottom text')
], ],
), ),
floatingActionButton: IconButton(
icon: const Icon(Icons.search),
onPressed: () {
// context.read<GymLinkProvider>().changeTheme(0xFFAABCAB);
},
),
); );
} }
} }

View File

@@ -270,12 +270,12 @@ class _MainPageState extends State<MainPage> {
SliverGridDelegateWithFixedCrossAxisCount( SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: min( crossAxisCount: min(
(MediaQuery.sizeOf(context).width ~/ (MediaQuery.sizeOf(context).width ~/
200) 220)
.toInt(), .toInt(),
8), 8),
childAspectRatio: 0.8, childAspectRatio: 0.8,
mainAxisSpacing: 10.0, mainAxisSpacing: 10.0,
crossAxisSpacing: 40.0), crossAxisSpacing: 20.0),
itemCount: itemViewCount, itemCount: itemViewCount,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final product = filteredData[index]; final product = filteredData[index];

View File

@@ -118,6 +118,7 @@ class _OrderConfirmationPageState extends State<OrderConfirmationPage> {
sum: totalPrice.toString(), sum: totalPrice.toString(),
date: '', date: '',
providers: providers, providers: providers,
timestamp: DateTime.now().millisecondsSinceEpoch.toString(),
); );
await addToHistory(order); await addToHistory(order);
} }

View File

@@ -151,7 +151,8 @@ class _HistoryPageState extends State<HistoryPage> {
final item = my_orders[index]; final item = my_orders[index];
return HistoryItemCard( return HistoryItemCard(
id: item.id, id: item.id,
cost: item.sum, cost: double.parse(item.sum)
.toStringAsFixed(2),
date: item.date, date: item.date,
image: FutureBuilder( image: FutureBuilder(
future: precacheImage( future: precacheImage(

View File

@@ -206,7 +206,8 @@ class _OrderInfoPageState extends State<OrderInfoPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
MarkdownBody( MarkdownBody(
data: '## Итого: ${detail!.sum} руб.'), data:
'## Итого: ${double.parse(detail!.sum).toStringAsFixed(2)} руб.'),
MarkdownBody( MarkdownBody(
data: data:
"### Адрес получателя: __${detail!.address}__"), "### Адрес получателя: __${detail!.address}__"),

View File

@@ -11,8 +11,7 @@ Future<List<GymHistoryItem>> getHistory() async {
for (var historyItem in jsonDecode(historyString) as List<dynamic>) { for (var historyItem in jsonDecode(historyString) as List<dynamic>) {
history.add(GymHistoryItem.fromJson(historyItem)); history.add(GymHistoryItem.fromJson(historyItem));
} }
history.sort((a, b) => b.id.compareTo(a.id)); history.sort((a, b) => b.timestamp.compareTo(a.timestamp));
history = history.reversed.toList();
return history; return history;
} }
@@ -50,7 +49,8 @@ Future<void> addToHistory(GymHistoryItemDetail item) async {
"receiver": item.receiver, "receiver": item.receiver,
"email": item.email, "email": item.email,
"address": item.address, "address": item.address,
"providers": providers "providers": providers,
"timestamp": DateTime.now().millisecondsSinceEpoch.toString(),
}; };
final detailHistoryItem = GymHistoryItemDetail.fromJson(json); final detailHistoryItem = GymHistoryItemDetail.fromJson(json);
detailHistory.add(detailHistoryItem); detailHistory.add(detailHistoryItem);
@@ -59,6 +59,7 @@ Future<void> addToHistory(GymHistoryItemDetail item) async {
id: detailHistoryItem.id, id: detailHistoryItem.id,
photo: detailHistoryItem.providers[0].items[0].photo, photo: detailHistoryItem.providers[0].items[0].photo,
sum: detailHistoryItem.sum, sum: detailHistoryItem.sum,
timestamp: detailHistoryItem.timestamp,
)); ));
prefs.setString('history', jsonEncode(history)); prefs.setString('history', jsonEncode(history));
prefs.setString('detail_history', jsonEncode(detailHistory)); prefs.setString('detail_history', jsonEncode(detailHistory));

View File

@@ -31,10 +31,16 @@
} }
const btn = document.getElementById('token'); const btn = document.getElementById('token');
btn.addEventListener('click', () => getToken('eeb42dcb-8e5b-4f21-825a-3fc7ada43445')); btn.addEventListener('click', () => {
localStorage.clear();
getToken('eeb42dcb-8e5b-4f21-825a-3fc7ada43445');
});
const btn2 = document.getElementById('token2'); const btn2 = document.getElementById('token2');
btn2.addEventListener('click', () => getToken('a8622a61-3142-487e-8db8-b6aebd4f04aa')); btn2.addEventListener('click', () => {
localStorage.clear();
getToken('a8622a61-3142-487e-8db8-b6aebd4f04aa');
});
let colorChangeBtnRed = document.getElementById('colorChangeBtnRed'); let colorChangeBtnRed = document.getElementById('colorChangeBtnRed');
colorChangeBtnRed.addEventListener('click', function () { colorChangeBtnRed.addEventListener('click', function () {

View File

@@ -1,51 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Прием платежа с помощью виджета ЮKassa</title>
<!--Подключение библиотеки для инициализации виджета ЮKassa-->
<script src="https://yookassa.ru/checkout-widget/v1/checkout-widget.js"></script>
</head>
<body>
Ниже отобразится платежная форма. Если вы еще не создавали платеж и не передавали токен для инициализации виджета, появится сообщение об ошибке.
<!--Контейнер, в котором будет отображаться платежная форма-->
<div id="payment-form"></div>
Данные банковской карты для оплаты в <b>тестовом магазине</b>:
- номер — <b>5555 5555 5555 4477</b>
- срок действия — <b>01/30</b> (или другая дата, больше текущей)
- CVC — <b>123</b> (или три любые цифры)
- код для прохождения 3-D Secure — <b>123</b> (или три любые цифры)
<a href=https://yookassa.ru/developers/payment-acceptance/testing-and-going-live/testing#test-bank-card>Другие тестовые банковские карты</a>
<script>
//Инициализация виджета. Все параметры обязательные.
const checkout = new window.YooMoneyCheckoutWidget({
confirmation_token: 'ct-287e0c37-000f-5000-8000-16961d35b0fd', //Токен, который перед проведением оплаты нужно получить от ЮKassa
return_url: 'https://example.com/', //Ссылка на страницу завершения оплаты, это может быть любая ваша страница
//При необходимости можно изменить цвета виджета, подробные настройки см. в документации
//customization: {
//Настройка цветовой схемы, минимум один параметр, значения цветов в HEX
//colors: {
//Цвет акцентных элементов: кнопка Заплатить, выбранные переключатели, опции и текстовые поля
//control_primary: '#00BF96', //Значение цвета в HEX
//Цвет платежной формы и ее элементов
//background: '#F2F3F5' //Значение цвета в HEX
//}
//},
error_callback: function(error) {
console.log(error)
}
});
//Отображение платежной формы в контейнере
checkout.render('payment-form');
</script>
</body>
</html>