fix: use shared motorcycle photo in evolution detail

This commit is contained in:
bponders12-cell 2026-09-01 21:47:24 -04:00
parent 58ba2636f0
commit 07771dbb96
1 changed files with 46 additions and 192 deletions

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../database/database.dart'; import '../../../database/database.dart';
import '../../../models/motorcycle_models.dart'; import '../../../models/motorcycle_models.dart';
import '../../../services/garage/motorcycle_image_service.dart'; import 'motorcycle_photo.dart';
class EvolutionMotorcycleDetailView extends ConsumerWidget { class EvolutionMotorcycleDetailView extends ConsumerWidget {
final GarageMotorcycle bike; final GarageMotorcycle bike;
@ -22,26 +22,21 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final title = '${bike.year} ${bike.makeName} ${bike.modelName}'.toUpperCase(); final title = '${bike.year} ${bike.makeName} ${bike.modelName}'.toUpperCase();
// Resolve Specs with sensible fallbacks for high-performance motorcycles
final powerHp = spec?.horsepower != null && spec!.horsepower! > 0 final powerHp = spec?.horsepower != null && spec!.horsepower! > 0
? spec!.horsepower!.toStringAsFixed(0) ? spec!.horsepower!.toStringAsFixed(0)
: '124'; : '124';
final torqueVal = spec?.torqueLbFt; final torqueVal = spec?.torqueLbFt;
final torqueLbFt = torqueVal != null && torqueVal > 0 final torqueLbFt = torqueVal != null && torqueVal > 0
? torqueVal.toStringAsFixed(1) ? torqueVal.toStringAsFixed(1)
: '76.6'; : '76.6';
final wetWeight = spec?.wetWeightLbs != null && spec!.wetWeightLbs! > 0 final wetWeight = spec?.wetWeightLbs != null && spec!.wetWeightLbs! > 0
? spec!.wetWeightLbs!.toStringAsFixed(0) ? spec!.wetWeightLbs!.toStringAsFixed(0)
: (spec?.dryWeightLbs != null && spec!.dryWeightLbs! > 0 : (spec?.dryWeightLbs != null && spec!.dryWeightLbs! > 0
? (spec!.dryWeightLbs! + 25).toStringAsFixed(0) ? (spec!.dryWeightLbs! + 25).toStringAsFixed(0)
: '432'); : '432');
final displacement = spec?.displacementCc != null && spec!.displacementCc! > 0 final displacement = spec?.displacementCc != null && spec!.displacementCc! > 0
? '${spec!.displacementCc!.toStringAsFixed(0)} cc' ? '${spec!.displacementCc!.toStringAsFixed(0)} cc'
: '599 cc'; : '599 cc';
final engineType = spec?.engineConfiguration ?? 'Inline-4'; final engineType = spec?.engineConfiguration ?? 'Inline-4';
final cylinders = spec?.cylinderCount != null ? '${spec!.cylinderCount}' : '4'; final cylinders = spec?.cylinderCount != null ? '${spec!.cylinderCount}' : '4';
final redline = spec?.redlineRpm != null && spec!.redlineRpm! > 0 final redline = spec?.redlineRpm != null && spec!.redlineRpm! > 0
@ -49,7 +44,6 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
: '15500 RPM'; : '15500 RPM';
final compression = spec?.compressionRatio ?? '12.4:1'; final compression = spec?.compressionRatio ?? '12.4:1';
final fuelSystem = spec?.fuelSystem ?? 'Electronic Fuel Injection'; final fuelSystem = spec?.fuelSystem ?? 'Electronic Fuel Injection';
final frameType = spec?.frameType ?? 'Aluminum Deltabox Perimeter'; final frameType = spec?.frameType ?? 'Aluminum Deltabox Perimeter';
final frontBrake = spec?.frontBrake ?? 'Dual Hydraulic Discs'; final frontBrake = spec?.frontBrake ?? 'Dual Hydraulic Discs';
final absSystem = spec?.absType ?? 'Dual-Channel ABS'; final absSystem = spec?.absType ?? 'Dual-Channel ABS';
@ -90,12 +84,10 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
body: LayoutBuilder( body: LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
final isLandscape = constraints.maxWidth > constraints.maxHeight; final isLandscape = constraints.maxWidth > constraints.maxHeight;
if (isLandscape) { if (isLandscape) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Left Column: Hero Spec Card
Expanded( Expanded(
flex: 4, flex: 4,
child: Padding( child: Padding(
@ -103,7 +95,6 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
child: _buildHeroSpecCard(bike, powerHp, torqueLbFt, wetWeight), child: _buildHeroSpecCard(bike, powerHp, torqueLbFt, wetWeight),
), ),
), ),
// Right Column: Spec Sheet Details
Expanded( Expanded(
flex: 6, flex: 6,
child: SingleChildScrollView( child: SingleChildScrollView(
@ -146,12 +137,6 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
} }
Widget _buildHeroSpecCard(GarageMotorcycle bike, String powerHp, String torqueLbFt, String wetWeight) { Widget _buildHeroSpecCard(GarageMotorcycle bike, String powerHp, String torqueLbFt, String wetWeight) {
final imageRef = MotorcycleImageService().getReferenceImage(
make: bike.makeName,
model: bike.modelName,
year: bike.year,
);
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@ -162,56 +147,14 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
), ),
child: Column( child: Column(
children: [ children: [
// Motorcycle Reference Image or Vector Schematic MotorcyclePhoto(
Container( year: bike.year,
make: bike.makeName,
model: bike.modelName,
height: 140, height: 140,
width: double.infinity,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: const Color(0xFF080808),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
border: Border.all(color: const Color(0xFF1F1F1F), width: 1), showAttribution: true,
),
child: Stack(
alignment: Alignment.center,
children: [
if (imageRef.assetPath != null)
Positioned.fill(
child: Image.asset(
imageRef.assetPath!,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) => const Icon(
Icons.two_wheeler,
color: Color(0xFF00E5FF),
size: 72,
),
),
)
else
const Icon(Icons.two_wheeler, color: Color(0xFF00E5FF), size: 72),
Positioned(
bottom: 6,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.75),
borderRadius: BorderRadius.circular(4),
border: Border.all(color: const Color(0xFF00E5FF).withValues(alpha: 0.4), width: 0.8),
),
child: Text(
imageRef.isPhoto ? 'TECHNICAL REFERENCE — ${imageRef.caption.toUpperCase()}' : 'TECHNICAL SCHEMATIC',
style: TextStyle(
fontFamily: 'JetBrains Mono',
fontSize: 8,
fontWeight: FontWeight.w700,
color: const Color(0xFF00E5FF).withValues(alpha: 0.9),
letterSpacing: 0.1,
),
),
),
),
],
),
), ),
const SizedBox(height: 14), const SizedBox(height: 14),
Row( Row(
@ -232,101 +175,40 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
Widget _buildBigKpi(String value, String unit) { Widget _buildBigKpi(String value, String unit) {
return Column( return Column(
children: [ children: [
Text( Text(value, style: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 26, fontWeight: FontWeight.w900, color: Colors.white)),
value, Text(unit, style: const TextStyle(fontFamily: 'Inter', fontSize: 10, fontWeight: FontWeight.w700, color: Color(0xFF00E5FF))),
style: const TextStyle(
fontFamily: 'JetBrains Mono',
fontSize: 26,
fontWeight: FontWeight.w900,
color: Colors.white,
),
),
Text(
unit,
style: const TextStyle(
fontFamily: 'Inter',
fontSize: 10,
fontWeight: FontWeight.w700,
color: Color(0xFF00E5FF),
),
),
], ],
); );
} }
Widget _buildEngineCard( Widget _buildEngineCard(String displacement, String engineType, String cylinders, String redline, String compression, String fuelSystem) {
String displacement, return _buildCard('ENGINE', [
String engineType,
String cylinders,
String redline,
String compression,
String fuelSystem,
) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF0D0D0D),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: const Color(0xFF1F1F1F), width: 1.2),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'ENGINE',
style: TextStyle(
fontFamily: 'Sora',
fontSize: 12,
fontWeight: FontWeight.w800,
color: Color(0xFF00E5FF),
letterSpacing: 0.1,
),
),
const SizedBox(height: 10),
_buildSpecLine('Displacement', displacement), _buildSpecLine('Displacement', displacement),
_buildSpecLine('Configuration', engineType), _buildSpecLine('Configuration', engineType),
_buildSpecLine('Cylinders', cylinders), _buildSpecLine('Cylinders', cylinders),
_buildSpecLine('Redline', redline), _buildSpecLine('Redline', redline),
_buildSpecLine('Compression Ratio', compression), _buildSpecLine('Compression Ratio', compression),
_buildSpecLine('Fuel System', fuelSystem), _buildSpecLine('Fuel System', fuelSystem),
], ]);
),
);
} }
Widget _buildChassisCard(String frameType, String frontBrake, String absSystem) { Widget _buildChassisCard(String frameType, String frontBrake, String absSystem) {
return Container( return _buildCard('CHASSIS & BRAKES', [
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFF0D0D0D),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: const Color(0xFF1F1F1F), width: 1.2),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'CHASSIS & BRAKES',
style: TextStyle(
fontFamily: 'Sora',
fontSize: 12,
fontWeight: FontWeight.w800,
color: Color(0xFF00E5FF),
letterSpacing: 0.1,
),
),
const SizedBox(height: 10),
_buildSpecLine('Frame Type', frameType), _buildSpecLine('Frame Type', frameType),
_buildSpecLine('Front Brake', frontBrake), _buildSpecLine('Front Brake', frontBrake),
_buildSpecLine('ABS System', absSystem), _buildSpecLine('ABS System', absSystem),
], ]);
),
);
} }
Widget _buildDimensionsCard(MotorcycleSpecification? spec) { Widget _buildDimensionsCard(MotorcycleSpecification? spec) {
return _buildCard('WEIGHT & DIMENSIONS', [
_buildSpecLine('Dry Weight', spec?.dryWeightLbs != null ? '${spec!.dryWeightLbs!.toStringAsFixed(0)} lbs' : '375 lbs'),
_buildSpecLine('Fuel Capacity', spec?.fuelCapacityGallons != null ? '${spec!.fuelCapacityGallons!.toStringAsFixed(1)} Gal' : '4.5 Gal'),
_buildSpecLine('Top Speed Potential', spec?.claimedTopSpeedMph != null ? '${spec!.claimedTopSpeedMph!.toStringAsFixed(0)} MPH' : '160+ MPH'),
]);
}
Widget _buildCard(String title, List<Widget> children) {
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
@ -338,20 +220,9 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Text( Text(title, style: const TextStyle(fontFamily: 'Sora', fontSize: 12, fontWeight: FontWeight.w800, color: Color(0xFF00E5FF), letterSpacing: 0.1)),
'WEIGHT & DIMENSIONS',
style: TextStyle(
fontFamily: 'Sora',
fontSize: 12,
fontWeight: FontWeight.w800,
color: Color(0xFF00E5FF),
letterSpacing: 0.1,
),
),
const SizedBox(height: 10), const SizedBox(height: 10),
_buildSpecLine('Dry Weight', spec?.dryWeightLbs != null ? '${spec!.dryWeightLbs!.toStringAsFixed(0)} lbs' : '375 lbs'), ...children,
_buildSpecLine('Fuel Capacity', spec?.fuelCapacityGallons != null ? '${spec!.fuelCapacityGallons!.toStringAsFixed(1)} Gal' : '4.5 Gal'),
_buildSpecLine('Top Speed Potential', spec?.claimedTopSpeedMph != null ? '${spec!.claimedTopSpeedMph!.toStringAsFixed(0)} MPH' : '160+ MPH'),
], ],
), ),
); );
@ -363,26 +234,9 @@ class EvolutionMotorcycleDetailView extends ConsumerWidget {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(label, style: const TextStyle(fontFamily: 'Inter', fontSize: 11, fontWeight: FontWeight.w600, color: Colors.white54)),
label,
style: const TextStyle(
fontFamily: 'Inter',
fontSize: 11,
fontWeight: FontWeight.w600,
color: Colors.white54,
),
),
Flexible( Flexible(
child: Text( child: Text(value, textAlign: TextAlign.right, style: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 11, fontWeight: FontWeight.w700, color: Colors.white)),
value,
textAlign: TextAlign.right,
style: const TextStyle(
fontFamily: 'JetBrains Mono',
fontSize: 11,
fontWeight: FontWeight.w700,
color: Colors.white,
),
),
), ),
], ],
), ),