Skip to content

Commit 54e884c

Browse files
2 - Desafio
1 parent 976c199 commit 54e884c

File tree

10 files changed

+203
-18
lines changed

10 files changed

+203
-18
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"moment": "^2.22.2",
1515
"multer": "^1.4.1",
1616
"nunjucks": "^3.1.4",
17+
"nunjucks-date-filter": "^0.1.1",
1718
"pg": "^7.6.1",
1819
"sequelize": "^4.41.2",
1920
"session-file-store": "^1.2.0"

src/app/controllers/AvailableController.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ class AvailableController {
1919
})
2020

2121
const schedule = [
22-
'8:00',
23-
'9:00',
22+
'08:00',
23+
'09:00',
2424
'10:00',
2525
'11:00',
2626
'12:00',
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const { Appointment, User } = require('../models')
2+
const { Op } = require('sequelize')
3+
const moment = require('moment')
4+
5+
class ScheduleController {
6+
async index (req, res) {
7+
const { date } = req.query
8+
9+
const defaultDate = moment(parseInt(date || new Date().getTime()))
10+
11+
const appointments = await Appointment.findAll({
12+
include: [{ model: User, as: 'user' }],
13+
where: {
14+
provider_id: req.session.user.id,
15+
date: {
16+
[Op.between]: [
17+
defaultDate.startOf('day').format(),
18+
defaultDate.endOf('day').format()
19+
]
20+
}
21+
},
22+
order: [['date', 'ASC']]
23+
})
24+
25+
return res.render('schedule/index', { appointments, defaultDate })
26+
}
27+
}
28+
29+
module.exports = new ScheduleController()

src/app/models/Appointment.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ module.exports = (sequelize, DataTypes) => {
44
})
55

66
Appointment.associate = models => {
7-
Appointment.belongsTo(models.User, { foreignKey: 'user_id' })
8-
Appointment.belongsTo(models.User, { foreignKey: 'provider_id' })
7+
Appointment.belongsTo(models.User, { as: 'user', foreignKey: 'user_id' })
8+
Appointment.belongsTo(models.User, {
9+
as: 'provider',
10+
foreignKey: 'provider_id'
11+
})
912
}
1013

1114
return Appointment

src/app/views/appointments/create.njk

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,37 @@
1212
</div>
1313
<form action="/app/appointments/new/{{ provider.id}}" method="POST">
1414
<input type="text" class="flatpickr" placeholder="Escolha uma data">
15-
1615
<div id="hours"></div>
17-
1816
<button type="submit">Agendar</button>
19-
17+
<a href="/app/dashboard" class="btn btn-secondary">Voltar ao início</a>
2018
</form>
2119
</div>
2220

2321
<script type="text/javascript">
22+
const defaultDate = new Date()
23+
2424
flatpickr('.flatpickr', {
25-
minDate: new Date(),
25+
minDate: defaultDate,
26+
defaultDate: defaultDate,
2627
dateFormat: 'd/m/Y',
2728
locale: 'pt',
2829
onChange: function (date) {
29-
fetch(`/app/available/{{ provider.id }}?date=${date[0].getTime()}`).then(function (response) {
30-
response
31-
.text()
32-
.then(function (html) {
33-
document
34-
.getElementById('hours')
35-
.innerHTML = html
36-
})
37-
})
30+
getHours(date[0])
3831
}
3932
})
33+
34+
getHours(defaultDate)
35+
36+
function getHours(date) {
37+
fetch(`/app/available/{{ provider.id }}?date=${date.getTime()}`).then(function (response) {
38+
response
39+
.text()
40+
.then(function (html) {
41+
document
42+
.getElementById('hours')
43+
.innerHTML = html
44+
})
45+
})
46+
}
4047
</script>
4148
{% endblock %}

src/app/views/dashboard.njk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
</li>
1616
{% endfor %}
1717
</ul>
18+
{% if (user.provider === true) %}
19+
<a href="/app/schedule" class="btn btn-primary">Meus agendamentos</a>
20+
{% endif %}
21+
1822
<a href="/app/logout" class="logout">Sair</a>
1923
</div>
2024
{% endblock %}

