Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
158 changes: 72 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,72 @@
# Coding Assignment
The goal of this assignment is to build a small React application that lets you search and display information from the Star Wars movies (no knowledge of SW is required). The data needed will be queried from [SWAPI (Star Wars API)](https://swapi.dev/) which is an open testing API.

## Overview
The app should consist of a front page with a centered search box where you can type a search string and get matching results. Clicking on a result should route to a new page with the search box on top and details about the query underneath.

### Searching
The search box will be used to query information about people, planets, starships and vehicles. Beneath the search box there should be five radio buttons:
* All (default)
* People
* Planets
* Starships
* Vehicles

You should use the existing `/search` endpoints for each category (see: https://swapi.dev/documentation#search).
The default behaviour (All) should be to query all four search endpoints and display all results.

### Search results
The search result page should have the whole search form at the top and the list with results beneath it (much like any other search engine, like google or duckduckgo).
Combined results (`All` selected) should be ordered by category whith the category with most results appearing at the top.

Each result entry should be listed with it's `name` property taken from the result plus a list of the films in which it appears (provided in the result).
So a result for a search with `query=luke` should look something like:

```
Luke Sywalker (appears in: 4, 5, 6, 3)
```
Where (4, 5, 6, 3) are the `episode_id`s of the films the character appears in. (Don't worry if the results are not up to date as of 2020)

Generally the useful information from the search response for a single entry is as follows:

```
{
"count": 1,
...
"results": [
{
"name": "Luke Skywalker",
...
"films": [
"http://swapi.dev/api/films/1/",
"http://swapi.dev/api/films/2/",
"http://swapi.dev/api/films/3/",
"http://swapi.dev/api/films/6/"
],
...
"url": "http://swapi.dev/api/people/1/"
}
]
}
```
Note: Pagination is not required, but feel free to add more details into the search result entry at your discretion, making anything better will give you bonus points.

### Detailed view
Each search result entry should be a link routing to a page having the search form at the top and details about the entry beneath it. The url should correspond to the search result entry, so that the the page can be accessed separately. For example if the search result entry url is `http://swapi.dev/api/people/1/` our url should also be `people/1`.
The details displayed should be simple key value pairs displayed as a table (or similar) plus the films in which the thing or person apears in e.g.:

> **Name:** Luke Skywalker
> **Height:** 172
> **Hair color:** blond
> **Skin color:** fair
> **Eye color:** blue
> **Gender:** male
> **Movies:** A New Hope, The Empire Strikes Back, Return of the Jedi

It is not required to include all fields from the result, just a reasonable amount. You get bonus points for displaying information requiring to poll other endpoints (like `Movies` in the example above)

**Extra Bonus**: Incorporate the detailed view to the side of the search results page implementing a master-detail pattern while also keeping the route to the detail view page.

## Technical details

## Requirements
The only strict requirements we pose are that the app is written in **typescript** using the latest version of React. We recommend the use of react patterns wherever meaningful of course, and be prepared to show and explain them when presenting the solution.

### Project Setup
Please setup the application in a way that we can start it by simply running `npm start` or else provide a simple `start.sh` script.

### SWAPI
The [SWAPI](https://swapi.dev/) API is a free service and has a 10,000 requests per day rate limiting. Please make sure you don't abuse it.
Note that in some of the results the URLs returned start with `http` which is wrong and should be modified to `https` for them to work, make sure you handle this correctly.

### External Libraries
We don't mind if you use whatever external libraries you like.

### Estimation
You will see an open issue "Call for estimation". Please estimate by writing a comment when you think the task will be ready before you start. We don't set any hard deadlines.
# Task Completed

First of all, thank you for waiting for this much time, unforunately had endless of queries, travel, work, loan, bank, notary related matters which left me with little time back than. The task has been completed, along with the extra bonus points asked. Below will add the list of things introduced along this project.

## @tanstack/react-query

This is used to handle the api requests hooks and as well the caching to prevent extra requests unneeded, especially for data that usually doesn't change much. Having redis is important on the backend, yet the frontend should as well cache what is needed to be cached.

Further more you can see the plugin configuration at `@plugins/QueryClient`

## beautiful-react-hooks

Set of hooks that allow us to use general usage hooks such as `useThrottledCallback`, `useDebouceCallback`, `useDidMount`, and many others are avaialble at their docs.

## craco

This one would say it is very essential for the following reasons

- Handles webpack matters without the need to eject the app whne using create react app
- Further Jest configuration + `react-app-rewire-alias` for alias
- Generally used for alias in our case for @name/*

## React Routing Dom

We'll know what it is for, and I'm using it for the routing, along with few hooks that we need such as `useNavigation` and `useParams`, you can find it as well used as a hook in `useNavQuery`

## Axios

Use this for our api requests handler, which will be combined later with @transtack/react-query hooks

## antd

Used this for design, yet generally I do not use this, first of all I do not really use chinese libs, due of certain events acquired around the world. Although the lib is used by many and is amazing, yet got althernatives to it which they're twice as much better.

## recoil

Used this for state, which allows cross state component, aka state management. One of good things about it, it is as well minimal

## Tests

Added tests generally for the following

- Testing utils
- Testing hooks
- Testing main app - Could add more for pages if required

## Structure

Aimed to provide a good structure for this project, since it is small project as well.

## Architecture

The general architecture of how everything is split and designed is to simplify everything as much as possible and remain performant. Introducing of reusability is in place, yet is not too much, as would be tiedly coupled later and would make it bigger problem to split and/or fix if any issue happens. Keep code simple and readable, in fact max of lines doesnt exceed 100 lines for no file.

## Full Typescript support

The whole project is full typescript support, including interfaces of the api.

## Futher improvements that could have been introduced

- ESlint
- Storyboard
- Further more tests, especially components testing
- Design could have been made more attractive, yet I believe in this task one of most important queries is the performance, as we know react anyone can write it, but not everyone can write it properly, which can end up with endless performance issues.
- Try and reduce more packages from the package, yet kept it to minimum, in fact the maximum a bit of extra package would be `beatiful-react-hooks`.

## Cheers

Cheers for the test, looking forward to hear from you

Best regards,
Red
99 changes: 99 additions & 0 deletions TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Coding Assignment

The goal of this assignment is to build a small React application that lets you search and display information from the Star Wars movies (no knowledge of SW is required). The data needed will be queried from [SWAPI (Star Wars API)](https://swapi.dev/) which is an open testing API.

## Overview

The app should consist of a front page with a centered search box where you can type a search string and get matching results. Clicking on a result should route to a new page with the search box on top and details about the query underneath.

### Searching

The search box will be used to query information about people, planets, starships and vehicles. Beneath the search box there should be five radio buttons:

* All (default)
* People
* Planets
* Starships
* Vehicles

You should use the existing `/search` endpoints for each category (see: <https://swapi.dev/documentation#search>).
The default behaviour (All) should be to query all four search endpoints and display all results.

### Search results

The search result page should have the whole search form at the top and the list with results beneath it (much like any other search engine, like google or duckduckgo).
Combined results (`All` selected) should be ordered by category whith the category with most results appearing at the top.

Each result entry should be listed with it's `name` property taken from the result plus a list of the films in which it appears (provided in the result).
So a result for a search with `query=luke` should look something like:

```text
Luke Sywalker (appears in: 4, 5, 6, 3)
```

Where (4, 5, 6, 3) are the `episode_id`s of the films the character appears in. (Don't worry if the results are not up to date as of 2020)

Generally the useful information from the search response for a single entry is as follows:

```json
{
"count": 1,
...
"results": [
{
"name": "Luke Skywalker",
...
"films": [
"http://swapi.dev/api/films/1/",
"http://swapi.dev/api/films/2/",
"http://swapi.dev/api/films/3/",
"http://swapi.dev/api/films/6/"
],
...
"url": "http://swapi.dev/api/people/1/"
}
]
}
```

Note: Pagination is not required, but feel free to add more details into the search result entry at your discretion, making anything better will give you bonus points.

### Detailed view

Each search result entry should be a link routing to a page having the search form at the top and details about the entry beneath it. The url should correspond to the search result entry, so that the the page can be accessed separately. For example if the search result entry url is `http://swapi.dev/api/people/1/` our url should also be `people/1`.
The details displayed should be simple key value pairs displayed as a table (or similar) plus the films in which the thing or person apears in e.g.:

> **Name:** Luke Skywalker
> **Height:** 172
> **Hair color:** blond
> **Skin color:** fair
> **Eye color:** blue
> **Gender:** male
> **Movies:** A New Hope, The Empire Strikes Back, Return of the Jedi

It is not required to include all fields from the result, just a reasonable amount. You get bonus points for displaying information requiring to poll other endpoints (like `Movies` in the example above)

**Extra Bonus**: Incorporate the detailed view to the side of the search results page implementing a master-detail pattern while also keeping the route to the detail view page.

## Technical details

## Requirements

The only strict requirements we pose are that the app is written in **typescript** using the latest version of React. We recommend the use of react patterns wherever meaningful of course, and be prepared to show and explain them when presenting the solution.

### Project Setup

Please setup the application in a way that we can start it by simply running `npm start` or else provide a simple `start.sh` script.

### SWAPI

The [SWAPI](https://swapi.dev/) API is a free service and has a 10,000 requests per day rate limiting. Please make sure you don't abuse it.
Note that in some of the results the URLs returned start with `http` which is wrong and should be modified to `https` for them to work, make sure you handle this correctly.

### External Libraries

We don't mind if you use whatever external libraries you like.

### Estimation

You will see an open issue "Call for estimation". Please estimate by writing a comment when you think the task will be ready before you start. We don't set any hard deadlines.
30 changes: 18 additions & 12 deletions craco.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
const path = require(`path`);
const {CracoAliasPlugin } = require('react-app-rewire-alias')

const aliasMap = {
"@components": "src/components",
"@pages": "src/pages",
"@hooks": "src/hooks",
"@plugins": "src/plugins",
"@services": "src/services",
"@utils": "src/utils",
"@api": "src/api",
"@app": "src",
}

module.exports = {
webpack: {
alias: {
"@components": path.resolve(__dirname, "src/components"),
"@pages": path.resolve(__dirname, "src/pages"),
"@hooks": path.resolve(__dirname, "src/hooks"),
"@plugins": path.resolve(__dirname, "src/plugins"),
"@services": path.resolve(__dirname, "src/services"),
"@utils": path.resolve(__dirname, "src/utils"),
"@api": path.resolve(__dirname, "src/api"),
},
},
plugins: [
{
plugin: CracoAliasPlugin,
options: {alias: aliasMap }
}
],
};
Loading