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
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015"]
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
vendor
4 changes: 4 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [NC,L,QSA]
65 changes: 31 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
# A tarefa
Sua tarefa consiste em desenvolver uma API RESTful para manipular um determinado recurso. Deverá ser utilizado o framework Silex.

# Requisitos
A escolha do recurso deverá ser feita pelo desenvolvedor, atendendo apenas os requisitos mínimos abaixo:

* Deverá conter um ID
* Deverá conter pelo menos quatro propriedades (exemplos: nome, email, etc.)
* Deverá conter campos que armazenem as datas de criação e alteração do recurso

A API deverá atender às seguintes exigências:

* Listagem de todos os recursos
* Busca de um recurso pelo ID
* Criação de um novo recurso
* Alteração de um recurso existente
* Exclusão de um recurso
* Aceitar e retornar apenas JSON
* Deverá possuir algum método de autenticação para utilização de seus endpoints

# Ferramentas
* PHP
* Banco de dados MySQL
* Framework Silex

# Fluxo de desenvolvimento
1. Faça um fork deste repositório
2. Crie uma nova branch e nomeie-a com seu usuário do Github
3. Quando o desenvolvimento estiver concluído, faça um pull request

# Padrões de nomenclatura
1. Código fonte, nome do banco de dados, tabelas e campos devem estar em inglês

**Inclua no seu commit todos os arquivos necessários para que possamos testar o código.**
# Gerenciador simples de tarefas
Simples gerenciador de tarefas, inser um titulo, descrição, data e tempo necessário para a tarefa

# Tecnologias utilizadas para agilizar o desenvolvimento do teste
* composer
* npm
* gulp
* vue.js
* bootstrap
* jquery

# html, css e js
* npm i
* gulp
- gera todos os arquivos
* gulp watch
- assiste modificações em css js e html
* gulp js
- gera js
* gulp js:main
- gera o arquivo main.js com os vendors
* gulp css
- gera css
* gulp html
- gera os html

# Considerações
* Foi utilizado um sistem simples de autenticação, com a senha em md5. Somente para agilizar o teste
* Vue.js utilizado para modificação do frontend
* Bootstrap para agilizar layout
* O usuário e senha existente no dump é admin senha teste
21 changes: 21 additions & 0 deletions _controllers/Main.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
namespace Tgenuino;

use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

class Main {
// Simple login strategy
static function login(Request $request, \Silex\Application $app, $user, $pass) {
$sql = "SELECT * FROM users where user = ?";
$user = $app['db']->fetchAssoc($sql, [$user]);

if (($user) && ($user['password'] == md5($pass))) {
$app['session']->set('user', $user);
return true;
} else return false;
}
}

?>
49 changes: 49 additions & 0 deletions _controllers/Serasa.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
namespace Tgenuino;

use Symfony\Component\HttpFoundation\JsonResponse;

class Serasa {
function __construct($app) {
$this->app = $app;
}

function listWinners($request, $app) {
$results = [

];

for ($i = 0, $x=6; $i < $x; $i++) {
$results[] = [
'id' => $i,
'date' => '17/08',
'city' => 'São Paulo',
'state' => 'SP',
'no' => '053484058978-9'
];
}

return new JsonResponse(array(
'results' => $results
));
}

function listDoorPrizeDates($request, $app) {
$results = [

];

for ($i = 0, $x=20; $i < $x; $i++) {
$results[] = [
'id' => $i,
'date' => '17/08',
];
}

return new JsonResponse(array(
'results' => $results
));
}
}

?>
69 changes: 69 additions & 0 deletions _controllers/Task.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
namespace Tgenuino;

use Symfony\Component\HttpFoundation\JsonResponse;

class Task {
function __construct($app) {
$this->app = $app;
}

function listTasks($request, $app) {
$sql = [];
$values = [];

$sql[] = 'SELECT * FROM tasks';

if ($request->query->get('term')) {
$sql[] = 'WHERE title LIKE ?';
$values[] = '%'.$request->query->get('term').'%';
$sql[] = 'OR id = ?';
$values[] = $request->query->get('term');
}

$sql[] = 'ORDER BY date DESC,title';

$tasks = $this->app['db']->executeQuery(join($sql, ' '), $values);

return new JsonResponse(array(
'results' => $tasks->fetchAll()
));
}

function insertTask($request, $app) {
return $this->app['db']->insert('tasks', $request->request->all());
}

function updateTask($request, $app, $id) {
$data = [];
parse_str($request->getContent(), $data);
$data['updated_by'] = $app['session']->get('user')['id'];
$data['updated_at'] = \date("Y-m-d H:i:s");

$values = [];
$buildFields = [];

foreach ($data as $key => $value) {
if ($key == 'id') continue;

$values[] = $value;
$buildFields[] = $key . ' = ? ';
}

$sql = 'UPDATE tasks SET ' . join($buildFields, ',') . " WHERE id = ?";
$values[] = $id;

return $this->app['db']->executeUpdate($sql, $values);
}

function deleteTask($request, $app) {
$data = [];
parse_str($request->getContent(), $data);

$sql = 'DELETE FROM tasks WHERE id = ?';

return !!$this->app['db']->executeQuery($sql, [$data['id']]);
}
}

?>
53 changes: 53 additions & 0 deletions _routes/api.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
use Symfony\Component\HttpFoundation\Request;

$api = $app['controllers_factory'];

$api->get('/Serasa/listWinners/', function (Request $request, \Silex\Application $app) {
$classBuild = '\\Tgenuino\\Serasa';
$instance = new $classBuild($app);
return call_user_func_array([$instance, 'listWinners'], array($request, $app));
});

$api->get('/Serasa/listDoorPrizeDates/', function (Request $request, \Silex\Application $app) {
$classBuild = '\\Tgenuino\\Serasa';
$instance = new $classBuild($app);
return call_user_func_array([$instance, 'listDoorPrizeDates'], array($request, $app));
});

$api->get('/Task/', function (Request $request, \Silex\Application $app) {
$classBuild = '\\Tgenuino\\Task';
$instance = new $classBuild($app);
return call_user_func_array([$instance, 'listTasks'], array($request, $app));
})
->before($isAuth);

$api->get('/Task/{id}', function (Request $request, \Silex\Application $app, $id) {
$classBuild = '\\Tgenuino\\Task';
$instance = new $classBuild($app);
return call_user_func_array([$instance, 'getTaskById'], array($request, $app, $id));
})
->before($isAuth);

$api->put('/Task/{id}', function (Request $request, \Silex\Application $app, $id) {
$classBuild = '\\Tgenuino\\Task';
$instance = new $classBuild($app);
return call_user_func_array([$instance, 'updateTask'], array($request, $app, $id));
})
->before($isAuth);

$api->post('/Task/', function (Request $request, \Silex\Application $app) {
$classBuild = '\\Tgenuino\\Task';
$instance = new $classBuild($app);
return call_user_func_array([$instance, 'insertTask'], array($request, $app));
})
->before($isAuth);

$api->delete('/Task/', function (Request $request, \Silex\Application $app) {
$classBuild = '\\Tgenuino\\Task';
$instance = new $classBuild($app);
return call_user_func_array([$instance, 'deleteTask'], array($request, $app));
})
->before($isAuth);

return $api;
Empty file added _src/js/main.js
Empty file.
100 changes: 100 additions & 0 deletions _src/js/packages/home.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
var $home = new Vue({
el: '.page-home,#taskEditModal',
data: {
title: 'Tasks',
selectedTask: {},
tasks: []
},
methods: {
loadTasks: function () {
var _this = this;
var $term = $('#taskSearch').val();

_this.title = 'Loading Tasks...';

$.get('./api/Task', {term: $term}, function (r) {
_this.title = 'Tasks';
_this.tasks = r.results;
});
},

addTask: function(data) {
$.post('./api/Task/', data, function (r) {
$home.loadTasks();
});
},

openTask: function (id) {
var _this = this;
_this.selectedTask = _this.tasks.filter(i => i.id == id)[0];

$('#taskEditModal').modal('show');
},

deleteTask: function (id) {
var _this = this;
$.ajax({
method: 'DELETE',
url: './api/Task/',
data: {
id: id
},
success: function(r) {
if (r == 1) {
$('#taskEditModal').modal('hide');
$home.loadTasks();
} else alert('Whoops, looks like something went wrong;')
}
})
}
},
mounted: function () {
this.loadTasks();
},
});

$(document).on('click', '[data-action="edit-task"]', function (ev){
ev.preventDefault();
var itemId = $(this).attr('data-key');
$home.openTask(itemId);
});

$(document).on('click', '[data-action="delete-task"]', function (ev){
ev.preventDefault();
var $this = $(this);
var itemId = $(this).attr('data-key');
if (confirm('Remove task?')) {
$home.deleteTask(itemId);
}
});

$(document).on('submit', '#taskEditModal form', function (ev) {
ev.preventDefault();
var $this = $(this);
var id = $this.find('[name="id"]').val();

$.ajax({
method: 'PUT',
data: $this.serialize(),
url: './api/Task/' + id,
success: function (r) {
if (r == 1) {
$('#taskEditModal').modal('hide');
$home.loadTasks();
} else {
alert('Invalid data or no changes detected');
}
}
})
});

$(document).on('submit', '#formAddTask', function (ev) {
ev.preventDefault();
var $this = $(this);

$home.addTask($this.serialize());
});

$(document).on('keyup', '#taskSearch', function (ev) {
$home.loadTasks();
});
1 change: 1 addition & 0 deletions _src/js/packages/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$('#loginModal').modal('show');
Loading