242 lines
7.6 KiB
Dart
242 lines
7.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:webview_flutter/webview_flutter.dart';
|
|
import 'package:provider/provider.dart';
|
|
import '../providers/cart_provider.dart';
|
|
import '../services/woocommerce_service.dart';
|
|
|
|
class CheckoutScreen extends StatefulWidget {
|
|
const CheckoutScreen({super.key});
|
|
|
|
@override
|
|
State<CheckoutScreen> createState() => _CheckoutScreenState();
|
|
}
|
|
|
|
class _CheckoutScreenState extends State<CheckoutScreen> {
|
|
late final WebViewController _controller;
|
|
bool _isLoading = true;
|
|
String? _error;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_initializeWebView();
|
|
}
|
|
|
|
void _initializeWebView() {
|
|
final cart = Provider.of<CartProvider>(context, listen: false);
|
|
|
|
// Erstelle WooCommerce Checkout URL mit Warenkorb-Daten
|
|
final checkoutUrl = _buildCheckoutUrl(cart);
|
|
|
|
_controller = WebViewController()
|
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
|
..addJavaScriptChannel(
|
|
'FlutterChannel',
|
|
onMessageReceived: (JavaScriptMessage message) {
|
|
// Handle messages from JavaScript if needed
|
|
if (message.message == 'order_success') {
|
|
_handleOrderSuccess();
|
|
}
|
|
},
|
|
)
|
|
..setNavigationDelegate(
|
|
NavigationDelegate(
|
|
onPageStarted: (String url) {
|
|
setState(() {
|
|
_isLoading = true;
|
|
_error = null;
|
|
});
|
|
},
|
|
onPageFinished: (String url) async {
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
|
|
// Prüfe ob Bestellung erfolgreich war
|
|
if (url.contains('order-received') || url.contains('order-received/')) {
|
|
_handleOrderSuccess();
|
|
}
|
|
|
|
// Füge Produkte zum WooCommerce-Warenkorb hinzu, wenn wir auf der Cart/Checkout-Seite sind
|
|
if (url.contains('/cart/') || url.contains('/checkout/')) {
|
|
await _addProductsToCart(cart);
|
|
}
|
|
},
|
|
onWebResourceError: (WebResourceError error) {
|
|
setState(() {
|
|
_error = 'Fehler beim Laden der Seite: ${error.description}';
|
|
_isLoading = false;
|
|
});
|
|
},
|
|
),
|
|
)
|
|
..loadRequest(Uri.parse(checkoutUrl));
|
|
}
|
|
|
|
/// Fügt Produkte mit JavaScript zum WooCommerce-Warenkorb hinzu
|
|
Future<void> _addProductsToCart(CartProvider cart) async {
|
|
if (cart.items.isEmpty) return;
|
|
|
|
// Erstelle JavaScript-Code, um Produkte zum Warenkorb hinzuzufügen
|
|
final jsCode = StringBuffer();
|
|
jsCode.writeln('(function() {');
|
|
|
|
// Für jedes Produkt im Warenkorb
|
|
for (var item in cart.items) {
|
|
jsCode.writeln('''
|
|
fetch('${WooCommerceService.baseUrl}/?wc-ajax=add_to_cart', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
body: 'product_id=${item.product.id}&quantity=${item.quantity}'
|
|
}).then(response => response.json()).then(data => {
|
|
if (data.error) {
|
|
console.error('Fehler beim Hinzufügen:', data.error);
|
|
}
|
|
});
|
|
''');
|
|
}
|
|
|
|
jsCode.writeln('})();');
|
|
|
|
try {
|
|
await _controller.runJavaScript(jsCode.toString());
|
|
|
|
// Warte kurz und leite dann zum Checkout weiter
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
await _controller.runJavaScript('window.location.href = "${WooCommerceService.baseUrl}/checkout/";');
|
|
} catch (e) {
|
|
// Falls JavaScript-Fehler auftreten, verwende die einfache URL-Methode
|
|
print('JavaScript-Fehler: $e');
|
|
}
|
|
}
|
|
|
|
String _buildCheckoutUrl(CartProvider cart) {
|
|
final baseUrl = WooCommerceService.baseUrl;
|
|
|
|
if (cart.items.isEmpty) {
|
|
return '$baseUrl/checkout/';
|
|
}
|
|
|
|
// Starte mit der Cart-Seite, damit wir die Produkte hinzufügen können
|
|
// Die JavaScript-Funktion _addProductsToCart wird dann die Produkte hinzufügen
|
|
return '$baseUrl/cart/';
|
|
}
|
|
|
|
void _handleOrderSuccess() {
|
|
// Warenkorb leeren nach erfolgreicher Bestellung
|
|
final cart = Provider.of<CartProvider>(context, listen: false);
|
|
cart.clearCart();
|
|
|
|
// Zeige Erfolgsmeldung
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Bestellung erfolgreich!'),
|
|
content: const Text(
|
|
'Vielen Dank für deine Bestellung. Du erhältst eine Bestätigungs-E-Mail.',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop(); // Dialog schließen
|
|
Navigator.of(context).pop(); // Checkout schließen
|
|
Navigator.of(context).pop(); // Warenkorb schließen (falls von dort gekommen)
|
|
},
|
|
child: const Text('OK'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Zur Kasse'),
|
|
leading: IconButton(
|
|
icon: const Icon(Icons.close),
|
|
onPressed: () {
|
|
// Frage ob wirklich abbrechen
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Checkout abbrechen?'),
|
|
content: const Text('Möchtest du wirklich abbrechen? Dein Warenkorb bleibt erhalten.'),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Weiter einkaufen'),
|
|
),
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop(); // Dialog
|
|
Navigator.of(context).pop(); // Checkout
|
|
},
|
|
child: const Text('Abbrechen'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
body: Stack(
|
|
children: [
|
|
if (_error != null)
|
|
Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
const Icon(Icons.error_outline, size: 64, color: Colors.red),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
'Fehler',
|
|
style: Theme.of(context).textTheme.titleLarge,
|
|
),
|
|
const SizedBox(height: 8),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
|
child: Text(
|
|
_error!,
|
|
style: Theme.of(context).textTheme.bodyMedium,
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
_initializeWebView();
|
|
},
|
|
child: const Text('Erneut versuchen'),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
else
|
|
WebViewWidget(controller: _controller),
|
|
|
|
if (_isLoading && _error == null)
|
|
Container(
|
|
color: Colors.white,
|
|
child: const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
CircularProgressIndicator(),
|
|
SizedBox(height: 16),
|
|
Text('Checkout wird geladen...'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|