src/app/views/schedule/index.njk

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{% extends "_layouts/default.njk" %}
2+
3+
{% block body %}
4+
<div class="content">
5+
<strong>Meus agendamentos</strong>
6+
7+
<div>
8+
<a href="/app/schedule" class="btn btn-primary">Hoje</a>
9+
<form action="/app/appointments/new/{{ provider.id}}" method="POST">
10+
<input type="text" class="flatpickr" placeholder="Escolha uma data">
11+
</form>
12+
</div>
13+
14+
{% if appointments.length %}
15+
<ul class="schedules">
16+
{% for appointment in appointments %}
17+
<li class="schedule {% if appointment.date | isAfter === false %}disabled{% endif %}">
18+
<strong>{{ appointment.date | date("HH:mm") }}</strong>
19+
<div>
20+
<img src="/files/{{appointment.user.avatar}}" alt="Avatar">
21+
<strong>{{ appointment.user.name }}</strong>
22+
</div>
23+
</li>
24+
{% endfor %}
25+
</ul>
26+
{% else %}
27+
<span align="center">Nenhum agendamento marcado!</span>
28+
{% endif %}
29+
30+
<a href="/app/dashboard" class="btn btn-secondary">Voltar ao início</a>
31+
32+
</div>
33+
34+
<script type="text/javascript">
35+
flatpickr('.flatpickr', {
36+
minDate: new Date(),
37+
defaultDate: new Date('{{defaultDate}}'),
38+
dateFormat: 'd/m/Y',
39+
locale: 'pt',
40+
onChange: function (date) {
41+
window
42+
.location
43+
.assign(`/app/schedule?date=${date[0].getTime()}`);
44+
}
45+
})
46+
</script>
47+
48+
{% endblock %}

src/public/styles.css

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,88 @@ ul.providers {
295295
background-color: #7159c1 !important;
296296
border-color: #634dac !important;
297297
}
298+
299+
.btn-add-plus {
300+
width: 28px;
301+
height: 28px;
302+
padding: 6px 10px;
303+
}
304+
305+
.btn {
306+
width: 100%;
307+
height: 40px;
308+
display: flex;
309+
justify-content: center;
310+
align-items: center;
311+
border-radius: 4px;
312+
font-weight: bold;
313+
font-size: 14px;
314+
border: 0;
315+
margin-top: 5px;
316+
margin-bottom: 5px;
317+
text-decoration: none;
318+
cursor: pointer;
319+
}
320+
321+
.btn-primary {
322+
color: #fff;
323+
background: #7159c1;
324+
}
325+
326+
.btn-primary:hover,
327+
.btn-primary:focus {
328+
background: #634dac;
329+
}
330+
331+
.btn-secondary {
332+
color: #fff;
333+
background: #de6d6d;
334+
}
335+
336+
.btn-secondary:hover,
337+
.btn-secondary:focus {
338+
background: #c15858;
339+
}
340+
341+
.schedules {
342+
list-style: none;
343+
display: flex;
344+
flex-direction: column;
345+
}
346+
347+
.schedule {
348+
padding: 10px 20px;
349+
border-width: 0;
350+
border-radius: 4px;
351+
display: flex;
352+
align-items: center;
353+
justify-content: space-between;
354+
}
355+
356+
.schedule div {
357+
display: flex;
358+
align-items: center;
359+
}
360+
361+
.schedule img {
362+
width: 48px;
363+
height: 48px;
364+
border-radius: 50%;
365+
}
366+
367+
.schedule strong {
368+
margin-left: 15px;
369+
color: #444;
370+
}
371+
372+
.schedule.disabled {
373+
opacity: 0.3;
374+
}
375+
376+
.schedule:nth-child(even) {
377+
background-color: #f2f2f2;
378+
}
379+
380+
.schedule:last-child {
381+
margin-bottom: 20px;
382+
}

src/routes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const DashboardController = require('./app/controllers/DashboardController')
1313
const FileController = require('./app/controllers/FileController')
1414
const AppointmentController = require('./app/controllers/AppointmentController')
1515
const AvailableController = require('./app/controllers/AvailableController')
16+
const ScheduleController = require('./app/controllers/ScheduleController')
1617

1718
routes.use((req, res, next) => {
1819
res.locals.flashSuccess = req.flash('success')
@@ -36,5 +37,6 @@ routes.get('/app/appointments/new/:provider', AppointmentController.create)
3637
routes.post('/app/appointments/new/:provider', AppointmentController.store)
3738

3839
routes.get('/app/available/:provider', AvailableController.index)
40+
routes.get('/app/schedule', ScheduleController.index)
3941

4042
module.exports = routes

src/server.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const FileStore = require('session-file-store')(session)
55
const nunjucks = require('nunjucks')
66
const path = require('path')
77
const flash = require('connect-flash')
8+
const dateFilter = require('nunjucks-date-filter')
9+
const moment = require('moment')
810

911
class App {
1012
constructor () {
@@ -33,12 +35,16 @@ class App {
3335
}
3436

3537
views () {
36-
nunjucks.configure(path.resolve(__dirname, 'app', 'views'), {
38+
const config = nunjucks.configure(path.resolve(__dirname, 'app', 'views'), {
3739
watch: this.isDev,
3840
express: this.express,
3941
autoescape: true
4042
})
4143

44+
config.addFilter('date', dateFilter)
45+
46+
config.addFilter('isAfter', date => moment(date).isAfter(moment()))
47+
4248
this.express.use(express.static(path.resolve(__dirname, 'public')))
4349
this.express.set('view engine', 'njk')
4450
}

0 commit comments

Comments
 (0)