VRFS-1667, VRFS-1729 implemented account session page, session detail page

This commit is contained in:
Bert Owen 2014-06-29 15:54:51 +02:00
parent d1288b3b71
commit 07d96d7a57
16 changed files with 757 additions and 155 deletions

View File

@ -220,7 +220,7 @@ module JamRuby
#query = query.where("public = false") unless !hide_private
query = query.where("music_sessions.band_id = '#{band_id}") unless band_id.nil?
query = query.where("music_sessions.genres like '%#{genre}%'") unless genre.nil?
query = query.where("music_sessionsgenres like '%#{genre}%'") unless genre.nil?
return query
end
@ -234,6 +234,20 @@ module JamRuby
query
end
def self.scheduled_rsvp user
MusicSession.where(%Q{music_sessions.id in (
select distinct(rs.music_session_id)
from rsvp_slots rs
where rs.id in (
select rrrs.rsvp_slot_id
from rsvp_requests rr
inner join rsvp_requests_rsvp_slots rrrs on rr.id = rrrs.rsvp_request_id
where rr.user_id = '#{user.id}'
)
)}
)
end
def self.create user, options
band = Band.find(options[:band]) unless options[:band].nil?
@ -521,6 +535,11 @@ module JamRuby
)
end
# retrieve pending RsvpRequests
def pending_rsvp_requests
RsvpRequest.index(self, nil, {status: 'pending'})
end
def recordings
Recording.where(music_session_id: self.id)
end

View File

