add auth, format
This commit is contained in:
@@ -46,7 +46,8 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
||||
// Validate file sizes
|
||||
final validFiles = <PlatformFile>[];
|
||||
for (final file in result.files) {
|
||||
if (file.size <= 10 * 1024 * 1024) { // 10MB max
|
||||
if (file.size <= 10 * 1024 * 1024) {
|
||||
// 10MB max
|
||||
validFiles.add(file);
|
||||
} else {
|
||||
if (context.mounted) {
|
||||
@@ -131,9 +132,7 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
actions: const [
|
||||
SizedBox(width: AppSpacing.sm),
|
||||
],
|
||||
actions: const [SizedBox(width: AppSpacing.sm)],
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(20),
|
||||
@@ -272,20 +271,31 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
DropdownButtonFormField<String>(
|
||||
value: selectedStyle.value.isEmpty ? null : selectedStyle.value,
|
||||
value: selectedStyle.value.isEmpty
|
||||
? null
|
||||
: selectedStyle.value,
|
||||
decoration: InputDecoration(
|
||||
hintText: '-- Chọn phong cách --',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.primaryBlue, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.primaryBlue,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
@@ -293,14 +303,38 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
items: const [
|
||||
DropdownMenuItem(value: 'hien-dai', child: Text('Hiện đại')),
|
||||
DropdownMenuItem(value: 'toi-gian', child: Text('Tối giản')),
|
||||
DropdownMenuItem(value: 'co-dien', child: Text('Cổ điển')),
|
||||
DropdownMenuItem(value: 'scandinavian', child: Text('Scandinavian')),
|
||||
DropdownMenuItem(value: 'industrial', child: Text('Industrial')),
|
||||
DropdownMenuItem(value: 'tropical', child: Text('Tropical')),
|
||||
DropdownMenuItem(value: 'luxury', child: Text('Luxury')),
|
||||
DropdownMenuItem(value: 'khac', child: Text('Khác (ghi rõ trong ghi chú)')),
|
||||
DropdownMenuItem(
|
||||
value: 'hien-dai',
|
||||
child: Text('Hiện đại'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'toi-gian',
|
||||
child: Text('Tối giản'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'co-dien',
|
||||
child: Text('Cổ điển'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'scandinavian',
|
||||
child: Text('Scandinavian'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'industrial',
|
||||
child: Text('Industrial'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'tropical',
|
||||
child: Text('Tropical'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'luxury',
|
||||
child: Text('Luxury'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'khac',
|
||||
child: Text('Khác (ghi rõ trong ghi chú)'),
|
||||
),
|
||||
],
|
||||
onChanged: (value) {
|
||||
selectedStyle.value = value ?? '';
|
||||
@@ -331,20 +365,31 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
DropdownButtonFormField<String>(
|
||||
value: selectedBudget.value.isEmpty ? null : selectedBudget.value,
|
||||
value: selectedBudget.value.isEmpty
|
||||
? null
|
||||
: selectedBudget.value,
|
||||
decoration: InputDecoration(
|
||||
hintText: '-- Chọn ngân sách --',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.primaryBlue, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.primaryBlue,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
@@ -352,12 +397,30 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
items: const [
|
||||
DropdownMenuItem(value: 'duoi-100tr', child: Text('Dưới 100 triệu')),
|
||||
DropdownMenuItem(value: '100-300tr', child: Text('100 - 300 triệu')),
|
||||
DropdownMenuItem(value: '300-500tr', child: Text('300 - 500 triệu')),
|
||||
DropdownMenuItem(value: '500tr-1ty', child: Text('500 triệu - 1 tỷ')),
|
||||
DropdownMenuItem(value: 'tren-1ty', child: Text('Trên 1 tỷ')),
|
||||
DropdownMenuItem(value: 'trao-doi', child: Text('Trao đổi trực tiếp')),
|
||||
DropdownMenuItem(
|
||||
value: 'duoi-100tr',
|
||||
child: Text('Dưới 100 triệu'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: '100-300tr',
|
||||
child: Text('100 - 300 triệu'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: '300-500tr',
|
||||
child: Text('300 - 500 triệu'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: '500tr-1ty',
|
||||
child: Text('500 triệu - 1 tỷ'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'tren-1ty',
|
||||
child: Text('Trên 1 tỷ'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'trao-doi',
|
||||
child: Text('Trao đổi trực tiếp'),
|
||||
),
|
||||
],
|
||||
onChanged: (value) {
|
||||
selectedBudget.value = value ?? '';
|
||||
@@ -429,18 +492,28 @@ class DesignRequestCreatePage extends HookConsumerWidget {
|
||||
controller: notesController,
|
||||
maxLines: 5,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Mô tả chi tiết về yêu cầu thiết kế, số phòng, công năng sử dụng, sở thích cá nhân...',
|
||||
hintText:
|
||||
'Mô tả chi tiết về yêu cầu thiết kế, số phòng, công năng sử dụng, sở thích cá nhân...',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.grey100, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.primaryBlue, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.primaryBlue,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
contentPadding: const EdgeInsets.all(16),
|
||||
),
|
||||
@@ -626,8 +699,8 @@ class _ProgressStep extends StatelessWidget {
|
||||
color: isCompleted
|
||||
? AppColors.success
|
||||
: isActive
|
||||
? AppColors.primaryBlue
|
||||
: AppColors.grey100,
|
||||
? AppColors.primaryBlue
|
||||
: AppColors.grey100,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
@@ -635,7 +708,9 @@ class _ProgressStep extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: isActive || isCompleted ? AppColors.white : AppColors.grey500,
|
||||
color: isActive || isCompleted
|
||||
? AppColors.white
|
||||
: AppColors.grey500,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -700,7 +775,10 @@ class _FormField extends StatelessWidget {
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: AppColors.primaryBlue, width: 2),
|
||||
borderSide: const BorderSide(
|
||||
color: AppColors.primaryBlue,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@@ -727,10 +805,7 @@ class _FilePreviewItem extends StatelessWidget {
|
||||
final PlatformFile file;
|
||||
final VoidCallback onRemove;
|
||||
|
||||
const _FilePreviewItem({
|
||||
required this.file,
|
||||
required this.onRemove,
|
||||
});
|
||||
const _FilePreviewItem({required this.file, required this.onRemove});
|
||||
|
||||
IconData _getFileIcon() {
|
||||
final extension = file.extension?.toLowerCase();
|
||||
@@ -765,11 +840,7 @@ class _FilePreviewItem extends StatelessWidget {
|
||||
color: AppColors.primaryBlue,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Icon(
|
||||
_getFileIcon(),
|
||||
color: AppColors.white,
|
||||
size: 20,
|
||||
),
|
||||
child: Icon(_getFileIcon(), color: AppColors.white, size: 20),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
@@ -802,10 +873,7 @@ class _FilePreviewItem extends StatelessWidget {
|
||||
color: AppColors.danger,
|
||||
onPressed: onRemove,
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 24,
|
||||
minHeight: 24,
|
||||
),
|
||||
constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -23,10 +23,7 @@ import 'package:worker/features/showrooms/presentation/pages/model_houses_page.d
|
||||
/// - Status timeline
|
||||
/// - Action buttons (edit, contact)
|
||||
class DesignRequestDetailPage extends ConsumerWidget {
|
||||
const DesignRequestDetailPage({
|
||||
required this.requestId,
|
||||
super.key,
|
||||
});
|
||||
const DesignRequestDetailPage({required this.requestId, super.key});
|
||||
|
||||
final String requestId;
|
||||
|
||||
@@ -252,7 +249,11 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _shareRequest(BuildContext context, String requestId, String name) async {
|
||||
Future<void> _shareRequest(
|
||||
BuildContext context,
|
||||
String requestId,
|
||||
String name,
|
||||
) async {
|
||||
try {
|
||||
await Share.share(
|
||||
'Yêu cầu thiết kế #$requestId\n$name',
|
||||
@@ -402,9 +403,7 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
||||
const SizedBox(height: 12),
|
||||
const Text(
|
||||
'Thiết kế 3D của bạn đã sẵn sàng để xem',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF065f46),
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF065f46)),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -451,10 +450,7 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Project Name
|
||||
_SectionHeader(
|
||||
icon: Icons.info,
|
||||
title: 'Thông tin dự án',
|
||||
),
|
||||
_SectionHeader(icon: Icons.info, title: 'Thông tin dự án'),
|
||||
const SizedBox(height: 12),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
@@ -476,10 +472,7 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Description
|
||||
_SectionHeader(
|
||||
icon: Icons.edit,
|
||||
title: 'Mô tả yêu cầu',
|
||||
),
|
||||
_SectionHeader(icon: Icons.edit, title: 'Mô tả yêu cầu'),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
request['description'] as String,
|
||||
@@ -525,10 +518,8 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
||||
)
|
||||
else
|
||||
...files.map(
|
||||
(file) => _FileItem(
|
||||
fileName: file,
|
||||
icon: _getFileIcon(file),
|
||||
),
|
||||
(file) =>
|
||||
_FileItem(fileName: file, icon: _getFileIcon(file)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -553,25 +544,22 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
||||
title: 'Lịch sử trạng thái',
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
...List.generate(
|
||||
timeline.length,
|
||||
(index) {
|
||||
final item = timeline[index];
|
||||
return _TimelineItem(
|
||||
title: item['title'] as String,
|
||||
description: item['description'] as String,
|
||||
date: item['date'] as String,
|
||||
status: item['status'] as DesignRequestStatus,
|
||||
icon: _getTimelineIcon(
|
||||
item['status'] as DesignRequestStatus,
|
||||
timeline.length - index - 1,
|
||||
),
|
||||
isLast: index == timeline.length - 1,
|
||||
getStatusColor: _getStatusColor,
|
||||
getStatusBackgroundColor: _getStatusBackgroundColor,
|
||||
);
|
||||
},
|
||||
),
|
||||
...List.generate(timeline.length, (index) {
|
||||
final item = timeline[index];
|
||||
return _TimelineItem(
|
||||
title: item['title'] as String,
|
||||
description: item['description'] as String,
|
||||
date: item['date'] as String,
|
||||
status: item['status'] as DesignRequestStatus,
|
||||
icon: _getTimelineIcon(
|
||||
item['status'] as DesignRequestStatus,
|
||||
timeline.length - index - 1,
|
||||
),
|
||||
isLast: index == timeline.length - 1,
|
||||
getStatusColor: _getStatusColor,
|
||||
getStatusBackgroundColor: _getStatusBackgroundColor,
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -587,7 +575,10 @@ class DesignRequestDetailPage extends ConsumerWidget {
|
||||
onPressed: () => _editRequest(context),
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: AppColors.grey900,
|
||||
side: const BorderSide(color: AppColors.grey100, width: 2),
|
||||
side: const BorderSide(
|
||||
color: AppColors.grey100,
|
||||
width: 2,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@@ -678,10 +669,7 @@ class _InfoGrid extends StatelessWidget {
|
||||
|
||||
/// Info Item Widget
|
||||
class _InfoItem extends StatelessWidget {
|
||||
const _InfoItem({
|
||||
required this.label,
|
||||
required this.value,
|
||||
});
|
||||
const _InfoItem({required this.label, required this.value});
|
||||
|
||||
final String label;
|
||||
final String value;
|
||||
@@ -723,10 +711,7 @@ class _InfoItem extends StatelessWidget {
|
||||
|
||||
/// Section Header Widget
|
||||
class _SectionHeader extends StatelessWidget {
|
||||
const _SectionHeader({
|
||||
required this.icon,
|
||||
required this.title,
|
||||
});
|
||||
const _SectionHeader({required this.icon, required this.title});
|
||||
|
||||
final IconData icon;
|
||||
final String title;
|
||||
@@ -752,10 +737,7 @@ class _SectionHeader extends StatelessWidget {
|
||||
|
||||
/// File Item Widget
|
||||
class _FileItem extends StatelessWidget {
|
||||
const _FileItem({
|
||||
required this.fileName,
|
||||
required this.icon,
|
||||
});
|
||||
const _FileItem({required this.fileName, required this.icon});
|
||||
|
||||
final String fileName;
|
||||
final IconData icon;
|
||||
@@ -835,11 +817,7 @@ class _TimelineItem extends StatelessWidget {
|
||||
color: getStatusBackgroundColor(status),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: getStatusColor(status),
|
||||
size: 20,
|
||||
),
|
||||
child: Icon(icon, color: getStatusColor(status), size: 20),
|
||||
),
|
||||
if (!isLast)
|
||||
Expanded(
|
||||
|
||||
@@ -54,13 +54,21 @@ class _ModelHousesPageState extends ConsumerState<ModelHousesPage>
|
||||
children: [
|
||||
Text('Đây là nội dung hướng dẫn sử dụng cho tính năng Nhà mẫu:'),
|
||||
SizedBox(height: 12),
|
||||
Text('• Tab "Thư viện Mẫu 360": Là nơi công ty cung cấp các mẫu thiết kế 360° có sẵn để bạn tham khảo.'),
|
||||
Text(
|
||||
'• Tab "Thư viện Mẫu 360": Là nơi công ty cung cấp các mẫu thiết kế 360° có sẵn để bạn tham khảo.',
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text('• Tab "Yêu cầu Thiết kế": Là nơi bạn gửi yêu cầu (ticket) để đội ngũ thiết kế của chúng tôi hỗ trợ bạn.'),
|
||||
Text(
|
||||
'• Tab "Yêu cầu Thiết kế": Là nơi bạn gửi yêu cầu (ticket) để đội ngũ thiết kế của chúng tôi hỗ trợ bạn.',
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text('• Bấm nút "+" trong tab "Yêu cầu Thiết kế" để tạo một Yêu cầu Thiết kế mới.'),
|
||||
Text(
|
||||
'• Bấm nút "+" trong tab "Yêu cầu Thiết kế" để tạo một Yêu cầu Thiết kế mới.',
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text('• Khi yêu cầu hoàn thành, bạn có thể xem link thiết kế 3D trong trang chi tiết yêu cầu.'),
|
||||
Text(
|
||||
'• Khi yêu cầu hoàn thành, bạn có thể xem link thiết kế 3D trong trang chi tiết yêu cầu.',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -127,10 +135,7 @@ class _ModelHousesPageState extends ConsumerState<ModelHousesPage>
|
||||
),
|
||||
body: TabBarView(
|
||||
controller: _tabController,
|
||||
children: const [
|
||||
_LibraryTab(),
|
||||
_DesignRequestsTab(),
|
||||
],
|
||||
children: const [_LibraryTab(), _DesignRequestsTab()],
|
||||
),
|
||||
floatingActionButton: AnimatedBuilder(
|
||||
animation: _tabController,
|
||||
@@ -141,7 +146,11 @@ class _ModelHousesPageState extends ConsumerState<ModelHousesPage>
|
||||
onPressed: _createNewRequest,
|
||||
backgroundColor: AppColors.primaryBlue,
|
||||
elevation: 4,
|
||||
child: const Icon(Icons.add, color: AppColors.white, size: 28),
|
||||
child: const Icon(
|
||||
Icons.add,
|
||||
color: AppColors.white,
|
||||
size: 28,
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
},
|
||||
@@ -160,31 +169,39 @@ class _LibraryTab extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(20),
|
||||
children: const [
|
||||
_LibraryCard(
|
||||
imageUrl: 'https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=800&h=200&fit=crop',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=800&h=200&fit=crop',
|
||||
title: 'Căn hộ Studio',
|
||||
date: '15/11/2024',
|
||||
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.',
|
||||
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.',
|
||||
has360View: true,
|
||||
),
|
||||
_LibraryCard(
|
||||
imageUrl: 'https://images.unsplash.com/photo-1570129477492-45c003edd2be?w=800&h=200&fit=crop',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1570129477492-45c003edd2be?w=800&h=200&fit=crop',
|
||||
title: 'Biệt thự Hiện đại',
|
||||
date: '12/11/2024',
|
||||
description: 'Biệt thự 3 tầng với phong cách kiến trúc hiện đại, sử dụng gạch granite và ceramic premium tạo điểm nhấn.',
|
||||
description:
|
||||
'Biệt thự 3 tầng với phong cách kiến trúc hiện đại, sử dụng gạch granite và ceramic premium tạo điểm nhấn.',
|
||||
has360View: true,
|
||||
),
|
||||
_LibraryCard(
|
||||
imageUrl: 'https://images.unsplash.com/photo-1562663474-6cbb3eaa4d14?w=800&h=200&fit=crop',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1562663474-6cbb3eaa4d14?w=800&h=200&fit=crop',
|
||||
title: 'Nhà phố Tối giản',
|
||||
date: '08/11/2024',
|
||||
description: 'Nhà phố 4x15m với thiết kế tối giản, tận dụng ánh sáng tự nhiên và gạch men màu trung tính.',
|
||||
description:
|
||||
'Nhà phố 4x15m với thiết kế tối giản, tận dụng ánh sáng tự nhiên và gạch men màu trung tính.',
|
||||
has360View: true,
|
||||
),
|
||||
_LibraryCard(
|
||||
imageUrl: 'https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?w=800&h=200&fit=crop',
|
||||
imageUrl:
|
||||
'https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?w=800&h=200&fit=crop',
|
||||
title: 'Chung cư Cao cấp',
|
||||
date: '05/11/2024',
|
||||
description: 'Căn hộ 3PN với nội thất sang trọng, sử dụng gạch marble và ceramic cao cấp nhập khẩu Italy.',
|
||||
description:
|
||||
'Căn hộ 3PN với nội thất sang trọng, sử dụng gạch marble và ceramic cao cấp nhập khẩu Italy.',
|
||||
has360View: true,
|
||||
),
|
||||
],
|
||||
@@ -212,15 +229,15 @@ class _LibraryCard extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
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'),
|
||||
content: Text(
|
||||
'Chức năng xem chi tiết sẽ được triển khai trong phiên bản tiếp theo',
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -243,9 +260,7 @@ class _LibraryCard extends StatelessWidget {
|
||||
placeholder: (context, url) => Container(
|
||||
height: 200,
|
||||
color: AppColors.grey100,
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
child: const Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
errorWidget: (context, url, error) => Container(
|
||||
height: 200,
|
||||
@@ -381,11 +396,7 @@ class _DesignRequestsTab extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Design Request Status
|
||||
enum DesignRequestStatus {
|
||||
pending,
|
||||
designing,
|
||||
completed,
|
||||
}
|
||||
enum DesignRequestStatus { pending, designing, completed }
|
||||
|
||||
/// Request Card Widget
|
||||
class _RequestCard extends StatelessWidget {
|
||||
@@ -438,13 +449,13 @@ class _RequestCard extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
context.push('/model-houses/design-request/${code.replaceAll('#', '')}');
|
||||
context.push(
|
||||
'/model-houses/design-request/${code.replaceAll('#', '')}',
|
||||
);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Padding(
|
||||
@@ -490,10 +501,7 @@ class _RequestCard extends StatelessWidget {
|
||||
// Date
|
||||
Text(
|
||||
'Ngày gửi: $date',
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
style: const TextStyle(fontSize: 14, color: AppColors.grey500),
|
||||
),
|
||||
|
||||
const SizedBox(height: 8),
|
||||
@@ -501,10 +509,7 @@ class _RequestCard extends StatelessWidget {
|
||||
// Description
|
||||
Text(
|
||||
description,
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
style: const TextStyle(fontSize: 14, color: AppColors.grey900),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user