├── .babelrc
├── .gitignore
├── src
├── index.js
├── css
│ ├── header.css
│ ├── body.css
│ └── app.css
├── App.jsx
└── Header.jsx
├── public
└── index.html
├── webpack.config.js
├── package.json
└── README.md
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | yarn-error.log
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './css/body.css';
2 | import './css/app.css';
3 | import './css/header.css';
4 |
5 | import App from './App.jsx';
6 |
7 |
--------------------------------------------------------------------------------
/src/css/header.css:
--------------------------------------------------------------------------------
1 | header {
2 | height: 40px;
3 | margin: 0 auto;
4 | padding: 20px 0;
5 | text-align: center;
6 | box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
7 | }
8 |
9 | header svg {
10 | display: block;
11 | width: 100%; height: 100%;
12 | }
13 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Aircall Phone
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/css/body.css:
--------------------------------------------------------------------------------
1 | html, body, h1, h2, h3, ul, li {
2 | margin: 0;
3 | padding: 0;
4 | border: 0;
5 | font: inherit;
6 | font-size: 100%;
7 | }
8 |
9 | body {
10 | background: #233142;
11 | font-family: helvetica, arial, sans-serif;
12 | font-size: 13px;
13 | color: #333333;
14 | line-height: 1;
15 | }
16 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import Header from './Header.jsx';
5 |
6 | const App = () => {
7 | return (
8 |
9 |
10 |
Some activities should be here
11 |
12 | );
13 | };
14 |
15 | ReactDOM.render(, document.getElementById('app'));
16 |
17 | export default App;
18 |
--------------------------------------------------------------------------------
/src/css/app.css:
--------------------------------------------------------------------------------
1 | #app {
2 | position: absolute;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 | left: 0;
7 | top: 0;
8 | right: 0;
9 | bottom: 0;
10 | }
11 |
12 | #app .container {
13 | width: 376px;
14 | height: 666px;
15 | z-index: 100;
16 |
17 | background: white;
18 | border-radius: 3px;
19 | box-shadow: 0 0 5px 0 rgba(0, 0, 0, .9);
20 | }
21 |
22 | #app .container-view {
23 | padding: 20px;
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const HtmlWebPackPlugin = require('html-webpack-plugin');
2 |
3 | module.exports = {
4 | module: {
5 | rules: [
6 | {
7 | test: /\.html$/,
8 | use: [
9 | {
10 | loader: 'html-loader',
11 | options: { minimize: true }
12 | }
13 | ]
14 | },
15 | {
16 | test: /\.css$/,
17 | use: [ 'style-loader', 'css-loader' ]
18 | },
19 | {
20 | test: /\.(js|jsx)$/,
21 | exclude: /node_modules/,
22 | use: {
23 | loader: 'babel-loader'
24 | }
25 | }
26 | ]
27 | },
28 | plugins: [
29 | new HtmlWebPackPlugin({
30 | template: "./public/index.html",
31 | filename: "./index.html"
32 | })
33 | ]
34 | };
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend-test-react",
3 | "version": "1.0.0",
4 | "description": "Technical test for Frontend Engineer position at Aircall",
5 | "main": "index.js",
6 | "repository": "https://github.com/aircall/frontend-test-react.git",
7 | "author": "Xavier Durand ",
8 | "license": "MIT",
9 | "private": false,
10 | "scripts": {
11 | "start": "webpack-dev-server --mode development --open",
12 | "build": "webpack --mode production"
13 | },
14 | "dependencies": {
15 | "react": "^16.3.1",
16 | "react-dom": "^16.3.1"
17 | },
18 | "devDependencies": {
19 | "babel-core": "6.26.*",
20 | "babel-loader": "7.1.*",
21 | "babel-preset-env": "1.7.0",
22 | "babel-preset-react": "6.24.*",
23 | "css-loader": "2.1.*",
24 | "html-loader": "0.5.*",
25 | "html-webpack-plugin": "3.2.*",
26 | "style-loader": "0.23.*",
27 | "webpack": "4.29.*",
28 | "webpack-cli": "3.2.*",
29 | "webpack-dev-server": "3.1.*"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [aircall.io](https://aircall.io) - Frontend technical test
2 |
3 | **This test is now deprecated. Please refer to [this one](https://github.com/aircall/frontend-hiring-test/blob/master/README.md) instead.**
4 |
5 | This test is a part of our hiring process at Aircall for [the Frontend Developer position](https://jobs.lever.co/aircall/c0fdd41e-a2a1-408d-ad08-890153518587). It should take you between 3 and 6 hours depending on your experience.
6 |
7 | **Feel free to apply! Drop us a line with your LinkedIn/GitHub/Twitter at jobs@aircall.io**
8 |
9 | ## Summary
10 |
11 | The goal of this test is to make you code a small ReactJS app. We have prepared a skeleton app for you, but please change whatever you want (CSS files, HTML structure, JS structure...).
12 |
13 | The app will have two different components:
14 | - **Activity Feed** - simple list of calls
15 | - **Activity Detail** - detail of a call
16 |
17 | Show us what you can do in 6 hours top :) Don't spend too much time on designing your app, our design team will hate it anyway.
18 |
19 | **Bonus:** the final user should be able to archive a call. The call will no longer be displayed on the Activity Feed. Please code that only if you have extra time.
20 |
21 |
22 | To give you an idea, here what our app looks like:
23 |
24 |
25 | 
26 |
27 | ## Installation
28 |
29 | We're using [yarn](https://yarnpkg.com) here:
30 |
31 | ```
32 | yarn install
33 | yarn start
34 | ```
35 |
36 | ## API documentation
37 |
38 | ### Routes
39 |
40 | Here is the API address: https://aircall-job.herokuapp.com.
41 |
42 | As you can see, it's hosted on a free Heroku server, which means that the first time you will fetch the API, it will take few seconds to answer.
43 |
44 | - **GET** - https://aircall-job.herokuapp.com/activities: get calls to display in the Activity Feed
45 | - **GET** - https://aircall-job.herokuapp.com/activities/:id: retrieve a specific call details
46 | - **POST** - https://aircall-job.herokuapp.com/activities/:id: update a call. The only field updatable is `is_archived (bool)`. You'll need to send a JSON in the request body:
47 | ```
48 | {
49 | is_archived: true
50 | }
51 | ```
52 | - **GET** - https://aircall-job.herokuapp.com/reset: Reset all calls to initial state (usefull if you archived all calls).
53 |
54 | ### Call object
55 |
56 | - **id** - unique ID of call
57 | - **created_at** - creation date
58 | - **direction** - `inbound` or `outbound` call
59 | - **from** - caller's number
60 | - **to** - callee's number
61 | - **via** - Aircall number used for the call
62 | - **duration** - duration of a call (in seconds)
63 | - **is_archived** - call is archived or not
64 | - **call_type** - can be a `missed`, `answered` or `voicemail` call.
65 |
66 |
67 |
68 | ## Submission
69 |
70 | Fork this repository and send us a pull request. We'll review it and get back to you in order to talk about your code!
71 |
72 | Contact us at jobs@aircall.io if you need more details.
73 |
--------------------------------------------------------------------------------
/src/Header.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Header = () => {
4 | return (
5 |
6 |
21 |
22 | );
23 | };
24 |
25 | export default Header;
26 |
--------------------------------------------------------------------------------