@ -0,0 +1,314 @@
(function (context, $) {
"use strict";
context.JK = context.JK || {};
context.JK.AccountSessionDetail = function (app) {
var logger = context.JK.logger;
var rest = context.JK.Rest();
var sessionId = null;
var sessionData = null;
var $screen = null;
var $cancelRsvpBtn = null;
var $inviteOthersBtn = null;
var $sessionDetail = null;
var instrument_logo_map = context.JK.getInstrumentIconMap24();
var invitationDialog = null;
var LATENCY = {
GOOD : {description: "GOOD", style: "latency-green", min: 0.0, max: 20.0},
MEDIUM : {description: "MEDIUM", style: "latency-yellow", min: 20.0, max: 40.0},
POOR : {description: "POOR", style: "latency-red", min: 40.0, max: 10000000000.0},
UNREACHABLE: {description: "UNREACHABLE", style: "latency-grey", min: -1, max: -1},
UNKNOWN: {description: "UNKNOWN", style: "latency-grey", min: -2, max: -2}
};
function beforeShow(data) {
sessionId = data.id;
loadSessionData();
}
function afterShow(data) {
}
function inviteMusicians(e) {
e.preventDefault();
context.JK.app.layout.showDialog('select-invites');
}
function cancelRsvpRequest(rsvpId) {
var rsvpCancelDlg = new context.JK.RsvpCancelDialog(app, sessionData.id, rsvpId);
rsvpCancelDlg.initialize();
context.JK.app.layout.showDialog('rsvp-cancel-dialog');
}
function approveRsvpRequest(e) {
e.preventDefault();
var rsvpId = $(e.target).attr('request-id');
}
function events() {
$inviteOthersBtn.on('click', inviteMusicians);
$cancelRsvpBtn.on('click', function(e) {
e.preventDefault();
cancelRsvpRequest(sessionData.rsvpId);
});
$screen.find(".approveRsvpRequest").on('click', approveRsvpRequest);
$screen.find(".declineRsvpRequest").on('click', function(e){
e.preventDefault();
var rsvpId = $(e.target).attr('request-id');
cancelRsvpRequest(rsvpId);
});
}
function loadSessionData() {
rest.getSessionHistory(sessionId)
.done(renderSession)
.fail(app.ajaxError);
}
function renderSession(data) {
sessionData = data;
var hasPending = false;
var isOwner = false;
if (sessionData.user_id == context.JK.currentUserId) {
if (sessionData.pending_rsvp_requests.length > 0) {
hasPending = true;
}
if (hasPending)
sessionData.notification_msg = "You have new RSVPs to review and approve, see details.";
else
sessionData.notification_msg = "";
isOwner = true;
}
else {
$.each(sessionData.pending_rsvp_requests, function(request) {
if (request.user_id == context.JK.currentUserId) {
hasPending = true;
sessionData.rsvpId = request.id;
}
});
if (hasPending)
sessionData.notification_msg = "Your RSVP has not been processed by session organizer yet";
else
sessionData.notification_msg = "";
isOwner = false;
}
if (isOwner) {
$inviteOthersBtn.show();
$cancelRsvpBtn.hide();
}
else if (hasPending) {
$inviteOthersBtn.hide();
$cancelRsvpBtn.show();
}
var pendingRsvpHtml = generatePendingRsvps();
var sessionRsvpsHtml = generateSessionRsvps();
var sessionNeededHtml = generateSessionNeeded();
var sessionInvitedHtml = generateSessionInvited();
var sessionPropertiesHtml = generateSessionProperties();
var template = context._.template(
$('#template-account-session-detail').html(),
{ has_pending: hasPending, is_owner: isOwner, notification_msg: sessionData.notification_msg,
pending_rsvps: pendingRsvpHtml, session_rsvps: sessionRsvpsHtml, still_needed: sessionNeededHtml,
invited_users: sessionInvitedHtml, session_properties: sessionPropertiesHtml},
{variable: 'data'}
);
$sessionDetail.html(template);
events();
}
function createLatency(user) {
var latencyStyle = LATENCY.UNREACHABLE.style, latencyDescription = LATENCY.UNREACHABLE.description
if (user.id === context.JK.currentUserId) {
latencyStyle = LATENCY.GOOD.style, latencyDescription = LATENCY.GOOD.description;
}
else {
var latency = user.latency;
console.log("latency = %o", latency);
if (!latency || latency === 1000) {
// 1000 is a magical number returned by new scoring API to indicate one or more people in the session have an unknown score
latencyDescription = LATENCY.UNKNOWN.description;
latencyStyle = LATENCY.UNKNOWN.style;
}
else {
if (latency <= LATENCY.GOOD.max) {
latencyDescription = LATENCY.GOOD.description;
latencyStyle = LATENCY.GOOD.style;
}
else if (latency > LATENCY.MEDIUM.min && latency <= LATENCY.MEDIUM.max) {
latencyDescription = LATENCY.MEDIUM.description;
latencyStyle = LATENCY.MEDIUM.style;
}
else {
latencyDescription = LATENCY.POOR.description;
latencyStyle = LATENCY.POOR.style;
}
}
}
return {
latency_style: latencyStyle,
latency_text: latencyDescription
};
}
function generatePendingRsvps() {
var resultHtml = "";
var rsvpHtml = "";
var instrumentLogoHtml = "";
var latencyHtml = "";
$.each(sessionData.pending_rsvp_requests, function(index, request) {
if (request.user_id != context.JK.currentUserId) {
if ("instrument_list" in request.user && request.user.instrument_list != null) {
$.each(request.user.instrument_list, function (index, instrument) {
var inst = '../assets/content/icon_instrument_default24.png';
if (instrument.id in instrument_logo_map) {
inst = instrument_logo_map[instrument.id].asset;
}
instrumentLogoHtml += '<img src="' + inst + '" width="24" height="24" />&nbsp;';
})
}
latencyHtml = context._.template($("#template-account-session-latency"),
createLatency(request.user), {variable: 'data'});
rsvpHtml = context._.template(
$("#template-account-pending-rsvp",
{user_id: request.user_id, avatar_url: request.user.avatar_url,
user_name: request.user.name, instruments: instrumentLogoHtml,
latency: latencyHtml, request_id: request.id},
{variable: 'data'})
);
resultHtml += rsvpHtml;
instrumentLogoHtml = "";
}
});
return resultHtml;
}
function generateSessionRsvps() {
var resultHtml = "";
var rsvpHtml = "";
var instrumentLogoHtml = "";
var latencyHtml = "";
$.each(sessionData.approved_rsvps, function(index, request) {
if ("instrument_list" in request) {
$.each(request.instrument_list, function(index, instrument) {
var inst = '../assets/content/icon_instrument_default24.png';
if (instrument.id in instrument_logo_map) {
inst = instrument_logo_map[instrument.id].asset;
}
instrumentLogoHtml += '<img src="' + inst + '" width="24" height="24" />&nbsp;';
});
}
latencyHtml = context._.template(
$("#template-account-session-latency").html(),
createLatency(request),
{variable: 'data'}
);
var avatar_url = request.resolved_photo_url;
rsvpHtml = context._.template(
$("#template-account-session-rsvp").html(),
{user_id: request.id, avatar_url: avatar_url,
user_name: request.name, instruments: instrumentLogoHtml,
latency: latencyHtml},
{variable: 'data'}
);
resultHtml += rsvpHtml;
instrumentLogoHtml = "";
});
return resultHtml;
}
function generateSessionNeeded() {
var resultHtml = "";
var slotHtml = "";
$.each(sessionData.open_slots, function(index, slot) {
var inst = '../assets/content/icon_instrument_default24.png';
if ("instrument_id" in slot) {
inst = instrument_logo_map[slot.instrument_id].asset;
}
slotHtml = context._.template(
$("#template-account-open-slot").html(),
{instrument_url: inst, instrument: slot.description,
proficiency: slot.proficiency_desc},
{variable: 'data'}
);
resultHtml += slotHtml;
});
return resultHtml;
}
function generateSessionInvited() {
var resultHtml = "";
var avatar_url = "";
$.each(sessionData.invitations, function(index, invitation) {
avatar_url = invitation.receiver_avatar_url;
resultHtml += context._.template(
$("#template-account-invited").html(),
{avatar_url: avatar_url, user_id: invitation.reciever_id},
{variable: 'data'}
);
});
return resultHtml;
}
function generateSessionProperties() {
var resultHtml = "";
resultHtml = context._.template(
$("#template-account-session-properties").html(),
sessionData,
{variable: 'data'}
);
return resultHtml;
}
function initialize(invitationDlg) {
var screenBindings = {
'beforeShow': beforeShow,
'afterShow': afterShow
};
app.bindScreen('account/sessionDetail', screenBindings);
$screen = $(".account-session-detail");
$inviteOthersBtn = $screen.find("#invite-others");
$cancelRsvpBtn = $screen.find("#cancel-rsvp");
$inviteOthersBtn.hide(); $cancelRsvpBtn.hide();
$sessionDetail = $screen.find("#account-session-detail-div");
invitationDialog = invitationDlg;
}
this.initialize = initialize;
this.beforeShow = beforeShow;
this.afterShow = afterShow;
return this;
};
})(window, jQuery);

