fix update page

This commit is contained in:
Phuoc Nguyen
2025-12-04 10:39:47 +07:00
parent 8ff7b3b505
commit d4de557662
3 changed files with 90 additions and 59 deletions

View File

@@ -53,10 +53,14 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
bool _isSubmitting = false;
bool _isLoadingDetail = false;
String? _deletingFileId; // Track which file is being deleted
bool _isAllowModify = true; // From API detail response
/// Whether we're editing an existing submission
bool get isEditing => widget.submission != null;
/// Whether the form is read-only (editing but not allowed to modify)
bool get isReadOnly => isEditing && !_isAllowModify;
@override
void initState() {
super.initState();
@@ -101,6 +105,9 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
// Set existing files from API
_existingFiles = detail.filesList;
// Set modify permission from API
_isAllowModify = detail.isAllowModify;
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
@@ -146,7 +153,11 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
onPressed: () => Navigator.of(context).pop(),
),
title: Text(
isEditing ? 'Chỉnh sửa Dự án' : 'Đăng ký Công trình',
isReadOnly
? 'Chi tiết Dự án'
: isEditing
? 'Chỉnh sửa Dự án'
: 'Đăng ký Công trình',
style: TextStyle(color: colorScheme.onSurface),
),
actions: [
@@ -197,10 +208,12 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
// File Upload
_buildFileUploadCard(colorScheme),
const SizedBox(height: 24),
// Submit Button
_buildSubmitButton(colorScheme),
// Submit Button - only show when not read-only
if (!isReadOnly) ...[
const SizedBox(height: 24),
_buildSubmitButton(colorScheme),
],
const SizedBox(height: 40),
],
),
@@ -376,49 +389,50 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
),
const SizedBox(height: 16),
// Upload Area
InkWell(
onTap: _pickFiles,
borderRadius: BorderRadius.circular(8),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 20),
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(
color: colorScheme.surfaceContainerHighest,
width: 2,
style: BorderStyle.solid,
// Upload Area - only show when not read-only
if (!isReadOnly)
InkWell(
onTap: _pickFiles,
borderRadius: BorderRadius.circular(8),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 20),
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(
color: colorScheme.surfaceContainerHighest,
width: 2,
style: BorderStyle.solid,
),
borderRadius: BorderRadius.circular(8),
),
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
FaIcon(
FontAwesomeIcons.cloudArrowUp,
size: 48,
color: colorScheme.onSurfaceVariant,
),
const SizedBox(height: 12),
Text(
'Kéo thả ảnh vào đây',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: colorScheme.onSurface,
),
),
const SizedBox(height: 4),
Text(
'hoặc nhấn để chọn file',
style: TextStyle(
fontSize: 14,
child: Column(
children: [
FaIcon(
FontAwesomeIcons.cloudArrowUp,
size: 48,
color: colorScheme.onSurfaceVariant,
),
),
],
const SizedBox(height: 12),
Text(
'Kéo thả ảnh vào đây',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: colorScheme.onSurface,
),
),
const SizedBox(height: 4),
Text(
'hoặc nhấn để chọn file',
style: TextStyle(
fontSize: 14,
color: colorScheme.onSurfaceVariant,
),
),
],
),
),
),
),
// Existing files from API
if (_existingFiles.isNotEmpty) ...[
@@ -488,7 +502,9 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
int maxLines = 1,
TextInputType? keyboardType,
String? helperText,
bool? readOnly,
}) {
final isFieldReadOnly = readOnly ?? isReadOnly;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -517,11 +533,12 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
controller: controller,
maxLines: maxLines,
keyboardType: keyboardType,
readOnly: isFieldReadOnly,
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(color: colorScheme.onSurfaceVariant),
filled: true,
fillColor: colorScheme.surface,
fillColor: isFieldReadOnly ? colorScheme.surfaceContainerHighest : colorScheme.surface,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: colorScheme.surfaceContainerHighest),
@@ -594,10 +611,10 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
const SizedBox(height: 8),
progressListAsync.when(
data: (progressList) => DropdownButtonFormField<ProjectProgress>(
initialValue: _selectedProgress,
value: _selectedProgress,
decoration: InputDecoration(
filled: true,
fillColor: colorScheme.surface,
fillColor: isReadOnly ? colorScheme.surfaceContainerHighest : colorScheme.surface,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: colorScheme.surfaceContainerHighest),
@@ -618,11 +635,13 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
child: Text(progress.status),
))
.toList(),
onChanged: (value) {
setState(() {
_selectedProgress = value;
});
},
onChanged: isReadOnly
? null
: (value) {
setState(() {
_selectedProgress = value;
});
},
validator: (value) {
if (value == null) {
return 'Vui lòng chọn tiến độ công trình';
@@ -692,11 +711,11 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
),
const SizedBox(height: 8),
InkWell(
onTap: _pickExpectedDate,
onTap: isReadOnly ? null : _pickExpectedDate,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: colorScheme.surface,
color: isReadOnly ? colorScheme.surfaceContainerHighest : colorScheme.surface,
border: Border.all(color: colorScheme.surfaceContainerHighest),
borderRadius: BorderRadius.circular(8),
),
@@ -847,8 +866,8 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
],
),
),
// Only show remove button when not uploading
if (!_isSubmitting)
// Only show remove button when not uploading and not read-only
if (!_isSubmitting && !isReadOnly)
IconButton(
icon: const FaIcon(
FontAwesomeIcons.xmark,
@@ -961,8 +980,8 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
],
),
),
// Delete button or checkmark
if (!_isSubmitting && !isDeleting)
// Delete button or checkmark - only show delete when not read-only
if (!_isSubmitting && !isDeleting && !isReadOnly)
IconButton(
icon: const FaIcon(
FontAwesomeIcons.trash,
@@ -1166,10 +1185,19 @@ class _SubmissionCreatePageState extends ConsumerState<SubmissionCreatePage> {
}
Future<void> _pickExpectedDate() async {
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
// For editing mode with past date, allow selecting from that date
// Otherwise, start from today
final firstDate = (_expectedStartDate != null && _expectedStartDate!.isBefore(today))
? _expectedStartDate!
: today;
final date = await showDatePicker(
context: context,
initialDate: _expectedStartDate ?? DateTime.now(),
firstDate: DateTime.now(),
initialDate: _expectedStartDate ?? today,
firstDate: firstDate,
lastDate: DateTime.now().add(const Duration(days: 365 * 3)),
);