Initialer Commit: Projekt Start
This commit is contained in:
241
lib/screens/checkout_screen.dart
Normal file
241
lib/screens/checkout_screen.dart
Normal file
@@ -0,0 +1,241 @@
|
||||
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...'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user