diff --git a/lib/data/dtos/potions_dto.dart b/lib/data/dtos/potions_dto.dart new file mode 100644 index 0000000..f276aef --- /dev/null +++ b/lib/data/dtos/potions_dto.dart @@ -0,0 +1,36 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'potions_dto.g.dart'; + +@JsonSerializable(createToJson: false) +class PotionsDto { + final List? data; + + const PotionsDto({this.data}); + + factory PotionsDto.fromJson(Map json) => _$PotionsDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class PotionDataDto { + final String? id; + final String? type; + final PotionAttributesDataDto? attributes; + + const PotionDataDto({this.id, this.type, this.attributes}); + + factory PotionDataDto.fromJson(Map json) => _$PotionDataDtoFromJson(json); +} + +@JsonSerializable(createToJson: false) +class PotionAttributesDataDto { + final String? name; + final String? characteristics; + final String? effect; + final String? image; + + const PotionAttributesDataDto({this.name, this.characteristics, this.effect, this.image}); + + factory PotionAttributesDataDto.fromJson(Map json) => + _$PotionAttributesDataDtoFromJson(json); +} \ No newline at end of file diff --git a/lib/data/dtos/potions_dto.g.dart b/lib/data/dtos/potions_dto.g.dart new file mode 100644 index 0000000..ab1beb0 --- /dev/null +++ b/lib/data/dtos/potions_dto.g.dart @@ -0,0 +1,32 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'potions_dto.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PotionsDto _$PotionsDtoFromJson(Map json) => PotionsDto( + data: (json['data'] as List?) + ?.map((e) => PotionDataDto.fromJson(e as Map)) + .toList(), +); + +PotionDataDto _$PotionDataDtoFromJson(Map json) => + PotionDataDto( + id: json['id'] as String?, + type: json['type'] as String?, + attributes: json['attributes'] == null + ? null + : PotionAttributesDataDto.fromJson( + json['attributes'] as Map), + ); + +PotionAttributesDataDto _$PotionAttributesDataDtoFromJson( + Map json) => + PotionAttributesDataDto( + name: json['name'] as String?, + characteristics: json['characteristics'] as String?, + effect: json['effect'] as String?, + image: json['image'] as String?, + ); \ No newline at end of file diff --git a/lib/data/mappers/potions_mapper.dart b/lib/data/mappers/potions_mapper.dart new file mode 100644 index 0000000..b0319b3 --- /dev/null +++ b/lib/data/mappers/potions_mapper.dart @@ -0,0 +1,23 @@ +import 'package:leonteva_pmu/data/dtos/potions_dto.dart'; +import 'package:leonteva_pmu/domain/models/card.dart'; + +const String imagePlaceholder = + 'https://cdn-icons-png.flaticon.com/512/4036/4036418.png'; + +extension PotionDataDtoToModel on PotionDataDto { + CardData toDomain() => CardData( + attributes?.name ?? 'UNKNOWN', + imageUrl: attributes?.image ?? imagePlaceholder, + descriptionText: _makeDescriptionText(attributes?.characteristics, attributes?.effect), + ); + + String _makeDescriptionText(String? characteristics, String? effect) { + return characteristics != null && effect != null + ? '$characteristics - $effect' + : characteristics != null + ? 'characteristics: $characteristics' + : effect != null + ? 'effect: $effect' + : ''; + } +} \ No newline at end of file diff --git a/lib/data/repositories/api_interface.dart b/lib/data/repositories/api_interface.dart new file mode 100644 index 0000000..a5ca4b6 --- /dev/null +++ b/lib/data/repositories/api_interface.dart @@ -0,0 +1,7 @@ +import 'package:leonteva_pmu/domain/models/card.dart'; + +typedef OnErrorCallback = void Function(String? error); + +abstract class ApiInterface { + Future?> loadData({OnErrorCallback? onError}); +} \ No newline at end of file diff --git a/lib/data/repositories/mock_repository.dart b/lib/data/repositories/mock_repository.dart new file mode 100644 index 0000000..b7f286d --- /dev/null +++ b/lib/data/repositories/mock_repository.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:leonteva_pmu/data/repositories/api_interface.dart'; +import 'package:leonteva_pmu/domain/models/card.dart'; + +class MockRepository extends ApiInterface { + @override + Future?> loadData({OnErrorCallback? onError}) async { + return [ + CardData( + 'dish1', + descriptionText: 'hehehe', + imageUrl: + 'https://n1s2.hsmedia.ru/48/2d/63/482d63d02b668677a73a2ffbd791a71b/728x546_1_aaca034dfa8a8c33247bd8cb2ed26817@1700x1275_0xac120003_9749770561671744766.jpeg', + ), + CardData( + 'dish2', + descriptionText: 'eeee', + icon: Icons.hail, + imageUrl: + 'https://n1s2.hsmedia.ru/48/2d/63/482d63d02b668677a73a2ffbd791a71b/728x546_1_aaca034dfa8a8c33247bd8cb2ed26817@1700x1275_0xac120003_9749770561671744766.jpeg', + ), + CardData( + 'dish3', + descriptionText: 'aaaaaa', + icon: Icons.warning_amber, + imageUrl: 'https://n1s2.hsmedia.ru/48/2d/63/482d63d02b668677a73a2ffbd791a71b/728x546_1_aaca034dfa8a8c33247bd8cb2ed26817@1700x1275_0xac120003_9749770561671744766.jpeg', + ), + ]; + } +} \ No newline at end of file diff --git a/lib/data/repositories/potter_repository.dart b/lib/data/repositories/potter_repository.dart new file mode 100644 index 0000000..87aa97c --- /dev/null +++ b/lib/data/repositories/potter_repository.dart @@ -0,0 +1,35 @@ +import 'package:dio/dio.dart'; +import 'package:leonteva_pmu/data/dtos/potions_dto.dart'; +import 'package:leonteva_pmu/data/mappers/potions_mapper.dart'; +import 'package:leonteva_pmu/data/repositories/api_interface.dart'; +import 'package:leonteva_pmu/domain/models/card.dart'; +import 'package:pretty_dio_logger/pretty_dio_logger.dart'; + +class PotterRepository extends ApiInterface { + static final Dio _dio = Dio() + ..interceptors.add(PrettyDioLogger( + requestHeader: true, + requestBody: true, + )); + + static const String _baseUrl = 'https://api.potterdb.com'; + + @override + Future?> loadData({String? q, OnErrorCallback? onError}) async { + try { + const String url = '$_baseUrl/v1/potions'; + + final Response response = await _dio.get>( + url, + queryParameters: q != null ? {'filter[name_cont]': q} : null, + ); + + final PotionsDto dto = PotionsDto.fromJson(response.data as Map); + final List? data = dto.data?.map((e) => e.toDomain()).toList(); + return data; + } on DioException catch (e) { + onError?.call(e.response?.statusMessage); + return null; + } + } +} \ No newline at end of file diff --git a/lib/presentation/home_page/home_page.dart b/lib/presentation/home_page/home_page.dart index af15463..d7f0fa9 100644 --- a/lib/presentation/home_page/home_page.dart +++ b/lib/presentation/home_page/home_page.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:leonteva_pmu/data/repositories/potter_repository.dart'; import 'package:leonteva_pmu/presentation/details_page/details_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:leonteva_pmu/domain/models/card.dart'; +import 'package:leonteva_pmu/presentation/dialogs/show_dialog.dart'; part 'card.dart'; @@ -15,21 +17,13 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State { - final Color _color = Colors.orangeAccent; - @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: _color, - title: Text(widget.title), - ), - body: const Body(), - ); + return const Scaffold(body: Body()); } } -class Body extends StatelessWidget { +class Body extends StatefulWidget { const Body({super.key}); // ключи @override diff --git a/pubspec.lock b/pubspec.lock index 3233d5c..69e5907 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -99,6 +99,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.1" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" leak_tracker: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 003b719..633979d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ environment: dependencies: dio: ^5.7.0 pretty_dio_logger: ^1.4.0 + json_annotation: ^4.9.0 flutter: sdk: flutter