Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Aircall test - Frontend & API #25

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"presets": ["env", "react"]
"presets": ["@babel/preset-react", "@babel/preset-typescript"]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
dist
yarn-error.log
*.css.d.ts
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"arrowParens": "always"
}
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 1.0.0 (2020-01-13)


### Features

* **archive:** allow to archive call ([3bd9a66](https://github.com/aircall/frontend-test/commit/3bd9a666d8a3c86d504b860239c11e6b50b2df8c))
* **detail:** add routed detail component ([441369b](https://github.com/aircall/frontend-test/commit/441369bbf0b0ec6470e2f35809aacb286b6b7b50))
* **feed:** add activity feed list component ([4ee4b5b](https://github.com/aircall/frontend-test/commit/4ee4b5b3b3a0eab34f3b9f2438927426187d8910))



70 changes: 54 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,68 @@
"name": "frontend-test-react",
"version": "1.0.0",
"description": "Technical test for Frontend Engineer position at Aircall",
"main": "index.js",
"repository": "https://github.com/aircall/frontend-test-react.git",
"main": "index.tsx",
"repository": "https://github.com/aircall/frontend-test.git",
"author": "Xavier Durand <jobs@aircall.io>",
"license": "MIT",
"private": false,
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
"format": "prettier --write '**/*.+(ts|tsx|css)'",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
"build": "webpack --mode production",
"preversion": "npm run changelog",
"api-doc": "redoc-cli bundle spec/openapi.yml --output spec/index.html",
"api-lint": "spectral lint spec/openapi.yml",
"api-mock": "prism mock spec/openapi.yml --dynamic",
"api-types": "dtsgen --out src/context/api.d.ts spec/openapi.yml && echo 'export = Components;' >> src/context/api.d.ts"
},
"lint-staged": {
"*.+(ts|tsx|css)": [
"prettier --write",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"dependencies": {
"react": "^16.3.1",
"react-dom": "^16.3.1"
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-intl": "^3.9.3",
"react-router-dom": "^5.1.2",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^0.88.2"
},
"devDependencies": {
"babel-core": "6.26.*",
"babel-loader": "7.1.*",
"babel-preset-env": "1.7.0",
"babel-preset-react": "6.24.*",
"css-loader": "2.1.*",
"html-loader": "0.5.*",
"html-webpack-plugin": "3.2.*",
"style-loader": "0.23.*",
"webpack": "4.29.*",
"webpack-cli": "3.2.*",
"webpack-dev-server": "3.1.*"
"@babel/core": "^7.8.0",
"@babel/preset-react": "^7.8.0",
"@babel/preset-typescript": "^7.8.0",
"@stoplight/prism-cli": "^3.2.3",
"@stoplight/spectral": "^5.0.0",
"@types/react-dom": "^16.9.4",
"@types/react-router-dom": "^5.1.3",
"babel-loader": "^8.0.6",
"conventional-changelog-cli": "^2.0.31",
"css-loader": "^3.4.2",
"css-modules-typescript-loader": "^4.0.0",
"dtsgenerator": "^2.3.2",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"husky": "^3.1.0",
"lint-staged": "^9.5.0",
"mini-css-extract-plugin": "^0.9.0",
"prettier": "^1.19.1",
"react-svg-loader": "^3.0.3",
"redoc-cli": "^0.9.5",
"style-loader": "^1.1.2",
"webpack": "^4.41.5",
"webpack-bundle-analyzer": "^3.6.0",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1",
"webpack-pwa-manifest": "^4.1.1",
"workbox-webpack-plugin": "^4.3.1"
}
}
16 changes: 13 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@
<html lang="en">
<head>
<title>Aircall Phone</title>

<link rel="icon" href="https://cdn.aircall.io/icos/favicon.ico" />
<meta charset="utf-8">
<meta property="description" name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#2AC420"/>
<meta property="description" name="description" content="Aircall activity feed">
</head>
<body>
<div id="app"></div>
<div id="app">
<noscript>
<section style="background-color:#fff;border-radius:3px;text-align:center;font-size:2em;padding:1em;">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSzPKk73Uvhe6rTB5U5Fi5ms-in0aC_JMrz8xwp8AtBlOw3ns09&s"/>
<p>This application requires Javascript,<br>it seems it's disabled on your browser 😢.</p>
<p>Please visit <a href="https://aircall.io/">Aircall</a> website to discover what you are missing!</p>
</section>
</noscript>
</div>
</body>
</html>
349 changes: 349 additions & 0 deletions spec/index.html

Large diffs are not rendered by default.

250 changes: 250 additions & 0 deletions spec/openapi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@

openapi: 3.0.2

info:
title: Aircall activities
version: 1.0.0
description: An API to list & archive inbound & outbound call activities.
contact:
email: api@aricall.io

servers:
- url: https://aircall-job.herokuapp.com
description: Test free heroku instance
- url: http://127.0.0.1:4010
description: Local Prism mock

tags:
- name: Activity
- name: Archive

paths:
/activities:
get:
summary: Activities
description: List inbound & outbound call activities.
operationId: getActivities
tags:
- Activity
responses:
'200':
description: Activities list.
content:
application/json:
schema:
$ref: '#/components/schemas/Activities'
examples:
Activity:
$ref: '#/components/examples/Activities'
/activities/{id}:
parameters:
- $ref: '#/components/parameters/ActivityId'
get:
summary: Activity
description: Get a call activity by Id.
operationId: getActivity
tags:
- Activity
responses:
'200':
description: An activity.
content:
application/json:
schema:
$ref: '#/components/schemas/Activity'
examples:
Activity:
$ref: '#/components/examples/Activity'
post:
summary: Archive activity
description: Set call activity archived status.
operationId: archiveActivity
tags:
- Activity
- Archive
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Activity'
examples:
Activity:
$ref: '#/components/examples/ArchiveActivity'
responses:
'200':
description: An activity.
content:
application/json:
schema:
$ref: '#/components/schemas/Activity'
examples:
Activity:
$ref: '#/components/examples/ArchivedActivity'
/reset:
get:
summary: Reset archives
description: Reset archived status of all call activities.
operationId: reset
tags:
- Activity
- Archive
responses:
'200':
description: Done.
content:
application/json:
schema:
type: object
required:
- message
properties:
message:
type: string
enum:
- done
examples:
Done:
value: {
"message": "done"
}

components:

parameters:

ActivityId:
name: id
description: Activity Id.
in: path
required: true
schema:
$ref: '#/components/schemas/ActivityId'

schemas:

ActivityId:
type: number
format: int64
minimum: 1
description: An activity Identifier.
example: 7834
x-faker: random.number
readOnly: true

ActivityIsArchived:
description: Is this activity archived.
type: boolean
default: false

Activity:
type: object
description: An inbound or outbound call activity.
required:
- id
- created_at
- direction
- from
- to
- via
- duration
- is_archived
- call_type
properties:
id:
$ref: '#/components/schemas/ActivityId'
created_at:
description: Creation date of the activity in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
type: string
format: date-time
x-faker: date.recent
readOnly: true
direction:
description: Inbound or Outbound call activity.
type: string
enum:
- inbound
- outbound
readOnly: true
from:
description: Person who called, name or phone number.
x-faker: phone.phoneNumber
type: string
readOnly: true
to:
description: Person who was called, name or phone number.
x-faker: name.findName
type: string
readOnly: true
via:
description: Name of the phoning plateform used.
type: string
x-faker: company.companyName
readOnly: true
duration:
description: Activity duration in seconds.
type: string
x-faker: random.number
readOnly: true
is_archived:
$ref: '#/components/schemas/ActivityIsArchived'
call_type:
description: Type of call activity.
type: string
enum:
- answered
- missed
- voicemail
readOnly: true

Activities:
type: array
uniqueItems: true
items:
$ref: '#/components/schemas/Activity'

examples:

Activity:
value: {
"id": 7834,
"created_at": "2018-04-19T09:38:41.000Z",
"direction": "outbound",
"from": "Pierre-Baptiste Béchu",
"to": "06 46 62 12 33",
"via": "NYC Office",
"duration": "120",
"is_archived": false,
"call_type": "missed"
}

ArchivedActivity:
value: {
"id": 7834,
"created_at": "2018-04-19T09:38:41.000Z",
"direction": "outbound",
"from": "Pierre-Baptiste Béchu",
"to": "06 46 62 12 33",
"via": "NYC Office",
"duration": "120",
"is_archived": true,
"call_type": "missed"
}

Activities:
value: [{
"id": 7834,
"created_at": "2018-04-19T09:38:41.000Z",
"direction": "outbound",
"from": "Pierre-Baptiste Béchu",
"to": "06 46 62 12 33",
"via": "NYC Office",
"duration": "120",
"is_archived": false,
"call_type": "missed"
}]

ArchiveActivity:
value: {
"is_archived": true
}
Loading