Skip to content
This repository was archived by the owner on Aug 9, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
2599f28
fix: updated gradle version
fonsecguilherme Jun 10, 2024
8ddd2df
fix: changed api key
fonsecguilherme Jun 10, 2024
0c82559
feat: added bloc and provider packages
fonsecguilherme Jun 11, 2024
d7d566f
feat: created app skeleton
fonsecguilherme Jun 11, 2024
88af2bd
feat: added app fonts
fonsecguilherme Jun 11, 2024
dbf5c54
feat: created app typography file
fonsecguilherme Jun 11, 2024
c8b3237
feat: creation of cubit, state, and home page
fonsecguilherme Jun 11, 2024
b6d9639
feat: changed api key and add blocprovider to homepage
fonsecguilherme Jun 11, 2024
caf7e22
feat:finished all listing in home page
fonsecguilherme Jun 11, 2024
aaccc3b
fix: deleted unnecessary code
fonsecguilherme Jun 11, 2024
edc4d15
feat: create favorite cubit and state
fonsecguilherme Jun 11, 2024
df881e1
feat: added navigation to restaurant details
fonsecguilherme Jun 11, 2024
d6324a0
feat: add new favorite cubit provider
fonsecguilherme Jun 12, 2024
17606c3
feat: create favorite cubit and state classes
fonsecguilherme Jun 12, 2024
9ae556b
feat: create restaurant details page
fonsecguilherme Jun 12, 2024
0b7e4db
feat: add navigation to restaurant details
fonsecguilherme Jun 12, 2024
1aa7dbb
fix: minor layout changes
fonsecguilherme Jun 12, 2024
1be4aba
feat: providing cubit to card
fonsecguilherme Jun 12, 2024
d7caeb3
fix: add missing text styles
fonsecguilherme Jun 12, 2024
f950352
feat: add favorite reactivity
fonsecguilherme Jun 12, 2024
46140a3
feat: implemented favorite restaurants screen
fonsecguilherme Jun 12, 2024
f33a4b4
fix: deleted unused test
fonsecguilherme Jun 12, 2024
8f6779d
feat: add test packages
fonsecguilherme Jun 13, 2024
fc1e493
fix: change cubit and state name
fonsecguilherme Jun 13, 2024
0145868
feat: added tests
fonsecguilherme Jun 13, 2024
949c47a
fix: changed api key
fonsecguilherme Jun 13, 2024
acc56a9
feat: add new packages
fonsecguilherme Jun 13, 2024
85c2aa7
feat: add equatable to model
fonsecguilherme Jun 13, 2024
941e9ad
fix: layout changed
fonsecguilherme Jun 13, 2024
9f7eaf6
Update README.md
fonsecguilherme Jun 13, 2024
3f2794f
fix: deleted commented code
fonsecguilherme Jun 13, 2024
29c2286
fix: ajusted logic and star size
fonsecguilherme Jun 13, 2024
27c51bf
feat: layout adjustments
fonsecguilherme Jun 13, 2024
39b0396
feat: add restaurant details test
fonsecguilherme Jun 14, 2024
9bcce21
feat: changed project structure
fonsecguilherme Jun 14, 2024
bf27393
fix: remove api key
fonsecguilherme Jun 14, 2024
0437dd2
Update README.md
fonsecguilherme Jun 14, 2024
1feb7b7
feat: get it implementation
fonsecguilherme Jun 14, 2024
042b14a
fix: removed api key
fonsecguilherme Jun 14, 2024
0755d4c
Merge branch 'develop'
fonsecguilherme Jun 14, 2024
4fa8b53
Update README.md
fonsecguilherme Jun 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 48 additions & 162 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,183 +1,69 @@
# RestauranTour

Be sure to read **all** of this document carefully, and follow the guidelines within.
PT/BR 🇧🇷
- Projeto proposto pela equipe da Super Formula. Onde é mostrado duas telas principais. Uma tela de catálogo de restaurantes onde o usuário possui as opção de clicar ver detalhes e a tela de favoritos onde estão listados os restaurantes favoritados.

## Vendorized Flutter
English 🇺🇸
- Project proposed by Super Formula team. Where it is shown a two main screen. Oee catalogue of restaurants where the user has the option tap and see more details and the favorites screen where are listed the favorited restaurants.

