# Упрощённое тестовое задание Front-End
Здесь находится описание тестового задания на позицию Front-End-разработчика в KazanExpress.\
Если вы нашли его случайно - попробуйте сделать! Авось и вас к себе возьмём.
Задание разбито на подзадачи.
## 1. Bug.
Есть абстрактное приложение с 1 компонентом. В текущей реализации есть несколько проблем. Нужно найти каждую проблему и описать, почему это проблема. Так же необходимо предоставить рабочее решение и описать как минимум еще 2 варианта решения. Требования: компонент должен работать без `props` ("кинул" компонент на страницу с любой вложенностью элементов/компонентов и он работает).
Ссылка на CodeSandbox: https://codesandbox.io/s/wizardly-euclid-xmm1p
### Ожидаемое поведение:
Значение StartDate в TimeComponent должно быть таким же как и значение StartDate в корневом компоненте (App.vue) и быть:
* **new Date("10/11/1977")** - до срабатывания таймера внутри корневого компонента
* **new Date("10/11/2075")** - после срабатывания таймера внутри корневого компонента
### Реальное поведение:
Из-за того, что значение StartDate в TimerComponent обновлялись только 1 раз по истечению таймера объявленном в App.vue - возможные значения StartDate в TimerComponent были:
* **""** - до emit'а события "update-start-date"
* **new Date("10/11/2075")** - после emit'а события "update-start-date"
### Мое решение:
#### Идея:
Я решил избавиться от конструкции с подпиской на "update-start-date" event и обойтись только функциональностью provide/inject.
#### Проблемы, с которыми можно столкнуться:
По дефолту, provide/inject - [не реактивный](https://v3.vuejs.org/guide/component-provide-inject.html#working-with-reactivity), а значит что при изменении значения StartDate это самое изменение никак не отобразится в TimerComponent.
#### Как я решил эту проблему:
Можно сделать так, чтобы данные которые мы передаем при помощи функциональности provide были переданы by-reference, что является неким обходом отсутствия реактивности.
Для этого мы можем обернуть наш StartDate в объект reactiveData и любое изменение его аттрибутов будет замечено TimerComponent'ом.
#### Ссылка на решение:
https://codesandbox.io/s/focused-microservice-lblee
### Альтернативные решения:
* Использовать state manger для передачи данных между компонентами (vuex)
* Использовать computed property для передачи его дочерним компонентам
* Использовать [Vue Observable](https://vuejs.org/v2/api/#Vue-observable) для создания reactive objects
## 2. Refactor.
Задача: сохранить функциональность и провести рефактор.
*Опционально*: описать где и почему были внесены изменения.
Ссылка на CodeSandbox: https://codesandbox.io/s/admiring-black-niwj0
**За что зацепился:**
* Ненужный вызов события this.$emit("click", e);
* Опечатка в слове rippling, вместо этого написано reppling
**Что не смог 😞:**
В стилизацию решил не лезть, поэтому искал только в <script>
Так же у меня нет опыта в использовании TypeScript, а я подразумеваю что это задание в большенстве своем на то, чтобы explicitly указывать типизацию.
**Ссылка на результат:**
https://codesandbox.io/s/nifty-leftpad-h9psh
## 3. Feature.
Есть данные с бэка:
```js
const payload = {
type: "BOTTOM_BLOCK",
elements: {
button: {
type: "primary",
text: "Buy",
action: "buyProduct",
},
textField: {
text: "This is my text, my text is amazing!",
},
icon: {
value: "/* svg */"
},
},
};
```
Создать Proxy и "добавить" поле `elementsCount` которое возвращает количество элементов в поле `elements` (в данном примере пэйлоада результат будет `3`).
Описать как можно с помощью Proxy сделать поиск в глобальном скоупе и вызов функции, которая указана в поле `action` (если есть) при обращении к элементу вызовом функции. Иными словами, чейн `payload.elements.button()` запускал бы функцию `buyProduct` в глобальном скоупе.
*Опционально*: выводить кастомную ошибку, если поля `action` нет у элемента.
### Ссылка на решение:
https://jsbin.com/maxoyus/2/edit?js,console
### Результат предоставить в виде ссылки на `.md` файл в котором описаны решения и указаны ссылки на `jsbin/jsfiddle/codepen/codesandbox`