
Populate the database
(Use git checkout 5.seed
to catch up with the class)
Now that we have our modules, let’s connect them all together?
Run this command to get the seed files:
git merge origin/seeds
Add this line to priv/repo/seeds.exs
run the seed file:
Fawkes.Schedule.Seed.perform()
Let’s seed our database:
mix run priv/repo/seeds.exs
Querying for data
(Use git checkout 5a.querydata
to catch up with the class)
When we load the schedule, we want to load the talk, slot, location, and category. Let’s open lib/fawkes/schedule/schedule.ex
. First thing we want to do add the ability to query. So import in Ecto.Query
on line 4.
import Ecto.Query
We’re going to load all the talks through the slots. Go to the function list_schedule_slots
(maybe line 126). We want to say load all the event and talks. For all the talks, list the slot, speakers, categories, audience, and location.
def list_schedule_slots do
Slot
|> preload([:event, talks: [:slot, :speakers, :categories, :audience, :location]])
|> order_by(asc: :start_time)
|> Repo.all()
|> Enum.group_by(&get_day/1)
end
defp get_day(slot) do
Timex.beginning_of_day(slot.start_time)
end
Now, we need to add a shared view to help with formatting the layout. Create a filed called lib/fawkes_web/views/shared_view.ex
. Add this code:
defmodule FawkesWeb.SharedView do
use FawkesWeb, :view
def full_name(people) when is_list(people) do
people
|> Enum.map(&full_name/1)
|> Enum.join(" && ")
end
def full_name(person) do
person.first <> " " <> person.last
end
end
Finally, let’s update our layout. Open lib/fawkes_web/templates/slot/index.html.eex
, and replace the code with this:
<div class="talk-index">
<div class="section-white">
<div class="container">
<div class="d-flex justify-content-center align-items-center dates">
<i class="fas fa-arrow-left"></i>
<%= for date <- conference_dates() do %>
<div class="card">
<div class="card-body">
<a href="/schedule_slots?date=<%= Timex.format!(date, "%Y-%m-%d", :strftime)%>">
<div class="dates__name smalltext"><%= Timex.format!(date, "%a", :strftime) %></div>
<div class="dates__number"><%= Timex.format!(date, "%e", :strftime) %></div>
</a>
</div>
</div>
<% end %>
<i class="fas fa-arrow-right"></i>
</div>
<div class="d-flex justify-content-center talk-index__tab">
<a href="/schedule_slots" class="talk-tab__link talk-tab__link-active"><h4 class="subheader">Full Schedule</h4></a>
<%= if @conn.assigns[:current_user] do %>
<a href="/agenda" class="talk-tab__link"><h4 class="subheader">My Agenda</h4></a>
<% end %>
</div>
</div>
</div>
<div class="container schedule">
<p class="alert alert-info" role="alert"></p>
<p class="alert alert-danger" role="alert"></p>
<%= for {date, slots} <- @schedule_slots do %>
<h2 class="schedule__date"><%= Timex.format!(date, "%A %m/%d/%y", :strftime)%></h2>
<%= for slot <- slots do %>
<div class="card">
<div class="card-header">
<h4 class="subheader schedule__time">
<%= Timex.format!(slot.start_time, "%-I:%M %p", :strftime)%> - <%= Timex.format!(slot.end_time, "%-I:%M %p", :strftime) %>
</h4>
</div>
<div class="card-body">
<%= if slot.event do %>
<h3 class="gray"><%= slot.event.name %></h3>
<% else %>
<%= for talk <- slot.talks do %>
<div class="schedule__talk">
<div class="float-right schedule__talk-link">
<i class="fas fa-angle-right"></i>
</div>
<a href="/talks/<%= talk.id %>">
<h3 class="schedule__talk-title">
<%= talk.title %>
</h3>
</a>
<div class="schedule__details">
<%= FawkesWeb.SharedView.full_name(talk.speakers) %> | <%= talk.location.name %>
</div>
<p class="icons">
<button class="btn talk__audience"><%= talk.audience.name %></button>
<%= for category <- talk.categories do %>
<%= if category.icon_url do %>
<img src="<%= category.icon_url %>" alt="<%= category.name %>">
<% else %>
<button class="btn talk__category">
<%= category.name %>
</button>
<% end %>
<% end %>
</p>
<%= if @conn.assigns[:current_user] do %>
<div class="schedule__action" data-talk-id="<%= talk.id %>">
<div class="add-to-schedule">
<i class="far fa-calendar-check"></i>
ADD TO AGENDA
</div>
<div class="remove-from-schedule" style="display: none">
<i class="far fa-trash-alt"></i>
REMOVE FROM AGENDA
</div>
</div>
<% end %>
</div>
<% end %> <!-- end for loop -->
<% end %> <!-- end if statement -->
</div>
</div>
<% end %>
<% end %>
</div>
</div>
<%= if @conn.assigns[:current_user] do %>
<script>
$(document).ready(function() {
$('.add-to-schedule').click(function(event) {
var parent = $(this).parent();
var talkId = parent.data('talk-id');
var data = { user_id: <%= @conn.assigns[:current_user].id %>, talk_id: talkId}
$.post( '/api/users_talks', data)
.done(function( data ) {
console.log(data.data.id);
console.log(parent.find('.remove-from-schedule'));
parent.find('.add-to-schedule').hide();
parent.find('.remove-from-schedule').data('user-talk-id', data.data.id).show();
});
})
$('.remove-from-schedule').click(function(event) {
var parent = $(this).parent();
var id = $(this).data('user-talk-id');
$.ajax({
url: '/api/users_talks/' + id,
type: 'DELETE',
success: function(result) {
parent.find('.add-to-schedule').show();
parent.find('.remove-from-schedule').hide();
}
});
});
});
</script>
<% end %>
Restart your server. Press Cmd
+ c
to quit. Then run:
mix phx.server
Exercise #1: Load speakers
(Use git checkout 5b.load_speaker
to catch up with the class)
- In the
lib/fawkes/schedule/schedule.ex
, find the functionlist_profiles
. Change it tolist_speakers
. - It should preload
talk
-
Open
lib/fawkes_web/controllers/speaker_controllers.ex
, update theindex
function to reference speakers instead of profile. The code should look like this:def index(conn, _params) do speakers = Schedule.list_speakers() render(conn, "index.html", speakers: speakers) end
-
Let’s update the layout. Open
lib/fawkes_web/templates/speaker/index.html.eex
<div class="container speaker-index"> <h4 class="subheader">Speakers</h4> <div class="row attendee"> <%= for speaker <- @speakers do %> <div class="card col-xs-4"> <div class="card-body "> <img src="<%= speaker.image_url %>" class="rounded-circle"> <h4><%= link FawkesWeb.SharedView.full_name(speaker), to: speaker_path(@conn, :show, speaker) %></h4> <p><%= link speaker.talk.title, to: "/talks/#{speaker.talk.id}" %></p> </div> </div> <% end %> </div> </div>
- Go to http://localhost:4000/speakers, make sure the speaker loads
Exercise #2: Show talk
(Use git checkout 5c.show_talk
to catch up with the class)
- In
lib/fawkes/schedule/schedule.ex
, find the functionget_talk
. Preload slot, speakers, categories, audience, location - Open
lib/fawkes_web/templates/talk/show.html.eex
. Replace the content with this HTML:
<div class="container talk">
<div class="card section">
<p class="subtext"><%= Timex.format!(@talk.slot.start_time, "%-I:%M %p", :strftime)%> - <%= Timex.format!(@talk.slot.end_time, "%-I:%M %p", :strftime) %></p>
<h2><%= @talk.title %></h2>
<p class="smalltext"><strong>Location</strong>: <%= @talk.location.name %></p>
<p class="icons">
<button class="btn talk__audience"><%= @talk.audience.name %></button>
<%= for category <- @talk.categories do %>
<%= if category.icon_url do %>
<img src="<%= category.icon_url %>">
<% else %>
<button class="btn talk__category">
<%= category.name %>
</button>
<% end %>
<% end %>
</p>
<div class="add-to-schedule action">
<i class="far fa-calendar-check"></i>
ADD TO AGENDA
</div>
</div>
<hr/>
<h4 class="subheader">Speakers/Trainers</h4>
<%= for speaker <- @talk.speakers do %>
<div class="card speaker">
<div class="row card-body">
<div class="col-sm-3">
<img src="<%= speaker.image_url %>" class="rounded-circle">
</div>
<div class="col-sm-7 speaker__info">
<a href="/speakers/<%= speaker.id %>"<h4><%= FawkesWeb.SharedView.full_name(speaker) %></h4></a>
<div class="speaker__handle">
<i class="fab fa-github"></i> @<%= speaker.github %>
</div>
<div class="speaker__handle">
<i class="fab fa-twitter"></i> @<%= speaker.twitter %>
</div>
</div>
<div class="col-sm-1 speaker__link">
<a href="/speakers/<%= speaker.id%>"><i class="fas fa-chevron-right"></i></a>
</div>
</div>
</div>
<% end %>
<hr />
<h4 class="subheader">About the event</h4>
<p><%= raw(@talk.description) %></p>
<hr />
<h4 class="subheader">Checked in attendees</h4>
<div class="row attendee">
<%= for _ <- (1..10) do %>
<div class="card col-sm-3">
<div class="card-body">
<img src="https://lh3.googleusercontent.com/-fEyw5rjNaN0/VIcChZfCYDI/AAAAAAAADfA/OW_u5voliss/w426-h351/good-job-job-lucky-star-konata-izumi-good-anime-otakus-1375040667.jpg" class="rounded-circle">
<i class="fas fa-check-circle attendee__check"></i>
<h4>Name name</h4>
<div class="speaker__handle">
<i class="fab fa-github"></i> @TODO-GIthubhandle
</div>
<div class="speaker__handle">
<i class="fab fa-twitter"></i> @TODO-twitterhandle
</div>
</div>
</div>
<% end %>
</div>
</div>
Go to http://localhost:4000/talks/1 It should work.