Skip to content

Commit

Permalink
Merge pull request #13 from f-lab-edu/6-job-posting-delete
Browse files Browse the repository at this point in the history
[#6] 공고 삭제 기능 구현
  • Loading branch information
Younggun-Kim authored Nov 10, 2024
2 parents 547fd12 + 11eec5d commit 51eb3a0
Show file tree
Hide file tree
Showing 20 changed files with 438 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:withu_app/core/core.dart';
import 'package:withu_app/feature/job_posting/data/data.dart';
import 'package:withu_app/shared/data/data.dart';

class JobPostingMockApi extends JobPostingApi with MockAPI {
/// 공고 목록
Expand Down Expand Up @@ -138,4 +139,28 @@ class JobPostingMockApi extends JobPostingApi with MockAPI {
return const ApiResponse.error();
}
}

/// 공고 삭제
@override
FutureOr<ApiResponse<DeleteResponseDto>> deleteJobPosting({
required String jobPostingId,
}) async {
try {
dioAdapter.onDelete(
url,
(server) => server.reply(
200,
DeleteResponseDto.mockSuccess(id: jobPostingId).toJson(),
delay: const Duration(milliseconds: 1000),
),
);

final response = await dio.delete(url);
return ApiResponse.success(
DeleteResponseDto.fromJson(response.data),
);
} catch (e) {
return const ApiResponse.error();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:withu_app/core/core.dart';
import 'package:withu_app/feature/job_posting/data/data.dart';
import 'package:withu_app/shared/data/data.dart';

abstract class JobPostingApi extends API {
/// 공고 목록
Expand All @@ -23,4 +24,9 @@ abstract class JobPostingApi extends API {
FutureOr<ApiResponse<JobPostingDetailDto>> close({
required String id,
});

/// 공고 삭제
FutureOr<ApiResponse<DeleteResponseDto>> deleteJobPosting({
required String jobPostingId,
});
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:withu_app/core/core.dart';
import 'package:withu_app/feature/job_posting/data/data.dart';
import 'package:withu_app/shared/data/data.dart';

class JobPostingApiImpl extends JobPostingApi {
/// 공고 목록
Expand Down Expand Up @@ -35,4 +36,12 @@ class JobPostingApiImpl extends JobPostingApi {
}) {
return const ApiResponse.error();
}

/// 공고 삭제
@override
FutureOr<ApiResponse<DeleteResponseDto>> deleteJobPosting({
required String jobPostingId,
}) {
return const ApiResponse.error();
}
}
11 changes: 10 additions & 1 deletion lib/feature/job_posting/data/repositories/repository_impl.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:withu_app/core/core.dart';
import 'package:withu_app/feature/job_posting/data/data.dart';
import 'package:withu_app/feature/job_posting/domain/domain.dart';
import 'package:withu_app/shared/data/data.dart';

class JobPostingRepositoryImpl implements JobPostingRepository {
final JobPostingApi jobPostingApi;
Expand Down Expand Up @@ -42,11 +43,19 @@ class JobPostingRepositoryImpl implements JobPostingRepository {
return await jobPostingApi.get(id: id);
}

/// 공고 상세 조회
/// 공고 마감
@override
Future<ApiResponse<JobPostingDetailDto>> close({
required String id,
}) async {
return await jobPostingApi.close(id: id);
}

/// 공고 삭제
@override
Future<ApiResponse<DeleteResponseDto>> deleteJobPosting({
required String jobPostingId,
}) async {
return await api.deleteJobPosting(jobPostingId: jobPostingId);
}
}
6 changes: 6 additions & 0 deletions lib/feature/job_posting/domain/repositories/repositories.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:withu_app/core/core.dart';
import 'package:withu_app/feature/job_posting/data/data.dart';
import 'package:withu_app/shared/data/data.dart';

abstract class JobPostingRepository {
/// 공고 목록 조회
Expand All @@ -22,4 +23,9 @@ abstract class JobPostingRepository {
Future<ApiResponse<JobPostingDetailDto>> close({
required String id,
});

/// 공고 삭제
Future<ApiResponse<DeleteResponseDto>> deleteJobPosting({
required String jobPostingId,
});
}
6 changes: 6 additions & 0 deletions lib/feature/job_posting/domain/usecases/usecases.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:withu_app/core/core.dart';
import 'package:withu_app/feature/job_posting/data/data.dart';
import 'package:withu_app/feature/job_posting/domain/domain.dart';
import 'package:withu_app/feature/job_posting/domain/entities/job_posting_detail_entity.dart';
import 'package:withu_app/shared/data/data.dart';

part 'usecases_impl.dart';

Expand All @@ -24,4 +25,9 @@ abstract class JobPostingUseCase {
Future<Either<JobPostingDetailEntity>> close({
required String jobPostingId,
});

/// 공고 삭제
Future<Either<bool>> deleteJobPosting({
required String jobPostingId,
});
}
20 changes: 20 additions & 0 deletions lib/feature/job_posting/domain/usecases/usecases_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,24 @@ class JobPostingUseCaseImpl implements JobPostingUseCase {
},
);
}

/// 공고 삭제
@override
Future<Either<bool>> deleteJobPosting({
required String jobPostingId,
}) async {
final result =
await repository.deleteJobPosting(jobPostingId: jobPostingId);

return result.maybeWhen(
success: (DeleteResponseDto dto) {
return dto.deleted
? const Either.success(true)
: Either.fail(dto.message ?? '');
},
orElse: () {
return Either.fail(StringRes.serverError.tr);
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class JobPostingDetailBloc
on<ClearMessage>(_clearMessage);
on<OnGettingDetailData>(_onGettingDetailData);
on<OnClosedJobPosting>(_onClosedJobPosting);
on<OnDeletedJobPosting>(_onDeletedJobPosting);
}

/// 메시지 초기화 이벤트.
Expand Down Expand Up @@ -75,16 +76,59 @@ class JobPostingDetailBloc
jobPostingId: jobPostingId,
);

result.when(success: (JobPostingDetailEntity data) {
emit(state.copyWith(
status: JobPostingDetailStatus.closed,
));
}, fail: (String message) {
emit(state.copyWith(
status: JobPostingDetailStatus.fail,
entity: null,
message: message,
));
});
result.when(
success: (JobPostingDetailEntity data) {
emit(
state.copyWith(
status: JobPostingDetailStatus.closed,
),
);
},
fail: (String message) {
emit(
state.copyWith(
status: JobPostingDetailStatus.fail,
entity: null,
message: message,
),
);
},
);
}

/// 공고 삭제
void _onDeletedJobPosting(
OnDeletedJobPosting event,
Emitter<JobPostingDetailState> emit,
) async {
final String? jobPostingId = state.entity?.id;

if (jobPostingId == null) {
return;
}

emit(state.copyWith(status: JobPostingDetailStatus.loading));

final Either<bool> result = await useCase.deleteJobPosting(
jobPostingId: jobPostingId,
);

result.when(
success: (bool data) {
emit(
state.copyWith(
status: JobPostingDetailStatus.deleted,
),
);
},
fail: (String message) {
emit(
state.copyWith(
status: JobPostingDetailStatus.fail,
message: message,
),
);
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ class ClearMessage extends JobPostingDetailEvent {}

/// 공고 마감
class OnClosedJobPosting extends JobPostingDetailEvent {}

/// 공고 삭제
class OnDeletedJobPosting extends JobPostingDetailEvent {}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ part of 'job_posting_detail_bloc.dart';
/// loading: Api 통신 중
/// success: API 통신 성공
/// fail: API 통신 실패
/// closed: 마감 상태로 변경됨
enum JobPostingDetailStatus { initial, loading, success, fail, closed }
/// closed: 마감 상태
/// deleted: 삭제 상태
enum JobPostingDetailStatus { initial, loading, success, fail, closed, deleted }

extension JobPostingDetailStatusExt on JobPostingDetailStatus {
bool get isInitial => this == JobPostingDetailStatus.initial;
Expand All @@ -15,6 +16,8 @@ extension JobPostingDetailStatusExt on JobPostingDetailStatus {
bool get isSuccess => this == JobPostingDetailStatus.success;

bool get isClosed => this == JobPostingDetailStatus.closed;

bool get isDeleted => this == JobPostingDetailStatus.deleted;
}

@freezed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ class _JobPostingDetailPage extends StatelessWidget {
CustomAlertDialog.showContentAlert(
context: context,
content: state.message,
closeCallback: () {},
closeCallback: () {
context.read<JobPostingDetailBloc>().add(ClearMessage());
},
);
}

// 마감으로 변경되었을 때
if (state.status.isClosed) {
context.router.back();
if (state.status.isClosed || state.status.isDeleted) {
context.router.maybePop(true);
}
},
builder: (context, state) {
Expand Down Expand Up @@ -158,7 +160,7 @@ class _AppBar extends StatelessWidget {
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
context.back();
context.router.back();
},
),
actions: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,14 @@ class JobPostingsListState<B extends JobPostingsBloc>
builderDelegate: PagedChildBuilderDelegate<JobPostingEntity>(
itemBuilder: (context, item, index) => JobPostingsItem(
entity: item,
onPressed: () {
context.router.push(
onPressed: () async {
final bool? result = await context.router.push<bool>(
JobPostingDetailRoute(jobPostingId: item.id),
);

if(result == true) {
// TODO: 리프레시 추가.
}
}),
firstPageProgressIndicatorBuilder: (context) => _emptyView(),
noItemsFoundIndicatorBuilder: (context) => _emptyView(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ class _DeleteBottomSheet implements DescriptionBottomSheetOption {
String get description => StringRes.canRevertFromPostingManagement.tr;

@override
Function(Bloc? bloc) get exec => (Bloc? bloc) {};
Function(Bloc? bloc) get exec => (Bloc? bloc) {
if (bloc is JobPostingDetailBloc) {
bloc.add(OnDeletedJobPosting());
}
};
}

/// 공고 마감
Expand Down
1 change: 1 addition & 0 deletions lib/shared/data/data.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'data_sources/data_sources.dart';
1 change: 1 addition & 0 deletions lib/shared/data/data_sources/data_sources.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'delete/delete_response_dto.dart';
28 changes: 28 additions & 0 deletions lib/shared/data/data_sources/delete/delete_response_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:freezed_annotation/freezed_annotation.dart';

part 'delete_response_dto.freezed.dart';

part 'delete_response_dto.g.dart';

part 'delete_response_dto.mock.dart';

/// 삭제 응답 DTO
@freezed
class DeleteResponseDto with _$DeleteResponseDto {
const factory DeleteResponseDto({
required String id,
required bool deleted,
required String? message,
}) = _DeleteResponseDto;

factory DeleteResponseDto.fromJson(Map<String, Object?> json) =>
_$DeleteResponseDtoFromJson(json);

/// Mock 삭제 성공
factory DeleteResponseDto.mockSuccess({required String id}) =>
DeleteResponseDtoMock.mockSuccess(id: id);

/// Mock 삭제 실패
factory DeleteResponseDto.mockFail({required String id}) =>
DeleteResponseDtoMock.mockFail(id: id);
}
Loading

0 comments on commit 51eb3a0

Please sign in to comment.