fix: use shared motorcycle photo in evolution detail
This commit is contained in:
parent
58ba2636f0
commit
07771dbb96
|
|
@ -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,
|
borderRadius: BorderRadius.circular(12),
|
||||||
clipBehavior: Clip.antiAlias,
|
showAttribution: true,
|
||||||
decoration: BoxDecoration(
|
fit: BoxFit.cover,
|
||||||
color: const Color(0xFF080808),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(color: const Color(0xFF1F1F1F), width: 1),
|
|
||||||
),
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
if (imageRef.assetPath != null)
|
|
||||||
Positioned.fill(
|
|
||||||
child: Image.asset(
|
|
||||||
imageRef.assetPath!,
|
|
||||||
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,
|
_buildSpecLine('Displacement', displacement),
|
||||||
String cylinders,
|
_buildSpecLine('Configuration', engineType),
|
||||||
String redline,
|
_buildSpecLine('Cylinders', cylinders),
|
||||||
String compression,
|
_buildSpecLine('Redline', redline),
|
||||||
String fuelSystem,
|
_buildSpecLine('Compression Ratio', compression),
|
||||||
) {
|
_buildSpecLine('Fuel System', 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('Configuration', engineType),
|
|
||||||
_buildSpecLine('Cylinders', cylinders),
|
|
||||||
_buildSpecLine('Redline', redline),
|
|
||||||
_buildSpecLine('Compression Ratio', compression),
|
|
||||||
_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,
|
_buildSpecLine('Frame Type', frameType),
|
||||||
padding: const EdgeInsets.all(16),
|
_buildSpecLine('Front Brake', frontBrake),
|
||||||
decoration: BoxDecoration(
|
_buildSpecLine('ABS System', absSystem),
|
||||||
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('Front Brake', frontBrake),
|
|
||||||
_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,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue