point record
This commit is contained in:
@@ -0,0 +1,654 @@
|
||||
/// Model House Detail Page
|
||||
///
|
||||
/// Displays 360° view launcher, project information, and image gallery.
|
||||
library;
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:worker/core/constants/ui_constants.dart';
|
||||
import 'package:worker/core/theme/colors.dart';
|
||||
|
||||
/// Model House Detail Page
|
||||
class ModelHouseDetailPage extends ConsumerWidget {
|
||||
final String modelId;
|
||||
|
||||
const ModelHouseDetailPage({
|
||||
required this.modelId,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
// Mock data - in real app, fetch from provider
|
||||
final modelData = _getMockData(modelId);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF4F6F8),
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: const FaIcon(
|
||||
FontAwesomeIcons.arrowLeft,
|
||||
color: Colors.black,
|
||||
size: 20,
|
||||
),
|
||||
onPressed: () => context.pop(),
|
||||
),
|
||||
title: const Text(
|
||||
'Chi tiết Nhà mẫu',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const FaIcon(
|
||||
FontAwesomeIcons.shareNodes,
|
||||
color: Colors.black,
|
||||
size: 20,
|
||||
),
|
||||
onPressed: () => _shareModel(context, modelData),
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
],
|
||||
elevation: AppBarSpecs.elevation,
|
||||
backgroundColor: AppColors.white,
|
||||
centerTitle: false,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 360° View Launcher
|
||||
_build360ViewLauncher(context, modelData),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Project Information
|
||||
_buildProjectInfo(modelData),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Image Gallery
|
||||
_buildImageGallery(context, modelData),
|
||||
|
||||
const SizedBox(height: 40),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _build360ViewLauncher(
|
||||
BuildContext context,
|
||||
Map<String, dynamic> modelData,
|
||||
) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.1),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => _launch360View(context, modelData['url360'] as String),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Container(
|
||||
height: 400,
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [Color(0xFF667eea), Color(0xFF764ba2)],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Background image with overlay
|
||||
Positioned.fill(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Opacity(
|
||||
opacity: 0.3,
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: (modelData['images'] as List<Map<String, String>>)
|
||||
.first['url']!,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Content
|
||||
Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// 360° Icon
|
||||
Container(
|
||||
width: 120,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white.withValues(alpha: 0.2),
|
||||
border: Border.all(color: Colors.white, width: 3),
|
||||
),
|
||||
child: const Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
FaIcon(
|
||||
FontAwesomeIcons.arrowsRotate,
|
||||
size: 40,
|
||||
color: Colors.white,
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'360°',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const Text(
|
||||
'Xem nhà mẫu 360°',
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black26,
|
||||
offset: Offset(0, 2),
|
||||
blurRadius: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'Trải nghiệm không gian thực tế ảo',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
// Launch Button
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.15),
|
||||
blurRadius: 12,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: const Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
FaIcon(
|
||||
FontAwesomeIcons.play,
|
||||
size: 14,
|
||||
color: Color(0xFF667eea),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'Bắt đầu tham quan',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF667eea),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildProjectInfo(Map<String, dynamic> modelData) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.08),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Title
|
||||
Text(
|
||||
modelData['title'] as String,
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Specs Grid
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildSpecItem(
|
||||
'Diện tích',
|
||||
modelData['area'] as String,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _buildSpecItem(
|
||||
'Địa điểm',
|
||||
modelData['location'] as String,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: _buildSpecItem(
|
||||
'Phong cách',
|
||||
modelData['style'] as String,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Description
|
||||
Text(
|
||||
modelData['description'] as String,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF4b5563),
|
||||
height: 1.6,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSpecItem(String label, String value) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF8FAFC),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
label.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildImageGallery(
|
||||
BuildContext context,
|
||||
Map<String, dynamic> modelData,
|
||||
) {
|
||||
final images = modelData['images'] as List<Map<String, String>>;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.08),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Gallery Title
|
||||
const Row(
|
||||
children: [
|
||||
FaIcon(
|
||||
FontAwesomeIcons.images,
|
||||
size: 18,
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
'Thư viện Hình ảnh',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Gallery Grid
|
||||
SizedBox(
|
||||
height: 120,
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: images.length,
|
||||
itemBuilder: (context, index) {
|
||||
final image = images[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: GestureDetector(
|
||||
onTap: () => _showImageViewer(context, images, index),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: SizedBox(
|
||||
width: 120,
|
||||
height: 120,
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: image['url']!,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) => Container(
|
||||
color: AppColors.grey100,
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
),
|
||||
errorWidget: (context, url, error) => Container(
|
||||
color: AppColors.grey100,
|
||||
child: const Icon(Icons.error),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _launch360View(BuildContext context, String url) async {
|
||||
final uri = Uri.parse(url);
|
||||
if (await canLaunchUrl(uri)) {
|
||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
} else {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Không thể mở link 360°')),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _showImageViewer(
|
||||
BuildContext context,
|
||||
List<Map<String, String>> images,
|
||||
int initialIndex,
|
||||
) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierColor: Colors.black87,
|
||||
builder: (context) => _ImageViewerDialog(
|
||||
images: images,
|
||||
initialIndex: initialIndex,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _shareModel(BuildContext context, Map<String, dynamic> modelData) {
|
||||
Share.share(
|
||||
'Xem mô hình 360° ${modelData['title']}\n${modelData['url360']}',
|
||||
subject: modelData['title'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _getMockData(String modelId) {
|
||||
// Mock data - in real app, fetch from repository
|
||||
return {
|
||||
'title': 'Căn hộ Studio',
|
||||
'area': '35m²',
|
||||
'location': 'Quận 7',
|
||||
'style': 'Hiện đại',
|
||||
'description':
|
||||
'Thiết kế hiện đại cho căn hộ studio 35m², tối ưu không gian sống với gạch men cao cấp và màu sắc hài hòa. Sử dụng gạch granite nhập khẩu cho khu vực phòng khách và gạch ceramic chống thấm cho khu vực ẩm ướt.',
|
||||
'url360': 'https://vr.house3d.com/web/panorama-player/H00179549',
|
||||
'images': [
|
||||
{
|
||||
'url':
|
||||
'https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=800&h=600&fit=crop',
|
||||
'caption': 'Phối cảnh tổng thể căn hộ studio với thiết kế hiện đại',
|
||||
},
|
||||
{
|
||||
'url':
|
||||
'https://center.eurotile.vn/data/eurotileData/design/202009/23/4/main_img.jpg',
|
||||
'caption': 'Khu vực phòng khách với gạch granite cao cấp',
|
||||
},
|
||||
{
|
||||
'url':
|
||||
'https://center.eurotile.vn/data/eurotileData/design/202009/23/4/project_img_1.jpg?v=1',
|
||||
'caption': 'Phòng ngủ chính với gạch ceramic màu trung tính',
|
||||
},
|
||||
{
|
||||
'url':
|
||||
'https://center.eurotile.vn/data/eurotileData/design/202009/23/4/project_img_0.jpg?v=1',
|
||||
'caption': 'Khu vực bếp với gạch mosaic điểm nhấn',
|
||||
},
|
||||
{
|
||||
'url':
|
||||
'https://images.unsplash.com/photo-1620626011761-996317b8d101?w=800&h=600&fit=crop',
|
||||
'caption': 'Phòng tắm hiện đại với gạch chống thấm cao cấp',
|
||||
},
|
||||
{
|
||||
'url':
|
||||
'https://center.eurotile.vn/data/eurotileData/design/202009/23/4/project_img_3.jpg?v=1',
|
||||
'caption': 'Khu vực bàn ăn ấm cúng',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Image Viewer Dialog with Swipe Navigation
|
||||
class _ImageViewerDialog extends StatefulWidget {
|
||||
final List<Map<String, String>> images;
|
||||
final int initialIndex;
|
||||
|
||||
const _ImageViewerDialog({
|
||||
required this.images,
|
||||
required this.initialIndex,
|
||||
});
|
||||
|
||||
@override
|
||||
State<_ImageViewerDialog> createState() => _ImageViewerDialogState();
|
||||
}
|
||||
|
||||
class _ImageViewerDialogState extends State<_ImageViewerDialog> {
|
||||
late PageController _pageController;
|
||||
late int _currentIndex;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_currentIndex = widget.initialIndex;
|
||||
_pageController = PageController(initialPage: widget.initialIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
insetPadding: EdgeInsets.zero,
|
||||
child: Container(
|
||||
color: Colors.black,
|
||||
child: Stack(
|
||||
children: [
|
||||
// Main PageView
|
||||
Center(
|
||||
child: PageView.builder(
|
||||
controller: _pageController,
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
},
|
||||
itemCount: widget.images.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Center(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: widget.images[index]['url']!,
|
||||
fit: BoxFit.contain,
|
||||
placeholder: (context, url) => const Center(
|
||||
child: CircularProgressIndicator(color: Colors.white),
|
||||
),
|
||||
errorWidget: (context, url, error) => const Icon(
|
||||
Icons.error,
|
||||
color: Colors.white,
|
||||
size: 48,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
// Top bar with counter and close button
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: SafeArea(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.black.withValues(alpha: 0.7),
|
||||
Colors.transparent,
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'${_currentIndex + 1} / ${widget.images.length}',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close, color: Colors.white),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Caption at bottom
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.transparent,
|
||||
Colors.black.withValues(alpha: 0.7),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
widget.images[_currentIndex]['caption']!,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -169,6 +169,7 @@ class _LibraryTab extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(20),
|
||||
children: const [
|
||||
_LibraryCard(
|
||||
modelId: 'studio-01',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=800&h=200&fit=crop',
|
||||
title: 'Căn hộ Studio',
|
||||
@@ -178,6 +179,7 @@ class _LibraryTab extends StatelessWidget {
|
||||
has360View: true,
|
||||
),
|
||||
_LibraryCard(
|
||||
modelId: 'villa-01',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1570129477492-45c003edd2be?w=800&h=200&fit=crop',
|
||||
title: 'Biệt thự Hiện đại',
|
||||
@@ -187,6 +189,7 @@ class _LibraryTab extends StatelessWidget {
|
||||
has360View: true,
|
||||
),
|
||||
_LibraryCard(
|
||||
modelId: 'townhouse-01',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1562663474-6cbb3eaa4d14?w=800&h=200&fit=crop',
|
||||
title: 'Nhà phố Tối giản',
|
||||
@@ -196,6 +199,7 @@ class _LibraryTab extends StatelessWidget {
|
||||
has360View: true,
|
||||
),
|
||||
_LibraryCard(
|
||||
modelId: 'apartment-01',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?w=800&h=200&fit=crop',
|
||||
title: 'Chung cư Cao cấp',
|
||||
@@ -212,6 +216,7 @@ class _LibraryTab extends StatelessWidget {
|
||||
/// Library Card Widget
|
||||
class _LibraryCard extends StatelessWidget {
|
||||
const _LibraryCard({
|
||||
required this.modelId,
|
||||
required this.imageUrl,
|
||||
required this.title,
|
||||
required this.date,
|
||||
@@ -219,6 +224,7 @@ class _LibraryCard extends StatelessWidget {
|
||||
this.has360View = false,
|
||||
});
|
||||
|
||||
final String modelId;
|
||||
final String imageUrl;
|
||||
final String title;
|
||||
final String date;
|
||||
@@ -233,13 +239,7 @@ class _LibraryCard extends StatelessWidget {
|
||||
margin: const EdgeInsets.only(bottom: 20),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Chức năng xem chi tiết sẽ được triển khai trong phiên bản tiếp theo',
|
||||
),
|
||||
),
|
||||
);
|
||||
context.push('/model-houses/$modelId');
|
||||
},
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Column(
|
||||
|
||||
Reference in New Issue
Block a user