feat: update UI theme and improve subscription data fetching and display logic

This commit is contained in:
Suherdy Yacob 2026-06-14 11:52:37 +07:00
parent afa528abd6
commit 6ff44041f0
4 changed files with 99 additions and 44 deletions

View File

@ -40,28 +40,10 @@ class _LoyaltyDashboardState extends State<LoyaltyDashboard> {
final rawSubs = results[1] as List<dynamic>; final rawSubs = results[1] as List<dynamic>;
final cms = results[2] as Map<String, dynamic>; final cms = results[2] as Map<String, dynamic>;
final List<dynamic> cards = [];
final List<dynamic> subs = [...rawSubs];
for (var card in rawCards) {
final progName = (card['program_id']?[1] as String? ?? '').toLowerCase();
final isSub = progName.contains('subscription') ||
card['subscription_start_date'] != null ||
card['subscription_end_date'] != null;
if (isSub) {
final code = card['code'];
if (!subs.any((s) => s['code'] == code)) {
subs.add(card);
}
} else {
cards.add(card);
}
}
if (mounted) { if (mounted) {
setState(() { setState(() {
_loyaltyCards = cards; _loyaltyCards = rawCards;
_subscriptions = subs; _subscriptions = rawSubs;
_carouselSlides = (cms['carousel'] as List<dynamic>?) ?? []; _carouselSlides = (cms['carousel'] as List<dynamic>?) ?? [];
_promos = (cms['promos'] as List<dynamic>?) ?? []; _promos = (cms['promos'] as List<dynamic>?) ?? [];
_isLoading = false; _isLoading = false;

View File

@ -185,10 +185,23 @@ class _MainShellState extends State<MainShell> {
const SizedBox(width: 4), const SizedBox(width: 4),
], ],
), ),
body: IndexedStack( body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
colorScheme.surfaceContainerLowest,
colorScheme.surface,
const Color(0xFFF3EAD3), // Warm traditional restaurant sand/cream
],
),
),
child: IndexedStack(
index: _currentIndex, index: _currentIndex,
children: _pages, children: _pages,
), ),
),
bottomNavigationBar: NavigationBar( bottomNavigationBar: NavigationBar(
selectedIndex: _currentIndex, selectedIndex: _currentIndex,
onDestinationSelected: (index) { onDestinationSelected: (index) {

View File

@ -48,9 +48,18 @@ class OdooService {
[ [
['partner_id', '=', partnerId], ['partner_id', '=', partnerId],
['program_id.program_type', '=', 'loyalty'], ['program_id.program_type', '=', 'loyalty'],
['program_id.active', '=', true],
], ],
], ],
'kwargs': {'fields': ['points', 'program_id', 'code']} 'kwargs': {
'fields': [
'points',
'program_id',
'code',
'subscription_start_date',
'subscription_end_date',
]
}
}) as List<dynamic>; }) as List<dynamic>;
} }
@ -65,10 +74,12 @@ class OdooService {
[ [
['partner_id', '=', partnerId], ['partner_id', '=', partnerId],
['program_id.program_type', '=', 'subscription'], ['program_id.program_type', '=', 'subscription'],
['program_id.active', '=', true],
], ],
], ],
'kwargs': { 'kwargs': {
'fields': [ 'fields': [
'points',
'program_id', 'program_id',
'code', 'code',
'subscription_start_date', 'subscription_start_date',

View File

@ -187,11 +187,12 @@ class _SubscriptionCard extends StatelessWidget {
), ),
], ],
), ),
if (sub['points'] != null)
Column( Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Text( Text(
'Validity Period', 'Claim Balance',
style: theme.textTheme.bodySmall?.copyWith( style: theme.textTheme.bodySmall?.copyWith(
color: colorScheme.onSurfaceVariant, color: colorScheme.onSurfaceVariant,
fontSize: 10, fontSize: 10,
@ -199,7 +200,54 @@ class _SubscriptionCard extends StatelessWidget {
), ),
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
'$startDate - $endDate', '${(sub['points'] as num).toDouble() % 1 == 0 ? (sub['points'] as num).toInt() : sub['points']} Claims',
style: theme.textTheme.bodyMedium?.copyWith(
color: colorScheme.primary,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
if (sub['subscription_start_date'] != null && sub['subscription_start_date'] != false) ...[
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Valid From',
style: theme.textTheme.bodySmall?.copyWith(
color: colorScheme.onSurfaceVariant,
fontSize: 10,
),
),
const SizedBox(height: 2),
Text(
startDate,
style: theme.textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurface,
fontWeight: FontWeight.w600,
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'Expires On',
style: theme.textTheme.bodySmall?.copyWith(
color: colorScheme.onSurfaceVariant,
fontSize: 10,
),
),
const SizedBox(height: 2),
Text(
endDate,
style: theme.textTheme.bodyMedium?.copyWith( style: theme.textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurface, color: colorScheme.onSurface,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -210,6 +258,7 @@ class _SubscriptionCard extends StatelessWidget {
], ],
), ),
], ],
],
), ),
), ),
), ),