import 'dart:async'; import 'dart:js_interop' as js; import 'dart:js_interop_unsafe' as js_util; import 'package:flutter/material.dart'; import 'package:gymlink_module_web/components/app_bar.dart'; import 'package:gymlink_module_web/components/card.dart'; import 'package:gymlink_module_web/pages/basket.dart'; import 'package:gymlink_module_web/pages/detail.dart'; import 'package:gymlink_module_web/pages/order_history.dart'; import 'package:gymlink_module_web/theme.dart'; import 'package:url_launcher/url_launcher.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); // This widget is the root of your application. @override State createState() => _MyAppState(); } const List> testData = [ { "name": "Протеин", "image": "product.png", "price": "120", "details": "Test details", "id": "34fa3126-bfaf-5dec-8f4a-b246c097ef73" }, { "name": "Протеин", "image": "product.png", "price": "150", "details": "Test details", "id": "34a26e82-7656-5e98-a44a-c2d01d0b1ad1123" }, { "name": "Протеин", "image": "product.png", "price": "250", "details": "Test details", "id": "4fb204b7-3f9e-52a2-bed1-415c00a31a37123" }, { "name": "Протеин", "image": "product.png", "price": "300", "details": "Test details", "id": "09b2f5bb-683e-5c39-ae89-b8e152fa8bcf123" }, { "name": "Протеин", "image": "product.png", "price": "100", "details": "Test details", "id": "cd1b6817-db94-5394-be1d-af88af79749f123" } ]; @js.JSExport() class _MyAppState extends State { final _streamController = StreamController.broadcast(); bool _isLoading = true; @override void initState() { super.initState(); final export = js.createJSInteropWrapper(this); js.globalContext['_appState'] = export; js.globalContext.callMethod('_stateSet'.toJS); } @override void dispose() { _streamController.close(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'GymLink Module', theme: myTheme, debugShowCheckedModeBanner: false, home: MainPage(isLoading: _isLoading), ); } @js.JSExport() void onTokenReceived(String token) { if (token == 'token123') { setState(() { _isLoading = false; }); } } } class MainPage extends StatefulWidget { final bool isLoading; const MainPage({ super.key, required this.isLoading, }); @override State createState() => _MainPageState(); } class _MainPageState extends State { Future _goToPage() async { final Uri url = Uri.parse('https://google.com'); if (!await launchUrl(url, webOnlyWindowName: '_blank')) { throw 'Could not launch $url'; } } @override Widget build(BuildContext context) { return Scaffold( appBar: widget.isLoading ? null : const GymLinkAppBar(), body: widget.isLoading ? const Center(child: CircularProgressIndicator()) : Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Expanded( child: TextField( decoration: InputDecoration( hintText: 'Search', border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), suffixIcon: Padding( padding: const EdgeInsets.only(right: 8), child: ElevatedButton( onPressed: _goToPage, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric( vertical: 8, horizontal: 0), minimumSize: const Size(50, kMinInteractiveDimension), backgroundColor: Theme.of(context).primaryColor, shape: const CircleBorder(), ), child: const Icon( Icons.search, color: Colors.white, size: 24, ), ), ), ), ), ), const SizedBox(width: 8), ElevatedButton( onPressed: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => const BasketPage(), )); }, style: ElevatedButton.styleFrom( padding: const EdgeInsets.all(0), minimumSize: const Size(40, kMinInteractiveDimension), backgroundColor: Theme.of(context).primaryColor, shape: const CircleBorder( side: BorderSide( color: Colors.black, width: 1, ), ), ), child: const Icon( Icons.shopping_basket, color: Colors.white, size: 24, ), ), const SizedBox(width: 8), ElevatedButton( onPressed: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => const HistoryPage(), )); }, style: ElevatedButton.styleFrom( padding: const EdgeInsets.all(0), minimumSize: const Size(40, kMinInteractiveDimension), backgroundColor: Theme.of(context).primaryColor, shape: const CircleBorder( side: BorderSide( color: Colors.black, width: 1, ), ), ), child: const Icon( Icons.history, color: Colors.white, size: 24, ), ), ], ), ), Expanded( child: GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: (MediaQuery.sizeOf(context).width ~/ 250).floor(), ), itemCount: testData.length, itemBuilder: (context, index) { final product = testData[index]; return ProductCard( imagePath: Image.asset( product['image']!, width: 100, ), name: product['name']!, price: product['price']!, onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (context) => DetailPage( name: product['name']!, description: product['details']!, price: product['price']!, id: product['id']!, image: Image.asset(product['image']!, width: 300), ), ), ), ); }, ), ), ], ), ); } }