View File

@ -5,6 +5,7 @@
context.JK = context.JK || {};
context.JK.AccountSessions = function (app) {
var logger = context.JK.logger;
var $sessions = null;
var rest = context.JK.Rest();
var userId;
var scheduledSessions = {};
@ -27,23 +28,51 @@
function cancelSession(e) {
e.preventDefault();
// var session_id = $(e.target).attr('data-id');
// rest.cancelSession({session_id: session_id})
// .done(function() {
// })
// .fail(app.ajaxError);
var session_id = $(e.target).attr('session-id');
var cancelSessionDlg = new context.JK.SessionCancelDialog(app, session_id);
cancelSessionDlg.initialize();
context.JK.app.layout.showDialog('session-cancel-dialog');
}
function detailSession(e) {
e.preventDefault();
var session_id = $(e.target).attr('session-id');
window.location = '/client#/account/sessionDetail/' + session_id;
}
function events() {
$(".session-cancel-button").on('click', cancelSession);
}
function appendSessions(template) {
$("#account-scheduled-sessions table tbody").replaceWith(template);
$sessions.find(".session-cancel-button").on('click', cancelSession);
$sessions.find(".session-detail-button").on('click', detailSession);
}
function populateSessions(sessionList) {
$.each(sessionList, function(index, session) {
var hasPending = false;
if (session.user_id == context.JK.currentUserId) {
if (session.pending_rsvp_requests.length > 0) {
hasPending = true;
}
if (hasPending)
session.notification_msg = "You have new RSVPs to review and approve, see details.";
else
session.notification_msg = "";
}
else {
$.each(session.pending_rsvp_requests, function(request) {
if (request.user_id == context.JK.currentUserId) {
hasPending = true;
}
});
if (hasPending)
session.notification_msg = "Your RSVP has not been processed by session organizer yet";
else
session.notification_msg = "";
}
scheduledSessions[session.id] = session;
});
@ -57,7 +86,7 @@
}
function renderAccountIdentity() {
rest.findScheduledSessions({})
rest.findScheduledRsvpSessions({})
.done(populateSessions)
.fail(app.ajaxError);
}
@ -73,12 +102,18 @@
'afterShow': afterShow
};
app.bindScreen('account/sessions', screenBindings);
$sessions = $('.account-sessions');
events();
}
this.initialize = initialize;
this.beforeShow = beforeShow;
this.afterShow = afterShow;
$(document).on("sessionCancelEvent", function() {
location.reload();
});
return this;
};

