Skip to content

Commit 3a1cc91

Browse files
authored
Merge pull request #58 from nimblehq/feature/15-backend-survey-list
[#15] [Backend] As a logged-in user, I can see the survey list on the Home screen
2 parents 62cdcbc + d7c069b commit 3a1cc91

14 files changed

+347
-2
lines changed

lib/api/response_decoder.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import 'package:japx/japx.dart';
22

33
class ResponseDecoder {
4-
static Map<String, dynamic> decode(Map<String, dynamic> json) {
4+
static Map<String, dynamic> decodeData(Map<String, dynamic> json) {
55
return Japx.decode(json)['data'];
66
}
7+
8+
static Map<String, dynamic> decode(Map<String, dynamic> json) =>
9+
Japx.decode(json);
710
}

lib/api/survey_api_service.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'package:dio/dio.dart';
2+
import 'package:retrofit/http.dart';
3+
import 'package:survey_flutter/model/response/surveys_container_response.dart';
4+
5+
part 'survey_api_service.g.dart';
6+
7+
@RestApi()
8+
abstract class SurveyApiService {
9+
factory SurveyApiService(Dio dio, {String baseUrl}) = _SurveyApiService;
10+
11+
@GET('/surveys')
12+
Future<SurveysContainerResponse> getSurveys(
13+
@Query('page[number]') int pageNumber,
14+
@Query('page[size]') int pageSize,
15+
);
16+
}

lib/model/meta_model.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import 'package:equatable/equatable.dart';
2+
3+
class MetaModel extends Equatable {
4+
final int page;
5+
final int pages;
6+
final int pageSize;
7+
final int records;
8+
9+
const MetaModel({
10+
required this.page,
11+
required this.pages,
12+
required this.pageSize,
13+
required this.records,
14+
});
15+
16+
const MetaModel.dummy()
17+
: this(
18+
page: 0,
19+
pages: 0,
20+
pageSize: 0,
21+
records: 0,
22+
);
23+
24+
@override
25+
List<Object?> get props => [
26+
page,
27+
pages,
28+
pageSize,
29+
records,
30+
];
31+
}

lib/model/response/login_response.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class LoginResponse {
2323
});
2424

2525
factory LoginResponse.fromJson(Map<String, dynamic> json) =>
26-
_$LoginResponseFromJson(ResponseDecoder.decode(json));
26+
_$LoginResponseFromJson(ResponseDecoder.decodeData(json));
2727

2828
LoginModel toLoginModel() => LoginModel(
2929
id: id,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:freezed_annotation/freezed_annotation.dart';
2+
import 'package:survey_flutter/api/response_decoder.dart';
3+
import 'package:survey_flutter/model/meta_model.dart';
4+
5+
part 'meta_response.g.dart';
6+
7+
@JsonSerializable()
8+
class MetaResponse {
9+
final int? page;
10+
final int? pages;
11+
final int? pageSize;
12+
final int? records;
13+
14+
MetaResponse({
15+
required this.page,
16+
required this.pages,
17+
required this.pageSize,
18+
required this.records,
19+
});
20+
21+
factory MetaResponse.fromJson(Map<String, dynamic> json) =>
22+
_$MetaResponseFromJson(ResponseDecoder.decode(json));
23+
24+
static MetaResponse dummy() {
25+
return MetaResponse(
26+
page: 0,
27+
pages: 0,
28+
pageSize: 0,
29+
records: 0,
30+
);
31+
}
32+
33+
MetaModel toMetaModel() => MetaModel(
34+
page: page ?? 0,
35+
pages: pages ?? 0,
36+
pageSize: pageSize ?? 0,
37+
records: records ?? 0,
38+
);
39+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import 'package:freezed_annotation/freezed_annotation.dart';
2+
import 'package:json_annotation/json_annotation.dart';
3+
import 'package:survey_flutter/api/response_decoder.dart';
4+
import 'package:survey_flutter/model/survey_model.dart';
5+
6+
part 'survey_response.g.dart';
7+
8+
@JsonSerializable()
9+
class SurveyResponse {
10+
final String? id;
11+
final String? title;
12+
final String? description;
13+
final String? coverImageUrl;
14+
15+
SurveyResponse({
16+
required this.id,
17+
required this.title,
18+
required this.description,
19+
required this.coverImageUrl,
20+
});
21+
22+
factory SurveyResponse.fromJson(Map<String, dynamic> json) =>
23+
_$SurveyResponseFromJson(ResponseDecoder.decodeData(json));
24+
25+
SurveyModel toSurveyModel() => SurveyModel(
26+
id: id ?? '',
27+
title: title ?? '',
28+
description: description ?? '',
29+
coverImageUrl: coverImageUrl ?? '',
30+
);
31+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import 'package:freezed_annotation/freezed_annotation.dart';
2+
import 'package:survey_flutter/api/response_decoder.dart';
3+
import 'package:survey_flutter/model/meta_model.dart';
4+
import 'package:survey_flutter/model/response/meta_response.dart';
5+
import 'package:survey_flutter/model/response/survey_response.dart';
6+
import 'package:survey_flutter/model/surveys_container_model.dart';
7+
8+
part 'surveys_container_response.g.dart';
9+
10+
@JsonSerializable()
11+
class SurveysContainerResponse {
12+
final List<SurveyResponse>? data;
13+
final MetaResponse? meta;
14+
15+
const SurveysContainerResponse({
16+
required this.data,
17+
required this.meta,
18+
});
19+
20+
factory SurveysContainerResponse.fromJson(Map<String, dynamic> json) {
21+
return _$SurveysContainerResponseFromJson(ResponseDecoder.decode(json));
22+
}
23+
24+
SurveysContainerModel toSurveysContainerModel() => SurveysContainerModel(
25+
surveys:
26+
data?.map((item) => item.toSurveyModel()).toList() ?? List.empty(),
27+
meta: meta?.toMetaModel() ?? const MetaModel.dummy(),
28+
);
29+
}

lib/model/survey_model.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'package:equatable/equatable.dart';
2+
3+
class SurveyModel extends Equatable {
4+
final String id;
5+
final String title;
6+
final String description;
7+
final String coverImageUrl;
8+
9+
const SurveyModel({
10+
required this.id,
11+
required this.title,
12+
required this.description,
13+
required this.coverImageUrl,
14+
});
15+
16+
@override
17+
List<Object?> get props => [
18+
id,
19+
title,
20+
description,
21+
coverImageUrl,
22+
];
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:survey_flutter/model/meta_model.dart';
3+
import 'package:survey_flutter/model/survey_model.dart';
4+
5+
class SurveysContainerModel extends Equatable {
6+
final List<SurveyModel> surveys;
7+
final MetaModel meta;
8+
9+
const SurveysContainerModel({
10+
required this.surveys,
11+
required this.meta,
12+
});
13+
14+
SurveysContainerModel.dummy()
15+
: this(
16+
surveys: List.empty(),
17+
meta: const MetaModel.dummy(),
18+
);
19+
20+
@override
21+
List<Object?> get props => [
22+
surveys,
23+
meta,
24+
];
25+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import 'package:survey_flutter/api/exception/network_exceptions.dart';
2+
import 'package:survey_flutter/api/survey_api_service.dart';
3+
import 'package:survey_flutter/model/surveys_container_model.dart';
4+
5+
abstract class SurveyRepository {
6+
Future<SurveysContainerModel> getSurveys({
7+
required int pageNumber,
8+
required int pageSize,
9+
});
10+
}
11+
12+
class SurveyRepositoryImpl extends SurveyRepository {
13+
final SurveyApiService _apiService;
14+
15+
SurveyRepositoryImpl(this._apiService);
16+
17+
@override
18+
Future<SurveysContainerModel> getSurveys({
19+
required int pageNumber,
20+
required int pageSize,
21+
}) async {
22+
try {
23+
final result = await _apiService.getSurveys(pageNumber, pageSize);
24+
return result.toSurveysContainerModel();
25+
} catch (exception) {
26+
throw NetworkExceptions.fromDioException(exception);
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)