3. We use [fvm](https://fvm.app/) for managing the flutter version within the project. Using terminal, while being on the test repository, install the tools dependencies by running the following commands:
## Autor
- Guilherme Fonseca [Github](https://github.com/fonsecguilherme) e [Linkedin](https://www.linkedin.com/in/devfonsecguilherme/)

```sh
dart pub global activate fvm
```
## Stack
Dart and Flutter
**Packages:** [Mocktail](https://pub.dev/packages/mocktail), [Flutter_bloc](https://pub.dev/packages/flutter_bloc), [Bloc]( https://pub.dev/packages/bloc), [Network Image Mock](https://pub.dev/packages/network_image_mock), [Equatable](https://pub.dev/packages/equatable), [Bloc test](https://pub.dev/packages/bloc_test), [GetIt](https://pub.dev/packages/get_it)

The output of the command will ask to add the folder `./pub-cache/bin` to your PATH variables, if you didn't already. If that is the case, add it to your environment variables, and restart the terminal.

```sh
export PATH="$PATH":"$HOME/.pub-cache/bin" # Add this to your environment variables
```

4. Install the project's flutter version using `fvm`.

```sh
fvm use
```

5. From now on, you will run all the flutter commands with the `fvm` prefix. Get all the projects dependencies.

```sh
fvm flutter pub get
```

More information on the approach can be found here:

> hhttps://fvm.app/docs/getting_started/installation

From the root directory:


### IDE Setup

<details>
<summary>Use with VSCode</summary>
<p>

If you're a VScode user link the new Flutter SDK path in your settings
`$projectRoot/.vscode/settings.json` (create if it doesn't exist yet)

```json
{
"dart.flutterSdkPath": ".fvm/flutter_sdk"
}
```
## BLoc
PT/BR 🇧🇷
- Para esse projeto, foi utilizado cubits para gerenciamento de estados e arquitetura proposta na documentação do bloc. A escolha foi baseada justamente por ser um padrão bem definido, altamente testável, com boa adoção pelo mercado e as possibilidades de ajustes finos na UI.

English 🇺🇸
- For this project, I used cubits for state management and the architecture proposed in bloc documentation. This choice was based on the fact that bloc is a well defined standard, highly testable, well received in the market and the possibilities of precise adjustments in the UI

<p float="left">
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/f08bacb2-f4da-4d95-8364-27e1934a1918" width="350" />
</p>
</details>

<details>
<summary>Use with IntelliJ / Android Studio</summary>
<p>
## Tests
PT/BR 🇧🇷
- Tentei cobrir as 3 principais componentes do app: listagem dos restaurantes, tela de detalhes e tela de favoritos. Além disso também foi testes do cubit favoritos.

Go to `Preferences > Languages & Frameworks > Flutter` and set the Flutter SDK path to `$projectRoot/.fvm/flutter_sdk`
English 🇺🇸
- I tried to cover all 3 main componentes of the app: restaurants listing, details screen and favorites screen. Beyond that, there are also tests for favorites cubit.

<img width="800" alt="IntelliJ Settings" src="https://user-images.githubusercontent.com/1096485/64658026-3a1fdd00-d436-11e9-9457-556059f68e2c.png">
## Video
[Video](https://drive.google.com/file/d/1MmWPcCwgEg64gvIHnNFpTsiJdiltdfQn/view?usp=share_link)

## Screenshots
* Home page Android
<p float="left">
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/3e1b54fb-7647-4bbc-b120-dd804e9306d3" width="350" />
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/f735a86e-0158-4655-b053-9332c1f9d26a" width="350" />
</p>
</details>

## Requirements

### App Structure

#### Restaurant List Page

- Tab Bar
- List of favorites (stored client side)
- List of businesses
- Hero image
- Name
- Price
- Category
- Rating (rounded to the nearest value)
- Open/Closed

#### Restaurant Detail View

- Ability to favorite a business
- Name
- Hero image
- Price and category
- Address
- Rating
- Total reviews
- List of reviews
- User name
- Rating
- User image
- Review Text (These are just snippets of the full review, usually like 3-4 lines long)

#### Misc.

- Clear documentation on the structure and architecture of your application.
- Clear and logical commit messages.
- We suggest following [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)

## Test Coverage

To demonstrate your experience writing different types of tests in Flutter please do the following:

- Choose ONE portion of your state management and write a unit test.
- Choose ONE widget and write a widget test.

Feel free to add more tests as you see fit but the above is the minimum requirement.

## Design

- See this [Figma File](https://www.figma.com/file/KsEhQUp66m9yeVkvQ0hSZm/Flutter-Test?node-id=0%3A1) for design information related to the overall look and feel of the application. We do not expect pixel-perfection but would like the application to visually be close to what is specified in the Figma file.

![List View](screenshots/listview.png)
![Detail View](screenshots/detailview.png)

## API

The [Yelp GraphQL API](https://www.yelp.com/developers/graphql/guides/intro) is used as the API for this Application. We have provided the boilerplate of the API requests and backing data models to save you some time. To successfully make a request to the Yelp GraphQL API, please follow these steps:

1. Please go to https://www.yelp.com/signup and sign up for a developer account.
1. Once signed up, navigate to https://www.yelp.com/developers/v3/manage_app.
1. Create a new app by filling out the required information.
1. Once your app is created, scroll down and join the `Developer Beta`. This allows you to use the GraphQL API.
1. Copy your API Key from your app page and paste it on `line 5` [yelp_repository.dart](app/lib/yelp_repository.dart) replacing the `<PUT YOUR API KEY HERE>` with your key.
1. Run the app and tap the `Fetch Restaurants` button. If you see a log like `Fetched x restaurants` you are all set!

## Technical Requirements

### State Management

Please restrict your usage of state management or dependency injection to the following options:

1. [provider](https://pub.dev/packages/provider)
2. [Riverpod](https://pub.dev/packages/riverpod)
3. [bloc](https://pub.dev/packages/bloc)
4. [get_it](https://pub.dev/packages/get_it)/[get_it_mixins](https://pub.dev/packages/get_it_mixin)
5. [Mobx](https://pub.dev/packages/mobx)

We ask this because this challenge values consistency and efficiency over ingenuity. Using commonly used libraries ensures that we can review your code in a timely manner and allows us to provide better feedback.

## Coding Values

At **Superformula** we strive to build applications that have

- Consistent architecture
- Extensible, clean code
- Solid testing
- Good security & performance best practices

### Clear, consistent architecture

Approach your submission as if it were a real world app. This includes Use any libraries that you would normally choose.

_Please note: we're interested in your code & the way you solve the problem, not how well you can use a particular library or feature._

### Easy to understand

Writing boring code that is easy to follow is essential at **Superformula**.

We're interested in your method and how you approach the problem just as much as we're interested in the end result.

### Solid testing approach

While the purpose of this challenge is not to gauge whether you can achieve 100% test coverage, we do seek to evaluate whether you know how & what to test.

## Q&A
* Favorites page Android
<p float="left">
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/3e35d0b8-f75d-45ee-a9a1-a03fffd7c45b" width="350" />
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/fe5dc2bc-f12c-4404-969b-82381832ba80" width="350" />
</p>

> Where should I send back the result when I'm done?
* Restaurant details Android
<p float="left">
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/9dfef093-8172-4afd-9e62-4d22062058a7" width="350" />
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/fccb7ef2-3e7d-475c-8c58-2dae4b9c6c1e" width="350" />
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/ef757006-2c8e-4e82-b22b-6b64cd6df171" width="350" />
</p>

Please fork this repo and then send us a pull request to our repo when you think you are done. There is no deadline for this task unless otherwise noted to you directly.
* Error to fetch restaurans Android
<p float="left">
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/6e596a1c-6263-42e0-8723-f89a65447ea9" width="350" />
</p>

> What if I have a question?

Just create a new issue in this repo and we will respond and get back to you quickly.
* Restaurant details snack bar Android
<p float="left">
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/6fdd2acb-88d2-4c06-b87e-c9f8f53b0eba" width="350" />
<img src="https://github.com/fonsecguilherme/flutter_test/assets/43682827/4e99886c-7df7-4d11-b756-28df722d4031" width="350" />
</p>

## Review

The coding challenge is a take-home test upon which we'll be conducting a thorough code review once complete. The review will consist of meeting some more of our mobile engineers and giving a review of the solution you have designed. Please be prepared to share your screen and run/demo the application to the group. During this process, the engineers will be asking questions.
19 changes: 6 additions & 13 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
Expand All @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
Expand All @@ -21,10 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion flutter.compileSdkVersion

Expand Down Expand Up @@ -62,7 +59,3 @@ android {
flutter {
source '../..'
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
15 changes: 1 addition & 14 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
google()
Expand All @@ -26,6 +13,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
30 changes: 22 additions & 8 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()

def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}

include ":app"
Binary file added assets/fonts/Lora-Bold.ttf
Binary file not shown.
Binary file added assets/fonts/Lora-Medium.ttf
Binary file not shown.
Binary file added assets/fonts/OpenSans-Regular.ttf
Binary file not shown.
Binary file added assets/fonts/OpenSans-SemiBold.ttf
Binary file not shown.
41 changes: 41 additions & 0 deletions lib/app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import 'package:restaurantour/business_logic/favorite/favorite_cubit.dart';
import 'package:restaurantour/data/repositories/yelp_repository.dart';
import 'package:restaurantour/presentation/pages/home_page.dart';

import 'business_logic/restaurants/restaurants_cubit.dart';

class App extends StatefulWidget {
const App({Key? key}) : super(key: key);

@override
State<App> createState() => _AppState();
}

class _AppState extends State<App> {
late YelpRepository repository;

@override
void initState() {
super.initState();
repository = GetIt.I<YelpRepository>();
}

@override
Widget build(BuildContext context) => MaterialApp(
debugShowCheckedModeBanner: false,
home: MultiBlocProvider(
providers: [
BlocProvider<RestaurantsCubit>(
create: (context) => RestaurantsCubit(repository),
),
BlocProvider<FavoriteCubit>(
create: (context) => FavoriteCubit(),
),
],
child: const HomePage(),
),
);
}
Loading