View File

@ -131,6 +131,13 @@
});
}
function findScheduledRsvpSessions(query) {
return $.ajax({
type: "GET",
url: "/api/sessions/scheduled_rsvp?" + $.param(query)
});
}
function updateSession(id, newSession) {
return $.ajax('/api/sessions/' + id, {
type: "PUT",
@ -1179,6 +1186,7 @@
this.findActiveSessions = findActiveSessions;
this.findInactiveSessions = findInactiveSessions;
this.findScheduledSessions = findScheduledSessions;
this.findScheduledRsvpSessions = findScheduledRsvpSessions;
this.updateSession = updateSession;
this.getSessionHistory = getSessionHistory;
this.addSessionComment = addSessionComment;

View File

@ -2,39 +2,18 @@
"use strict";
context.JK = context.JK || {};
context.JK.SessionCancelDialog = function(app, sessionId, rsvpRequestId) {
context.JK.SessionCancelDialog = function(app, sessionId) {
var logger = context.JK.logger;
var rest = context.JK.Rest();
var $screen = null;
var dialogId = 'rsvp-cancel-dialog';
var $btnCancel = $("#btnCancelRsvp");
var dialogId = 'session-cancel-dialog';
var $btnCancel = null;
function beforeShow(data) {
console.log(sessionId);
}
function afterShow(data) {
rest.getSessionHistory(sessionId)
.done(function(response) {
if (response) {
$('.session-name', $screen).html(response.name);
$('.scheduled-start', $screen).html(response.scheduled_start);
if (response.recurring_mode !== null) {
$('.schedule-recurrence', $screen).html("Recurs " + response.recurring_mode + " on this day at this time");
}
}
})
.fail(function(xhr) {
});
}
function afterHide() {
}
function showDialog() {
app.layout.showDialog('rsvp-cancel-dialog');
}
function events() {
@ -43,31 +22,14 @@
e.preventDefault();
var error = false;
var cancelOption = $('input[name="cancel"]:checked', $screen).val();
rest.cancelRsvpRequest(sessionId, rsvpRequestId, cancelOption)
rest.cancelSession({session_id: sessionId})
.done(function(response) {
var comment = $.trim($('#txtComment', $screen).val());
if (comment.length > 0) {
rest.addSessionInfoComment(sessionId, comment)
.done(function(response) {
})
.fail(function(xhr) {
error = true;
$('.error', $screen).html("Unexpected error occurred while saving message (" + xhr.status + ")");
$('.error', $screen).show();
});
}
if (!error) {
app.layout.closeDialog(dialogId);
$btnCancel.trigger("rsvpCancelEvent");
$btnCancel.trigger("sessionCancelEvent");
}
})
.fail(function(xhr) {
$('.error', $screen).html("Unexpected error occurred while cancelling RSVP request (" + xhr.status + ")");
$('.error', $screen).show();
});
.fail(app.ajaxError);
});
}
@ -75,20 +37,17 @@
var dialogBindings = {
'beforeShow' : beforeShow,
'afterShow' : afterShow,
'afterHide': afterHide
'afterShow' : afterShow
};
app.bindDialog(dialogId, dialogBindings);
$screen = $('[layout-id="' + dialogId + '"]');
$btnCancel = $screen.find("#btnCancelSession");
events();
}
this.initialize = initialize;
this.showDialog = showDialog;
}
return this;
};
})(window,jQuery);

View File

@ -1,6 +1,7 @@
@import 'common.css.scss';
.account-content-scroller,
.session-detail-scroller,
#account-identity-content-scroller {
.content-wrapper {
@ -241,24 +242,131 @@
}
}
/** account sessions */
.account-sessions {
table.generaltable td {
vertical-align:middle;
.sessions-header {
width: 100%;
margin: 10px 0px;
.sessions-caption h2 {
min-width: 165px;
color: #FFFFFF;
font-size: 23px;
font-weight: 400;
}
}
/** account session detail */
.account-session-detail {
.dark-box {
background-color: #202020;
padding: 8px;
margin-top: 5px;
}
#account-session-detail-div {
.box-header {
margin: 5px 0px;
h2 {
width: 65%;
font-weight: normal;
}
#latency-header {
width: 20%;
line-height: 30px;
vertical-align: middle;
font-size: 11px;
text-align: center;
}
}
table.rsvp-table {
margin-top: 6px;
tbody tr td {
padding-right: 10px;
}
}
.latency {
font-size: 15px;
height: 16px;
padding-left: 4px;
width: 100%;
}
#session-rsvps, #still-needed, #invited-users {
margin-bottom: 5px;
}
.musician-left {
width: 20%;
float: left;
margin-top: 8px;
}
.musician-right {
width: 75%;
float: right;
}
.session-properties-left {
width: 20%;
float: left;
font-weight: strong;
margin-bottom: 10px;
}
.session-properties-right {
width: 75%;
float: left;
margin-bottom: 10px;
}
}
}
/** account sessions */
.account-sessions {
div#account-scheduled-sessions {
position: relative;
display: block;
overflow: auto;
margin: 0px;
height: 340px;
height: 100%;
}
table.generaltable {
background-color: inherit;
border: none;
td {
vertical-align:middle;
font-size: 15px;
border: none;
}
}
table.generaltable td {
vertical-align:middle;
}
.session-left {
width: 20%;
margin-bottom: 10px;
float: left;
}
.session-right {
width: 80%;
margin-bottom: 10px;
float: right;
}
}
}
#session-cancel-dialog {
.cancel-description {
width: 90%;
font-size: 15;
padding: 5px;
}
}

View File

@ -87,6 +87,10 @@ class ApiMusicSessionsController < ApiController
@music_sessions = MusicSession.scheduled(current_user)
end
def scheduled_rsvp
@music_sessions = MusicSession.scheduled_rsvp(current_user)
end
def create
@music_session = MusicSession.create(current_user, params)

View File

@ -0,0 +1,3 @@
object @music_sessions
extends "api_music_sessions/show_history"

View File

@ -79,12 +79,15 @@ else
attributes :id, :sender_id, :receiver_id
node do |invitation|
{ latency: user_score(invitation.receiver.id) }
{
latency: user_score(invitation.receiver.id),
receiver_avatar_url: invitation.receiver.resolved_photo_url
}
end
}
child({:approved_rsvps => :approved_rsvps}) {
attributes :id, :photo_url, :first_name, :last_name, :instrument_list
attributes :id, :photo_url, :first_name, :last_name, :instrument_list, :name, :resolved_photo_url
node do |user|
{ latency: user_score(user.id), name: user.name }
@ -99,6 +102,18 @@ else
attributes :id, :email, :photo_url
}
child({:pending_rsvp_requests => :pending_rsvp_requests}) {
attributes :id, :email, :photo_url, :user_id
child({:user => :user}) {
attributes :id, :photo_url, :name, :first_name, :last_name, :instrument_list
node do |user|
{ latency: user_score(user.id), name: user.name }
end
}
}
child(:active_music_session => :active_music_session) {
attributes :claimed_recording_initiator_id, :track_changes_counter

View File

@ -29,7 +29,7 @@
<div class="account-left">
<h2>sessions: </h2>
</div>
<div class="account-mid">
<div class="account-mid sessions">
</div>
<div class="right">
<a id="account-schduled-sessions-link" href="#" class="button-orange">UPDATE</a>

View File

@ -0,0 +1,162 @@
/ Account Sessions Dialog
%div{'layout' => 'screen', 'layout-id' => 'account/sessionDetail', id: 'account-session-detail', 'layout-arg' => 'id', class: 'screen secondary'}
.content-head
.content-icon
= image_tag "content/icon_account.png", :width => 27, :height => 20
%h1 my account
= render "screen_navigation"
/ session detail area
.content-body
.content-body-scroller.session-detail-scroller#session-detail-content-scroller
.content-wrapper.account-session-detail
.sessions-header
.left.sessions-caption
%h2 session details:
.right
%a.button-orange{href: "#", id: 'cancel-rsvp'} Cancel RSVP
%a.button-orange{href: "#", id: 'invite-others'} Invite Others
.clearall
#account-session-detail-div
.clearall
/ end content scrolling area
%script{type: 'text/template', id: 'template-account-session-detail'}
= "{% if (data.has_pending) { %}"
.pending-rsvps.dark-box
.box-header
%h2.left
RSVPs
.right
{{data.notification_msg}}
.clearall
#pendingRSVPs
{{data.pending_rsvps}}
= "{% } %}"
.session-musicians.dark-box
.box-header
%h2.left
Session Musicians
.clearall
#session-rsvps
.musician-left
RSVPs
.musician-right
{{data.session_rsvps}}
.clearall
#still-needed
.musician-left
Still Needed
.musician-right
%table.rsvp-table
%tbody
{{data.still_needed}}
.clearall
#invited-users
.musician-left
Invited
.musician-right
%table.rsvp-table
%tbody
%tr
{{data.invited_users}}
.clearall
.session-properties.dark-box
.box-header
%h2.left
Session Properties
.right
%a.button-orange{href: "#"} UPDATE
.clearall
#session-properties
{{data.session_properties}}
%script{type: 'text/template', id: 'template-account-pending-rsvp'}
.left
%table.rsvp-table
%tbody
%td
%a{href: "#", 'user-id' => "{{data.user_id}}", 'hoveraction' => "musician", class: 'avatar-tiny'}
%img{src: "{{data.avatar_url}}"}
%td
{{data.user_name}}
%td
{{data.instruments}}
%td
{{data.latency}}
.right
%a{href: "#", class: 'button-orange left', 'user-id' => "{{data.user_id}}"} PROFILE
%a{href: "#", class: 'button-orange left approveRsvpRequest', 'user-id' => "{{data.user_id}}", 'request-id' => "{{data.request_id}}"} APPROVE
%a{href: "#", class: 'button-orange left declineRsvpRequest', 'user-id' => "{{data.user_id}}", 'request-id' => "{{data.request_id}}"} DECLINE
.clearall
.clearall
%script{type: 'text/template', id: 'template-account-session-rsvp'}
.left
%table.rsvp-table
%tbody
%td
%a{href: "#", 'user-id' => "{{data.user_id}}", 'hoveraction' => "musician", class: 'avatar-tiny'}
%img{src: "{{data.avatar_url}}"}
%td
{{data.user_name}}
%td
{{data.instruments}}
%td
{{data.latency}}
.right
%a{href: "#", class: 'button-orange declineRsvpRequest'} CANCEL
.clearall
%script{type: 'text/template', id: 'template-account-session-properties'}
.session-properties-left Date/Time:
.session-properties-right
{{data.scheduled_start_time}}
.clearall.session-properties-left Genre:
.session-properties-right
{{data.genres}}
.clearall.session-properties-left Name:
.session-properties-right
{{data.name}}
.clearall.session-properties-left Description:
.session-properties-right
{{data.description}}
.clearall.session-properties-left Notation Files:
.session-properties-right
%table.rsvp-table
%tbody
%tr
= "{% _.each(data.music_notations, function(notation) { %}"
%td
%a{href: "/music_notations/{{notation.id}}"}
{{notation.file_name}}
= "{% }); %}"
{{data.notations}}
.clearall.session-properties-left Language:
.session-properties-right
{{data.language_description}}
.clearall.session-properties-left Access:
.session-properties-right
{{data.musician_access_description}} {{data.fan_access_description}}
.clearall.session-properties-left Legal
.session-properties-right
{{data.legal_policy}}
.clearall
%script{type: 'text/template', id: 'template-account-open-slot'}
%tr
%td{width: 24}
%img{src: "{{data.instrument_url}}"}
%td
%div{class: 'nowrap'}
{{data.instrument}} ({{data.proficiency}})
%script{type: 'text/template', id: 'template-account-invited'}
%td
%a{href: "#", 'user-id' => "{{data.user_id}}", 'hoveraction' => "musician", class: 'avatar-tiny'}
%img{src: "{{data.avatar_url}}"}
%script{type: 'text/template', id: 'template-account-session-latency'}
.latency{class: "{{data.latency_style}}"}
{{data.latency_text}}

View File

@ -1,80 +0,0 @@
<!-- Account Summary Dialog -->
<div layout="screen" layout-id="account/sessions" class="screen secondary" id="account-sessions">
<!-- header -->
<div class="content-head">
<!-- icon -->
<div class="content-icon">
<%= image_tag "content/icon_account.png", {:width => 27, :height => 20} %>
</div>
<!-- section head text -->
<h1>my account</h1>
<%= render "screen_navigation" %>
</div>
<!-- end header -->
<!-- sessions scrolling area -->
<div class="content-body">
<div id="account-sessions-content-scroller" class="content-body-scroller account-content-scroller">
<div class="content-wrapper account-sessions">
<br />
<div class="account-left w80 mb10">
<h2>scheduled sessions:</h2>
</div>
<div class="right mb10">
<a class="button-grey" href="javascript:history.go(-1)">BACK</a>
</div>
<br clear="all" />
<div id="account-scheduled-sessions">
<table class="generaltable f14" cellpadding="0" cellspacing="0">
<thead>
</thead>
<tbody>
</tbody>
</table>
</div>
<br clear="all" />
</div>
</div>
</div>
<!-- end content scrolling area -->
</div>
<script type="text/template" id="template-account-session">
<tbody>
{% for (var i = 0; i < data.sessions.length; i++) { %}
{% var session = data.sessions[i]; %}
<tr>
<td>
<div data-id="{{session.id}}">
<div class="left w20 mb5">Date/Time:</div>
<div class="right w80 mb5 ">
{{session.scheduled_start_time}} {{session.timezone_description}}
</div>
<br class="all"/>
<div class="left w20 mb5">Session:</div>
<div class="right w80 mb5">
{{session.name}}
</div>
<br class="all"/>
<div class="left w20 mb5">Notifications:</div>
<div class="right w80 mb5">
{{session.name}}
</div>
<br class="all"/>
<div class="left w20 mb5"></div>
<div class="right w80 mb5">
<a href="#" data-id="{{session.id}}" class="button-orange session-detail-button">DETAILS</a>
{% if (data.current_user == session.user_id) { %}
<a href="#" class="button-orange session-cancel-button">CANCEL SESSION</a>
{% } %}
</div>
</div>
</td>
</tr>
{% } %}
</tbody>
</script>

View File

@ -0,0 +1,52 @@
/ Account Sessions Dialog
%div{'layout' => 'screen', 'layout-id' => 'account/sessions', id: 'account-sessions', class: 'screen secondary'}
.content-head
.content-icon
= image_tag "content/icon_account.png", :width => 27, :height => 20
%h1 my account
= render "screen_navigation"
/ sessions scrolling area
.content-body
.content-body-scroller.account-content-scroller#account-sessions-content-scroller
.content-wrapper.account-sessions
.sessions-header
.left.sessions-caption
%h2 scheduled sessions:
.right
%a.button-grey{href: "javascript:history.go(-1)"} BACK
.clearall
#account-scheduled-sessions
%table.generaltable
%thead
%tbody
.clearall
/ end content scrolling area
%script{type: 'text/template', id: 'template-account-session'}
%tbody
= "{% _.each(data.sessions, function(session) { %}"
%tr
%td
%div{'data-id' => "{{session.id}}"}
.session-left Date/Time:
.session-right
{{session.scheduled_start_time}}\
.clearall
.session-left Session:
.session-right
{{session.name}}
.clearall
.session-left Notifications:
.session-right
{{session.notification_msg}}
.clearall
.session-left
.session-right
%a.button-orange.session-detail-button{href: '#', 'session-id' => "{{session.id}}"} DETAILS
= "{% if (data.current_user == session.user_id) { %}"
%a.button-orange.session-cancel-button{href: '#', 'session-id' => "{{session.id}}"} CANCEL SESSION
= "{% } %}"
%hr.clearall
= "{% }); %}"

View File

@ -11,15 +11,12 @@
%span.schedule-recurrence
%br/
%br/
.error{:style => 'display:none'}
%input{:type => 'radio', :name => 'cancel', :value => 'yes', :checked => true} Cancel RSVP just for this one session
%br/
Enter a message to the other musicians in the session (optional):
%textarea.w95.p5.f15{id: 'txtComment', rows: '2', placeholder: 'Enter a comment...'}
%textarea.cancel-description{id: 'txtCancelMessage', rows: '2', placeholder: 'Enter a message...'}
%br/
%br/
.left
%a.button-orange{:href => 'TBD', :rel => 'external', :target => '_blank'} HELP
%a.button-orange{:href => 'http://jamkazam.desk.com/', :rel => 'external', :target => '_blank'} HELP
.right
%a.button-grey{:id => 'btnCancel', 'layout-action' => 'close'} CANCEL
%a.button-orange{:id => 'btnCancelSession'} CANCEL SESSION

View File

@ -49,6 +49,7 @@
<%= render "account_profile_avatar" %>
<%= render "account_audio_profile" %>
<%= render "account_sessions" %>
<%= render "account_session_detail" %>
<%= render "configure_tracks_dialog" %>
<%= render "invitationDialog" %>
<%= render "inviteMusicians" %>
@ -74,6 +75,7 @@
<%= render "commentDialog" %>
<%= render "rsvpSubmitDialog" %>
<%= render "rsvpCancelDialog" %>
<%= render "sessionCancelDialog" %>
<div id="fb-root"></div>
@ -187,6 +189,9 @@
var accountSessionsScreen = new JK.AccountSessions(JK.app);
accountSessionsScreen.initialize();
var accountSessionDetailScreen = new JK.AccountSessionDetail(JK.app);
accountSessionDetailScreen.initialize(invitationDialog);
var affiliateReportScreen = new JK.AffiliateReportScreen(JK.app);
affiliateReportScreen.initialize();
@ -214,7 +219,7 @@
var instrumentSelectorRSVPInstance = new JK.InstrumentSelector(JK.app);
instrumentSelectorRSVPInstance.initialize(true);
var createScheduledSessionScreen = new JK.CreateScheduledSession(JK.app);
createScheduledSessionScreen.initialize(
createScheduledSessionScreen.initialize(
invitationDialog,
inviteMusiciansUtil1,
instrumentSelectorInstance,

View File

@ -152,6 +152,7 @@ SampleApp::Application.routes.draw do
match '/participants/:id' => 'api_music_sessions#participant_show', :via => :get, :as => 'api_session_participant_detail'
match '/participants/:id' => 'api_music_sessions#participant_delete', :via => :delete
match '/sessions/scheduled' => 'api_music_sessions#scheduled', :via => :get
match '/sessions/scheduled_rsvp' => 'api_music_sessions#scheduled_rsvp', :via => :get
match '/sessions/legacy' => 'api_music_sessions#create_legacy', :via => :post
match '/sessions/active' => 'api_music_sessions#ams_index', :via => :get
match '/sessions/inactive' => 'api_music_sessions#sms_index', :via => :get