Skip to content
This repository was archived by the owner on Aug 9, 2024. It is now read-only.

PR Flutter Test by Rolando Minera #26

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions .fvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"flutter": "3.13.9"
}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,7 @@ app.*.map.json
/android/app/release

# fvm
.fvm/flutter_sdk
.fvm/flutter_sdk

# env
*.env
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"dart.lineLength": 120,
"dart.flutterSdkPath": ".fvm/flutter_sdk",
"search.exclude": {
"**/.fvm": true
Expand Down
205 changes: 205 additions & 0 deletions coverage/lcov.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
SF:lib/models/restaurant.dart
DA:10,0
DA:15,0
DA:16,0
DA:18,0
DA:26,0
DA:30,0
DA:32,0
DA:42,0
DA:48,0
DA:50,0
DA:59,0
DA:65,0
DA:67,0
DA:75,0
DA:79,0
DA:80,0
DA:82,0
DA:97,1
DA:109,0
DA:110,0
DA:112,0
DA:115,0
DA:116,0
DA:117,0
DA:123,0
DA:124,0
DA:125,0
DA:132,0
DA:133,0
DA:134,0
DA:146,0
DA:151,0
DA:152,0
DA:154,0
LF:34
LH:1
end_of_record
SF:lib/models/restaurant.g.dart
DA:9,0
DA:10,0
DA:11,0
DA:14,0
DA:15,0
DA:16,0
DA:19,0
DA:20,0
DA:23,0
DA:24,0
DA:27,0
DA:28,0
DA:29,0
DA:30,0
DA:33,0
DA:34,0
DA:35,0
DA:36,0
DA:39,0
DA:40,0
DA:41,0
DA:42,0
DA:44,0
DA:47,0
DA:48,0
DA:49,0
DA:50,0
DA:53,0
DA:54,0
DA:57,0
DA:58,0
DA:61,0
DA:62,0
DA:63,0
DA:64,0
DA:65,0
DA:67,0
DA:68,0
DA:69,0
DA:70,0
DA:71,0
DA:72,0
DA:73,0
DA:74,0
DA:75,0
DA:76,0
DA:77,0
DA:79,0
DA:82,0
DA:83,0
DA:84,0
DA:85,0
DA:86,0
DA:87,0
DA:88,0
DA:89,0
DA:90,0
DA:91,0
DA:92,0
DA:95,0
DA:97,0
DA:98,0
DA:99,0
DA:100,0
DA:101,0
DA:104,0
DA:106,0
DA:107,0
DA:108,0
LF:69
LH:0
end_of_record
SF:lib/app_state.dart
DA:5,3
DA:7,1
DA:8,1
DA:11,1
DA:14,2
DA:15,0
DA:16,0
DA:17,0
DA:20,1
DA:21,1
DA:22,2
DA:23,1
DA:26,1
DA:27,6
DA:28,2
DA:29,1
DA:32,1
DA:34,6
DA:35,2
LF:19
LH:16
end_of_record
SF:lib/widgets/star_rating.dart
DA:8,1
DA:12,0
DA:14,1
DA:16,2
DA:17,1
DA:19,1
DA:21,2
DA:23,1
DA:24,1
LF:9
LH:8
end_of_record
SF:lib/resources/color_manager.dart
DA:4,0
DA:5,0
DA:6,0
DA:7,0
DA:8,0
DA:9,0
DA:10,0
DA:11,0
DA:12,0
DA:14,0
DA:15,0
DA:16,0
DA:17,0
DA:18,0
DA:20,0
DA:21,0
DA:22,0
DA:23,0
DA:24,0
DA:25,0
DA:26,0
DA:28,0
DA:29,3
DA:30,0
DA:32,0
DA:34,0
DA:35,0
DA:37,0
DA:38,0
DA:39,0
DA:40,0
DA:41,0
DA:43,0
DA:44,0
DA:46,0
DA:47,0
DA:48,0
DA:50,0
DA:51,0
DA:53,0
DA:54,0
DA:55,0
DA:59,1
DA:60,1
DA:61,2
DA:62,1
DA:64,3
LF:47
LH:6
end_of_record
SF:lib/utils/helper_utils.dart
DA:2,1
DA:3,1
DA:6,1
LF:3
LH:3
end_of_record
37 changes: 37 additions & 0 deletions lib/app_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:restaurantour/models/restaurant.dart';

class AppState extends ChangeNotifier {
static final AppState _instance = AppState._internal();

factory AppState() {
return _instance;
}

AppState._internal();

List<Restaurant> _favorites = [];
List<Restaurant> get favorites => _favorites;
set favorites(List<Restaurant> options) {
_favorites = options;
notifyListeners();
}

void addFavorite(Restaurant restaurant) {
if (isFavorite(restaurant)) return;
_favorites.add(restaurant);
notifyListeners();
}

void removeFavorite(Restaurant restaurant) {
final index = _favorites.indexWhere((element) => element.id == restaurant.id);
_favorites.removeAt(index);
notifyListeners();
}

bool isFavorite(Restaurant? restaurant) {
if (restaurant == null) return false;
final index = _favorites.indexWhere((element) => element.id == restaurant.id);
return index != -1;
}
}
66 changes: 22 additions & 44 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,56 +1,34 @@
import 'package:flutter/material.dart';
import 'package:restaurantour/repositories/yelp_repository.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:provider/provider.dart';
import 'package:restaurantour/app_state.dart';
import 'package:restaurantour/resources/resources_exports.dart';
import 'package:restaurantour/resources/routes_manager.dart';
import 'package:restaurantour/resources/theme_manager.dart';

void main() {
runApp(const Restaurantour());
void main() async {
final appState = AppState(); // Initialize FFAppState
await dotenv.load();
runApp(
MultiProvider(
providers: [ChangeNotifierProvider(create: (context) => appState)],
child: const Restaurantour(),
),
);
}

class Restaurantour extends StatelessWidget {
// This widget is the root of your application.
const Restaurantour({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'RestauranTour',
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const HomePage(),
);
}
}

class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Restaurantour'),
ElevatedButton(
child: const Text('Fetch Restaurants'),
onPressed: () async {
final yelpRepo = YelpRepository();

try {
final result = await yelpRepo.getRestaurants();
if (result != null) {
print('Fetched ${result.restaurants!.length} restaurants');
} else {
print('No restaurants fetched');
}
} catch (e) {
print('Failed to fetch restaurants: $e');
}
},
),
],
),
return ScreenUtilInit(
builder: (context, child) => MaterialApp(
title: AppStrings.appName,
theme: getApplicationTheme(false, context),
onGenerateRoute: RouteGenerator.getRoute,
initialRoute: Routes.homeRoute,
debugShowCheckedModeBanner: false,
),
);
}
Expand Down
22 changes: 20 additions & 2 deletions lib/repositories/yelp_repository.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:restaurantour/models/restaurant.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:restaurantour/utils/mock_data.dart';

const _apiKey = '<PUT YOUR API KEY HERE>';
String? _apiKey = dotenv.env['YELP_API_KEY'];

class YelpRepository {
late Dio dio;
Expand Down Expand Up @@ -64,12 +67,27 @@ class YelpRepository {
'/v3/graphql',
data: _getQuery(offset),
);
return RestaurantQueryResult.fromJson(response.data!['data']['search']);
final data = response.data!['data']['search'];

// final data = await fakeApiCall();
return RestaurantQueryResult.fromJson(data);
} catch (e) {
return null;
}
}

Future<Map<String, dynamic>> fakeApiCall() async {
await Future.delayed(const Duration(seconds: 1));

try {
Map<String, dynamic> parsed = jsonDecode(MockData.yelpResponse);
return parsed;
} catch (e) {
print('Fake api call failed: $e');
return {};
}
}

String _getQuery(int offset) {
return '''
query getRestaurants {
Expand Down
Loading