diff --git a/lib/screens/loyalty_dashboard.dart b/lib/screens/loyalty_dashboard.dart index 5998327..10bcda9 100644 --- a/lib/screens/loyalty_dashboard.dart +++ b/lib/screens/loyalty_dashboard.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:barcode_widget/barcode_widget.dart'; import '../services/odoo_service.dart'; import '../widgets/carousel_widget.dart'; import '../widgets/promo_card_widget.dart'; @@ -253,33 +254,65 @@ class _LoyaltyCardTile extends StatelessWidget { ), const SizedBox(height: 36), - // Middle Section: Card Label - Text( - 'MEMBER ID', - style: theme.textTheme.labelSmall?.copyWith( - color: onPrimary.withValues(alpha: 0.6), - fontWeight: FontWeight.bold, - letterSpacing: 1.5, - ), - ), - const SizedBox(height: 8), - - // Card Number (Membership Code) - Text( - '${card['code'] ?? 'N/A'}', - style: theme.textTheme.titleMedium?.copyWith( - color: onPrimary, - fontFamily: 'monospace', - fontSize: 16, - fontWeight: FontWeight.bold, - shadows: [ - Shadow( - color: Colors.black.withValues(alpha: 0.25), - offset: const Offset(1, 1), - blurRadius: 2, + // Middle Section: Card Label + Barcode beside it + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'MEMBER ID', + style: theme.textTheme.labelSmall?.copyWith( + color: onPrimary.withValues(alpha: 0.6), + fontWeight: FontWeight.bold, + letterSpacing: 1.5, + ), + ), + const SizedBox(height: 8), + Text( + '${card['code'] ?? 'N/A'}', + style: theme.textTheme.titleMedium?.copyWith( + color: onPrimary, + fontFamily: 'monospace', + fontSize: 16, + fontWeight: FontWeight.bold, + shadows: [ + Shadow( + color: Colors.black.withValues(alpha: 0.25), + offset: const Offset(1, 1), + blurRadius: 2, + ), + ], + ), + ), + ], + ), + if (card['code'] != null && (card['code'] as String).isNotEmpty) + Container( + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.9), + borderRadius: BorderRadius.circular(6), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.1), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + child: BarcodeWidget( + barcode: Barcode.code128(), + data: card['code'] as String, + width: 130, + height: 36, + color: colorScheme.primary, + drawText: false, + ), ), - ], - ), + ], ), const SizedBox(height: 24), diff --git a/lib/widgets/subscription_list_widget.dart b/lib/widgets/subscription_list_widget.dart index e25eac5..5ce7300 100644 --- a/lib/widgets/subscription_list_widget.dart +++ b/lib/widgets/subscription_list_widget.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:barcode_widget/barcode_widget.dart'; import '../utils/safe_cast.dart'; /// "My Subscriptions" list displayed on the home tab below the loyalty card. @@ -208,6 +209,31 @@ class _SubscriptionCard extends StatelessWidget { color: colorScheme.onSurface, ), ), + if (code.isNotEmpty) ...[ + const SizedBox(height: 6), + Container( + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3), + decoration: BoxDecoration( + color: active + ? colorScheme.tertiary.withValues(alpha: 0.06) + : colorScheme.primary.withValues(alpha: 0.06), + borderRadius: BorderRadius.circular(4), + border: Border.all( + color: active + ? colorScheme.tertiary.withValues(alpha: 0.15) + : colorScheme.primary.withValues(alpha: 0.15), + ), + ), + child: BarcodeWidget( + barcode: Barcode.code128(), + data: code, + width: 110, + height: 28, + color: active ? colorScheme.tertiary : colorScheme.primary, + drawText: false, + ), + ), + ], ], ), if (sub['points'] != null) diff --git a/pubspec.lock b/pubspec.lock index 1bfe11f..74f0d31 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -33,6 +33,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" + barcode: + dependency: transitive + description: + name: barcode + sha256: "7b6729c37e3b7f34233e2318d866e8c48ddb46c1f7ad01ff7bb2a8de1da2b9f4" + url: "https://pub.dev" + source: hosted + version: "2.2.9" + barcode_widget: + dependency: "direct main" + description: + name: barcode_widget + sha256: "6f2c5b08659b1a5f4d88d183e6007133ea2f96e50e7b8bb628f03266c3931427" + url: "https://pub.dev" + source: hosted + version: "2.0.4" boolean_selector: dependency: transitive description: @@ -584,6 +600,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index cff5579..a98afff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,7 @@ dependencies: geolocator: ^13.0.2 smooth_page_indicator: ^1.2.0 flutter_html: ^3.0.0-beta.2 + barcode_widget: ^2.0.4 dev_dependencies: flutter_test: