Skip to content

Commit f6c0438

Browse files
authored
Merge pull request #336 from DevKor-github/333-test-preparationformcreatelist-component
preparation form result 전달 방식 변경, 준비과정 수정 http 요청 put으로 변경
2 parents 0af2e99 + 1a98325 commit f6c0438

9 files changed

Lines changed: 131 additions & 160 deletions

File tree

lib/data/data_sources/preparation_remote_data_source.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class PreparationRemoteDataSourceImpl implements PreparationRemoteDataSource {
145145
PreparationScheduleModifyRequestModelListExtension.fromEntityList(
146146
preparationEntity.preparationStepList);
147147

148-
final result = await dio.post(
148+
final result = await dio.put(
149149
Endpoint.updatePreparationByScheduleId(scheduleId),
150150
data: updateModel.map((model) => model.toJson()).toList(),
151151
);

lib/presentation/my_page/preparation_spare_time_edit/preparation_spare_time_edit_screen.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ class _PreparationSection extends StatelessWidget {
201201
Expanded(
202202
child: PreparationFormCreateList(
203203
preparationNameState: preparationNameState,
204-
enableDismissible: true,
205204
onNameChanged: ({required int index, required String value}) {
206205
context.read<PreparationFormBloc>().add(
207206
PreparationFormPreparationStepNameChanged(

lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_create_list.dart

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,39 @@ import 'package:on_time_front/presentation/onboarding/preparation_name_select/co
44
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart';
55
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_list_field.dart';
66
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_reorderable_list.dart';
7-
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_reorderable_list_dissmissible.dart';
87
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart';
98

109
class PreparationFormCreateList extends StatelessWidget {
1110
const PreparationFormCreateList(
1211
{super.key,
1312
required this.preparationNameState,
1413
required this.onNameChanged,
15-
required this.onCreationRequested,
16-
this.enableDismissible = false});
14+
required this.onCreationRequested});
1715

1816
final PreparationFormState preparationNameState;
1917
final void Function({required int index, required String value})
2018
onNameChanged;
2119
final VoidCallback onCreationRequested;
22-
final bool enableDismissible;
2320

2421
@override
2522
Widget build(BuildContext context) {
2623
return SingleChildScrollView(
2724
child: Column(
2825
children: [
29-
enableDismissible
30-
? PreparationFormReorderableListDismissible(
31-
preparationStepList: preparationNameState.preparationStepList,
32-
onNameChanged: (index, value) {
33-
onNameChanged(index: index, value: value);
34-
},
35-
onTimeChanged: (index, value) => context
36-
.read<PreparationFormBloc>()
37-
.add(PreparationFormPreparationStepTimeChanged(
38-
index: index, preparationStepTime: value)),
39-
onReorder: (oldIndex, newIndex) => context
40-
.read<PreparationFormBloc>()
41-
.add(PreparationFormPreparationStepOrderChanged(
42-
oldIndex: oldIndex, newIndex: newIndex)),
43-
)
44-
: PreparationFormReorderableList(
45-
preparationStepList: preparationNameState.preparationStepList,
46-
onNameChanged: (index, value) {
47-
onNameChanged(index: index, value: value);
48-
},
49-
onTimeChanged: (index, value) => context
50-
.read<PreparationFormBloc>()
51-
.add(PreparationFormPreparationStepTimeChanged(
52-
index: index, preparationStepTime: value)),
53-
onReorder: (oldIndex, newIndex) => context
54-
.read<PreparationFormBloc>()
55-
.add(PreparationFormPreparationStepOrderChanged(
56-
oldIndex: oldIndex, newIndex: newIndex)),
57-
),
26+
PreparationFormReorderableList(
27+
preparationStepList: preparationNameState.preparationStepList,
28+
onNameChanged: (index, value) {
29+
onNameChanged(index: index, value: value);
30+
},
31+
onTimeChanged: (index, value) => context
32+
.read<PreparationFormBloc>()
33+
.add(PreparationFormPreparationStepTimeChanged(
34+
index: index, preparationStepTime: value)),
35+
onReorder: (oldIndex, newIndex) => context
36+
.read<PreparationFormBloc>()
37+
.add(PreparationFormPreparationStepOrderChanged(
38+
oldIndex: oldIndex, newIndex: newIndex)),
39+
),
5840
preparationNameState.status == PreparationFormStatus.adding
5941
? BlocProvider<PreparationStepFormCubit>(
6042
create: (context) => PreparationStepFormCubit(

lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_reorderable_list.dart

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,32 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
import 'package:flutter_swipe_action_cell/core/cell.dart';
4+
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart';
25
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_list_field.dart';
36
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart';
47

8+
class _SwipeActionContent extends StatelessWidget {
9+
const _SwipeActionContent({
10+
required this.icon,
11+
required this.color,
12+
});
13+
14+
final Widget icon;
15+
final Color color;
16+
17+
@override
18+
Widget build(BuildContext context) {
19+
return Container(
20+
decoration: BoxDecoration(
21+
borderRadius: BorderRadius.circular(12),
22+
color: color,
23+
),
24+
padding: const EdgeInsets.all(18.0),
25+
child: icon,
26+
);
27+
}
28+
}
29+
530
class PreparationFormReorderableList extends StatelessWidget {
631
const PreparationFormReorderableList({
732
super.key,
@@ -40,16 +65,44 @@ class PreparationFormReorderableList extends StatelessWidget {
4065
physics: NeverScrollableScrollPhysics(),
4166
itemCount: preparationStepList.length,
4267
itemBuilder: (context, index) {
43-
return PreparationFormListField(
44-
key: ValueKey<String>(preparationStepList[index].id),
45-
index: index,
46-
preparationStep: preparationStepList[index],
47-
onNameChanged: (value) {
48-
onNameChanged(index, value);
49-
},
50-
onPreparationTimeChanged: (value) {
51-
onTimeChanged(index, value);
52-
},
68+
final step = preparationStepList[index];
69+
final theme = Theme.of(context);
70+
71+
return SwipeActionCell(
72+
key: ValueKey<String>(step.id),
73+
backgroundColor: Colors.transparent,
74+
trailingActions: [
75+
SwipeAction(
76+
onTap: (controller) {
77+
if (preparationStepList.length <= 1) return;
78+
context.read<PreparationFormBloc>().add(
79+
PreparationFormPreparationStepRemoved(
80+
preparationStepId: step.id,
81+
),
82+
);
83+
},
84+
color: Colors.transparent,
85+
content: _SwipeActionContent(
86+
icon: const Icon(
87+
Icons.delete,
88+
color: Colors.white,
89+
size: 24,
90+
),
91+
color: theme.colorScheme.error,
92+
),
93+
),
94+
],
95+
child: PreparationFormListField(
96+
key: ValueKey<String>('field_${step.id}'),
97+
index: index,
98+
preparationStep: step,
99+
onNameChanged: (value) {
100+
onNameChanged(index, value);
101+
},
102+
onPreparationTimeChanged: (value) {
103+
onTimeChanged(index, value);
104+
},
105+
),
53106
);
54107
},
55108
onReorder: (int oldIndex, int newIndex) {

lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_reorderable_list_dissmissible.dart

Lines changed: 0 additions & 94 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:flutter_bloc/flutter_bloc.dart';
2+
import 'package:injectable/injectable.dart';
3+
import 'package:on_time_front/domain/entities/preparation_entity.dart';
4+
5+
/// Shared draft state for the `/preparationEdit` flow.
6+
///
7+
/// The caller sets a draft before navigating. The editor overwrites it on Save.
8+
/// The caller reads it after pop and then clears it.
9+
@LazySingleton()
10+
class PreparationEditDraftCubit extends Cubit<PreparationEntity?> {
11+
PreparationEditDraftCubit() : super(null);
12+
13+
void setDraft(PreparationEntity draft) => emit(draft);
14+
15+
void clear() => emit(null);
16+
}
17+
18+

lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/screens/preparation_edit_form.dart

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ import 'package:go_router/go_router.dart';
44
import 'package:on_time_front/core/di/di_setup.dart';
55
import 'package:on_time_front/domain/entities/preparation_entity.dart';
66
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart';
7+
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_edit_draft_cubit.dart';
78
import 'package:on_time_front/presentation/schedule_create/components/top_bar.dart';
89
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/components/preparation_form_create_list.dart';
910

1011
class PreparationEditForm extends StatefulWidget {
11-
const PreparationEditForm({super.key, required this.preparationEntity});
12-
13-
final PreparationEntity preparationEntity;
12+
const PreparationEditForm({super.key});
1413

1514
@override
1615
State<PreparationEditForm> createState() => _PreparationEditFormState();
@@ -24,20 +23,25 @@ class _PreparationEditFormState extends State<PreparationEditForm> {
2423

2524
@override
2625
Widget build(BuildContext context) {
26+
final draft = getIt.get<PreparationEditDraftCubit>().state ??
27+
const PreparationEntity(preparationStepList: []);
28+
2729
return Scaffold(
2830
body: SafeArea(
2931
child: BlocProvider<PreparationFormBloc>(
3032
create: (context) => getIt.get<PreparationFormBloc>()
31-
..add(PreparationFormEditRequested(
32-
preparationEntity: widget.preparationEntity)),
33+
..add(PreparationFormEditRequested(preparationEntity: draft)),
3334
child: BlocBuilder<PreparationFormBloc, PreparationFormState>(
3435
builder: (context, state) {
3536
return Column(
3637
children: [
3738
TopBar(
3839
onNextPageButtonClicked: state.isValid
3940
? () {
40-
context.pop(state.toPreparationEntity());
41+
getIt
42+
.get<PreparationEditDraftCubit>()
43+
.setDraft(state.toPreparationEntity());
44+
context.pop();
4145
}
4246
: null,
4347
onPreviousPageButtonClicked: context.pop,

lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_bloc/flutter_bloc.dart';
33
import 'package:go_router/go_router.dart';
44
import 'package:on_time_front/domain/entities/preparation_entity.dart';
5+
import 'package:on_time_front/core/di/di_setup.dart';
56
import 'package:on_time_front/presentation/app/bloc/auth/auth_bloc.dart';
67
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart';
8+
import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_edit_draft_cubit.dart';
79
import 'package:on_time_front/presentation/shared/components/cupertino_picker_modal.dart';
810
import 'package:on_time_front/l10n/app_localizations.dart';
911
import 'package:on_time_front/presentation/shared/utils/duration_format.dart';
@@ -46,15 +48,25 @@ class _ScheduleSpareAndPreparingTimeFormState
4648
controller: TextEditingController(
4749
text: formatDuration(
4850
context, state.totalPreparationTime)),
49-
onTap: () async {
50-
final PreparationEntity? updatedPreparation =
51-
await context.push('/preparationEdit',
52-
extra: state.preparation);
53-
if (updatedPreparation != null) {
54-
context
55-
.read<ScheduleFormSpareTimeCubit>()
56-
.preparationChanged(updatedPreparation);
57-
}
51+
onTap: () {
52+
final draftCubit = getIt.get<PreparationEditDraftCubit>();
53+
final scheduleSpareTimeCubit =
54+
context.read<ScheduleFormSpareTimeCubit>();
55+
final before = state.preparation ??
56+
const PreparationEntity(preparationStepList: []);
57+
58+
draftCubit.setDraft(before);
59+
context.push('/preparationEdit').then((_) {
60+
if (!mounted) return;
61+
62+
final after = draftCubit.state;
63+
if (after != null && after != before) {
64+
scheduleSpareTimeCubit.preparationChanged(after);
65+
}
66+
67+
// Avoid stale drafts leaking into the next edit session.
68+
draftCubit.clear();
69+
});
5870
},
5971
),
6072
onSaved: (value) {},
@@ -96,11 +108,11 @@ class _ScheduleSpareAndPreparingTimeFormState
96108
Padding(
97109
padding: const EdgeInsets.only(top: 8.0, left: 16.0),
98110
child: MessageBubble(
99-
message: state.getOverlapMessage(context)!,
111+
message: state.getOverlapMessage(context)!,
100112
type: state.isOverlapError
101113
? MessageBubbleType.error
102114
: MessageBubbleType.warning,
103-
),
115+
),
104116
),
105117
],
106118
);

0 commit comments

Comments
 (0)